"""
login command — authenticate via OAuth in the browser.

  skilark login  → opens browser to GitHub/Google login, writes user_id to config

Similar to `gh auth login` — starts a local HTTP server, opens browser,
receives callback with user_id after OAuth completes.
"""

import http.server
import re
import time
import webbrowser
from urllib.parse import parse_qs, urlparse

from rich.console import Console

from skilark_cli.config_store import ConfigStore, DEFAULT_API_URL

console = Console()


def dispatch() -> None:
    """Entry point called from main.py."""
    config_store = ConfigStore()

    api_url = DEFAULT_API_URL
    if not config_store.is_first_run():
        config = config_store.load()
        api_url = config.get("api_url", DEFAULT_API_URL)

    run(config_store=config_store, api_url=api_url)


def run(config_store: ConfigStore, api_url: str = DEFAULT_API_URL) -> None:
    """Run the login flow."""
    result: dict = {}

    class CallbackHandler(http.server.BaseHTTPRequestHandler):
        def do_GET(self):
            parsed = urlparse(self.path)
            if parsed.path != "/callback":
                self.send_error(404)
                return
            params = parse_qs(parsed.query)
            result["user_id"] = params.get("user_id", [None])[0]
            result["status"] = params.get("status", [None])[0]
            self.send_response(200)
            self.send_header("Content-Type", "text/html")
            self.end_headers()
            self.wfile.write(
                b"<html><body style='font-family:system-ui;background:#0f1117;color:#e1e4e8;"
                b"display:flex;align-items:center;justify-content:center;min-height:100vh'>"
                b"<div style='text-align:center'>"
                b"<h2 style='color:#3fb950'>Logged in!</h2>"
                b"<p>You can close this tab and return to the terminal.</p>"
                b"</div></body></html>"
            )

        def log_message(self, format, *args):
            pass  # Silence request logs

    server = http.server.HTTPServer(("127.0.0.1", 0), CallbackHandler)
    port = server.server_address[1]
    channel_id = f"127.0.0.1:{port}"

    login_url = f"{api_url}/oauth/channel-link?channel_type=cli&channel_id={channel_id}"
    console.print("Opening browser to log in...")
    console.print(f"[dim]If the browser doesn't open, visit:[/dim]")
    console.print(f"[dim]{login_url}[/dim]\n")
    webbrowser.open(login_url)

    # Wait for callback — loop because browsers may fire /favicon.ico first
    deadline = time.monotonic() + 120
    while not result and time.monotonic() < deadline:
        server.timeout = max(0.1, deadline - time.monotonic())
        server.handle_request()
    server.server_close()

    user_id = result.get("user_id")
    if not user_id or result.get("status") != "ok":
        console.print("[red]Login failed or timed out.[/red]")
        return

    if not re.match(r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", user_id):
        console.print("[red]Login failed: invalid user ID received.[/red]")
        return

    if config_store.is_first_run():
        config_store.save(user_id=user_id, topics=[], api_url=api_url)
    else:
        config_store.update_user_id(user_id)

    console.print("[green]✓[/green] Logged in successfully.")
    console.print(f"[dim]User ID: {user_id}[/dim]")
