"""
Metabase first-run setup script.

Run once after `just up` to create the admin account,
connect the data database, and generate an API key.

Usage:
    just setup
    # or directly:
    uv run scripts/setup.py
"""

import sys
import time

import httpx

METABASE_URL = "http://localhost:3000"
ADMIN_EMAIL = "admin@metaverse.local"
ADMIN_PASSWORD = "metaverse-admin-1"
SITE_NAME = "Metaverse"

DB_CONFIG = {
    "engine": "postgres",
    "name": "Metaverse Data",
    "details": {
        "host": "postgres",
        "port": 5432,
        "dbname": "metaverse",
        "user": "metaverse",
        "password": "metaverse",
    },
}


def wait_for_metabase(client: httpx.Client, timeout: int = 120) -> None:
    print("Waiting for Metabase to be ready...", end="", flush=True)
    deadline = time.time() + timeout
    while time.time() < deadline:
        try:
            r = client.get("/api/health", timeout=5)
            if r.status_code == 200 and r.json().get("status") == "ok":
                print(" ready.")
                return
        except httpx.RequestError:
            pass
        print(".", end="", flush=True)
        time.sleep(5)
    print()
    print("ERROR: Metabase did not become ready in time.", file=sys.stderr)
    print("Run `docker compose logs metabase` to investigate.", file=sys.stderr)
    sys.exit(1)


def get_setup_token(client: httpx.Client) -> str:
    r = client.get("/api/session/properties")
    r.raise_for_status()
    token = r.json().get("setup-token")
    if not token:
        print("ERROR: No setup token found — Metabase may already be configured.")
        print("If you need a fresh API key, create one in Admin → Settings → API Keys.")
        sys.exit(1)
    return token


def run_setup(client: httpx.Client, token: str) -> str:
    """Complete the setup wizard. Returns the session token."""
    payload = {
        "token": token,
        "user": {
            "first_name": "Admin",
            "last_name": "User",
            "email": ADMIN_EMAIL,
            "password": ADMIN_PASSWORD,
            "site_name": SITE_NAME,
        },
        "database": {
            "engine": DB_CONFIG["engine"],
            "name": DB_CONFIG["name"],
            "details": DB_CONFIG["details"],
        },
        "prefs": {
            "site_name": SITE_NAME,
            "allow_tracking": False,
        },
    }
    r = client.post("/api/setup", json=payload)
    if r.status_code != 200:
        print(f"ERROR: Setup failed ({r.status_code}): {r.text}", file=sys.stderr)
        sys.exit(1)
    return r.json()["id"]


def create_api_key(client: httpx.Client, session_token: str) -> str:
    """Create an API key using the freshly created admin session."""
    headers = {"X-Metabase-Session": session_token}

    # Get the administrators group id (always group 2 in a fresh Metabase)
    r = client.get("/api/permissions/group", headers=headers)
    r.raise_for_status()
    groups = r.json()
    admin_group = next((g for g in groups if g.get("name") == "Administrators"), None)
    group_id = admin_group["id"] if admin_group else 2

    r = client.post(
        "/api/api-key",
        json={"name": "Metaverse MCP", "group_id": group_id},
        headers=headers,
    )
    if r.status_code not in (200, 201):
        print(f"ERROR: API key creation failed ({r.status_code}): {r.text}", file=sys.stderr)
        sys.exit(1)
    return r.json()["unmasked_key"]


def main() -> None:
    with httpx.Client(base_url=METABASE_URL) as client:
        wait_for_metabase(client)

        print("Fetching setup token...")
        token = get_setup_token(client)

        print("Running setup wizard...")
        session_token = run_setup(client, token)
        print(f"✓ Admin account created  ({ADMIN_EMAIL} / {ADMIN_PASSWORD})")

        print("Creating API key...")
        api_key = create_api_key(client, session_token)
        print("✓ API key created")

    print()
    print("─" * 60)
    print("Add this to your .env file:")
    print()
    print(f"METABASE_API_KEY={api_key}")
    print()
    print("Then start the MCP server:")
    print("  just serve")
    print("─" * 60)


if __name__ == "__main__":
    main()
