"""Browser-based CLI authentication and local credential storage."""

import json
import time
import webbrowser
from pathlib import Path
from typing import Any

import httpx


def _config_dir() -> Path:
    """Return ~/.config/tyko, creating it if needed."""
    d = Path.home() / ".config" / "tyko"
    d.mkdir(parents=True, exist_ok=True)
    return d


def _credentials_path() -> Path:
    return _config_dir() / "credentials"


def get_stored_credentials() -> dict[str, Any] | None:
    """Read stored credentials from ~/.config/tyko/credentials.

    Returns dict with 'api_key' and 'api_url', or None if not found.
    """
    path = _credentials_path()
    if not path.exists():
        return None
    try:
        with path.open() as f:
            data = json.load(f)
        if not isinstance(data, dict) or "api_key" not in data:
            return None
        return data
    except (json.JSONDecodeError, OSError):
        return None


def store_credentials(*, api_key: str, api_url: str) -> None:
    """Save API key to ~/.config/tyko/credentials (mode 0600)."""
    path = _credentials_path()
    data = {"api_key": api_key, "api_url": api_url}
    path.write_text(json.dumps(data, indent=2))
    path.chmod(0o600)


def clear_credentials() -> bool:
    """Remove stored credentials. Returns True if they existed."""
    path = _credentials_path()
    if path.exists():
        path.unlink()
        return True
    return False


def login(*, api_url: str = "https://api.tyko-labs.com", open_browser: bool = True) -> str:
    """Interactive browser-based login.

    Opens the browser to the authorization page, polls until authorized,
    stores the API key, and returns it.

    Raises:
        RuntimeError: if login times out or fails.
    """
    # Step 1: Initiate session
    print("Connecting to Tyko Labs...")
    try:
        response = httpx.post(f"{api_url}/auth/cli/initiate", timeout=10.0)
        response.raise_for_status()
    except Exception as e:
        raise RuntimeError(f"Failed to connect to {api_url}: {e}") from e

    data = response.json()
    token = data["token"]
    auth_url = data["auth_url"]

    print("\nOpen the following URL in your browser to authorize:")
    print(f"\n  {auth_url}\n")

    if open_browser:
        webbrowser.open(auth_url)
        print("(Browser opened automatically)")

    # Step 2: Poll for authorization
    print("\nWaiting for authorization", end="", flush=True)
    poll_interval = 2.0
    timeout = 600.0  # 10 minutes
    start = time.monotonic()

    while time.monotonic() - start < timeout:
        time.sleep(poll_interval)
        print(".", end="", flush=True)

        try:
            poll_response = httpx.get(f"{api_url}/auth/cli/poll/{token}", timeout=10.0)
            poll_response.raise_for_status()
        except Exception:
            continue

        result = poll_response.json()
        status = result.get("status")

        if status == "authorized":
            api_key = result.get("api_key")
            if isinstance(api_key, str) and api_key:
                store_credentials(api_key=api_key, api_url=api_url)
                print("\n\nLogged in successfully! API key saved to ~/.config/tyko/credentials")
                return api_key

        if status == "expired":
            raise RuntimeError("Authorization expired. Please try again.")

    raise RuntimeError("Login timed out. Please try again.")
