"""Combined HTTP static file + token server for R1 creations."""

import json
import os
import time
from http.server import HTTPServer, SimpleHTTPRequestHandler
from urllib.parse import parse_qs, urlsplit

from livekit import api
from livekit.protocol.room import RoomConfiguration

# Load credentials from agent/.env.local
env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "agent", ".env.local")
if os.path.exists(env_path):
    with open(env_path) as f:
        for line in f:
            line = line.strip()
            if line and not line.startswith("#") and "=" in line:
                key, _, value = line.partition("=")
                value = value.strip().strip('"').strip("'")
                os.environ.setdefault(key.strip(), value)

DIR = os.path.dirname(os.path.abspath(__file__))
os.chdir(DIR)


class Handler(SimpleHTTPRequestHandler):
    def do_POST(self):
        parsed = urlsplit(self.path)
        if parsed.path == "/getToken":
            if not self._authorized(parsed):
                self.send_response(401)
                self._cors_headers()
                self.end_headers()
                self.wfile.write(b'{"error":"unauthorized"}')
                return
            self._handle_token()
        else:
            self.send_error(404)

    def do_OPTIONS(self):
        self.send_response(200)
        self._cors_headers()
        self.end_headers()

    def do_GET(self):
        parsed = urlsplit(self.path)
        if parsed.path == "/healthz":
            self.send_response(200)
            self._cors_headers()
            self.end_headers()
            self.wfile.write(b"ok")
            return
        # Reflect's memory (for the app's "welcome back" + journal). Gated.
        if parsed.path == "/memory":
            if not self._authorized(parsed):
                self.send_response(401)
                self._cors_headers()
                self.end_headers()
                self.wfile.write(b'{"error":"unauthorized"}')
                return
            self._handle_memory()
            return
        # Gate downloadable app builds (the APK) behind the shared secret.
        if parsed.path.endswith(".apk") and not self._authorized(parsed):
            self.send_response(401)
            self._cors_headers()
            self.end_headers()
            self.wfile.write(b'{"error":"unauthorized"}')
            return
        super().do_GET()

    def _handle_memory(self):
        data_dir = os.environ.get(
            "R1_DATA_DIR", os.path.dirname(os.path.abspath(__file__))
        )
        sessions = []
        try:
            path = os.path.join(data_dir, "therapy_sessions.json")
            if os.path.exists(path):
                with open(path) as f:
                    loaded = json.load(f)
                if isinstance(loaded, list):
                    sessions = loaded
        except Exception:
            sessions = []

        payload = json.dumps(
            {"name": os.environ.get("R1_USER_NAME", ""), "sessions": sessions}
        ).encode()
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self._cors_headers()
        self.end_headers()
        self.wfile.write(payload)

    def _authorized(self, parsed) -> bool:
        """Allow only requests carrying the shared secret. If R1_TOKEN_SECRET is
        not set, auth is disabled (open, as before)."""
        expected = os.environ.get("R1_TOKEN_SECRET")
        if not expected:
            return True
        provided = self.headers.get("X-R1-Auth")
        if not provided:
            provided = (parse_qs(parsed.query).get("k") or [None])[0]
        return provided == expected

    def _handle_token(self):
        length = int(self.headers.get("Content-Length", 0))
        body = json.loads(self.rfile.read(length)) if length else {}

        room_name = body.get("room_name") or f"r1-room-{int(time.time())}"
        identity = body.get("participant_identity") or f"r1-user-{int(time.time())}"

        token = (
            api.AccessToken(
                os.environ["LIVEKIT_API_KEY"], os.environ["LIVEKIT_API_SECRET"]
            )
            .with_identity(identity)
            .with_name(body.get("participant_name") or "R1 User")
            .with_grants(
                api.VideoGrants(
                    room_join=True,
                    room=room_name,
                    can_publish=True,
                    can_subscribe=True,
                )
            )
        )

        if body.get("room_config"):
            rc_data = body["room_config"]
            room_config = RoomConfiguration()
            for a in rc_data.get("agents", []):
                dispatch = room_config.agents.add()
                dispatch.agent_name = a.get("agent_name", "")
            token = token.with_room_config(room_config)

        resp = json.dumps(
            {
                "server_url": os.environ["LIVEKIT_URL"],
                "participant_token": token.to_jwt(),
            }
        ).encode()

        self.send_response(201)
        self.send_header("Content-Type", "application/json")
        self._cors_headers()
        self.end_headers()
        self.wfile.write(resp)

    def _cors_headers(self):
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "Content-Type, X-R1-Auth")

    def log_message(self, fmt, *args):
        print(f"[server] {args[0]}")


if __name__ == "__main__":
    server = HTTPServer(("0.0.0.0", 8081), Handler)
    print("Server running on http://0.0.0.0:8081 (static files + token endpoint)")
    server.serve_forever()
