import http.server
from http.server import ThreadingHTTPServer
import json
import os
import time
import socket
import qrcode

PORT = 8080
ACTIVE_SESSIONS = {} 

def get_local_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except:
        return "127.0.0.1"

class QuizHandler(http.server.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate')
        super().end_headers()

    def do_GET(self):
        if self.path == '/skor.json' and not os.path.exists('skor.json'):
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(b'[]')
            return
            
        elif self.path == '/get_live_status':
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(list(ACTIVE_SESSIONS.values())).encode('utf-8'))
            return

        elif self.path == '/check_ip':
            client_ip = self.client_address[0]
            completed = False
            nama = ""
            current_q = 0
            
            if os.path.exists('skor.json'):
                try:
                    with open('skor.json', 'r') as f:
                        scores = json.load(f)
                        for s in scores:
                            if s.get('ip') == client_ip:
                                completed = True
                                nama = s.get('nama', 'Siswa')
                                break
                except: pass
            
            if not completed and client_ip in ACTIVE_SESSIONS:
                nama = ACTIVE_SESSIONS[client_ip].get('nama', '')
                current_q = ACTIVE_SESSIONS[client_ip].get('current_question', 0)

            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps({
                "completed": completed, 
                "nama": nama, 
                "current_question": current_q
            }).encode('utf-8'))
            return
            
        super().do_GET()

    def do_POST(self):
        global ACTIVE_SESSIONS
        client_ip = self.client_address[0]

        if self.path == '/update_status':
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            data = json.loads(post_data)
            
            nama = data.get('nama', 'Tanpa Nama')
            q_idx = data.get('current_question', 0)
            total_q = data.get('total_questions', 40)
            
            ACTIVE_SESSIONS[client_ip] = {
                "ip": client_ip,
                "nama": nama,
                "current_question": q_idx + 1,
                "total_questions": total_q,
                "status": f"Mengerjakan Soal {q_idx + 1}/{total_q}",
                "waktu_update": time.strftime('%H:%M:%S')
            }
            
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(b'{"status":"success"}')

        elif self.path == '/submit_score':
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            data = json.loads(post_data)
            
            data['ip'] = client_ip
            data['id'] = str(time.time())
            
            scores = []
            if os.path.exists('skor.json'):
                with open('skor.json', 'r') as f:
                    try: scores = json.load(f)
                    except: pass
            
            scores.append(data)
            
            with open('skor.json', 'w') as f:
                json.dump(scores, f, indent=4)
                
            if client_ip in ACTIVE_SESSIONS:
                ACTIVE_SESSIONS[client_ip]['status'] = "Selesai (Skor: " + str(data.get('skor')) + ")"
                ACTIVE_SESSIONS[client_ip]['current_question'] = "Selesai"

            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(b'{"status":"success"}')
            
        elif self.path == '/update_soal':
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            data = json.loads(post_data)
            
            with open('soal.json', 'w') as f:
                json.dump(data, f, indent=4)
                
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(b'{"status":"success"}')

        elif self.path == '/delete_score':
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            req = json.loads(post_data)
            score_id = req.get('id')
            
            if os.path.exists('skor.json'):
                with open('skor.json', 'r') as f:
                    scores = json.load(f)
                scores = [s for s in scores if s.get('id') != score_id]
                with open('skor.json', 'w') as f:
                    json.dump(scores, f, indent=4)
                    
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(b'{"status":"success"}')

        elif self.path == '/clear_scores':
            ACTIVE_SESSIONS = {}
            with open('skor.json', 'w') as f:
                f.write("[]")
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(b'{"status":"success"}')

if __name__ == "__main__":
    local_ip = get_local_ip()
    quiz_url = f"http://{local_ip}:{PORT}/kuis.html"
    admin_url = f"http://localhost:{PORT}/admin.html"

    print("=" * 60)
    print(f" SERVER PSTS SIAP DIGUNAKAN!")
    print("=" * 60)
    print(f"🔗 Link Siswa : {quiz_url}")
    print(f"🔗 Link Guru  : {admin_url}")
    print("-" * 60)
    print("📱 SILAHKAN SCAN QR CODE DI BAWAH INI UNTUK SISWA:\n")
    
    # Cetak QR Code langsung di jendela CMD
    qr = qrcode.QRCode(box_size=1, border=1)
    qr.add_data(quiz_url)
    qr.make(fit=True)
    qr.print_ascii(invert=True)

    print("\n" + "=" * 60)
    print("Tekan Ctrl+C di keyboard untuk mematikan server.")
    print("=" * 60)

    with ThreadingHTTPServer(("", PORT), QuizHandler) as httpd:
        try: httpd.serve_forever()
        except KeyboardInterrupt: print("\nServer dimatikan.")