"""First-run setup endpoint — vault folder selection.

Only active when no vault is configured. Accepts a folder path,
initializes the vault there, saves config, and signals the server
to restart with the full lifespan.
"""

from __future__ import annotations

import logging
import os
import sys
from pathlib import Path

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

log = logging.getLogger(__name__)

router = APIRouter(prefix="/setup", tags=["setup"])


class SetupRequest(BaseModel):
    vault_path: str


class SetupStatus(BaseModel):
    needs_setup: bool
    current_root: str | None = None


@router.get("/status")
async def setup_status() -> SetupStatus:
    """Check whether the server needs vault setup."""
    from agntspace.infra.config import get_settings
    settings = get_settings()

    needs = (
        not settings.root_explicit
        and settings.root_dir == Path.home()
        and not (settings.vault_dir / "system" / "identity" / "SOUL.md").exists()
    )
    return SetupStatus(
        needs_setup=needs,
        current_root=str(settings.root_dir) if settings.root_explicit else None,
    )


@router.post("/init")
async def setup_init(body: SetupRequest) -> dict:
    """Initialize a vault at the given path and save to config.

    After this call, the server will restart to load the full app.
    """
    vault_path = Path(body.vault_path).expanduser().resolve()

    # Validate
    if str(vault_path) == str(Path.home()):
        raise HTTPException(400, "Cannot use home directory as vault. Choose a subfolder.")

    # Ensure the directory exists (or create it)
    try:
        vault_path.mkdir(parents=True, exist_ok=True)
    except OSError as exc:
        raise HTTPException(400, f"Cannot create directory: {exc}") from exc

    if not vault_path.is_dir():
        raise HTTPException(400, f"Path is not a directory: {vault_path}")

    # Initialize vault structure
    from agntspace.setup.init import run_init
    try:
        run_init(vault_dir=vault_path, minimal=True)
    except Exception as exc:
        raise HTTPException(500, f"Vault initialization failed: {exc}") from exc

    # Save to config.toml
    config_dir = Path.home() / ".agntspace"
    config_dir.mkdir(parents=True, exist_ok=True)
    config_path = config_dir / "config.toml"

    if config_path.exists():
        import tomllib

        import tomli_w
        with open(config_path, "rb") as _f:
            _data = tomllib.load(_f)
        _data["root_dir"] = str(vault_path)
        config_path.write_bytes(tomli_w.dumps(_data).encode())
    else:
        import tomli_w
        config_path.write_bytes(tomli_w.dumps({
            "root_dir": str(vault_path),
            "llm": {"mode": "cloud", "cloud_provider": "anthropic", "cloud_model": "balanced"},
            "server": {"host": "127.0.0.1", "port": 8000},
        }).encode())

    log.info("Setup complete: vault at %s, config saved", vault_path)

    # Schedule server restart so it loads the full lifespan with the new vault
    import asyncio
    asyncio.get_event_loop().call_later(0.5, _restart_server)

    return {
        "status": "ok",
        "vault_path": str(vault_path),
        "message": "Vault initialized. Server restarting...",
    }


@router.post("/browse")
async def browse_directory(body: dict) -> dict:
    """List directories for a folder browser.

    Accepts {"path": "C:/..."} and returns subdirectories.
    """
    raw = body.get("path", "")
    if not raw:
        # Return drive roots on Windows, / on Unix
        if sys.platform == "win32":
            import string
            drives = []
            for letter in string.ascii_uppercase:
                drive = f"{letter}:\\"
                if Path(drive).exists():
                    drives.append({"name": f"{letter}:", "path": drive})
            return {"dirs": drives, "current": ""}
        return {"dirs": [{"name": "/", "path": "/"}], "current": ""}

    p = Path(raw).expanduser().resolve()
    if not p.is_dir():
        return {"dirs": [], "current": str(p)}

    dirs = []
    try:
        for child in sorted(p.iterdir()):
            if child.is_dir() and not child.name.startswith("."):
                dirs.append({"name": child.name, "path": str(child)})
    except PermissionError:
        pass

    return {"dirs": dirs, "current": str(p)}


def _restart_server() -> None:
    """Restart the server process.

    Uses `sys.orig_argv` (Python 3.10+) to preserve the original `-m` form.
    Without it, `python -m agntspace.cli start` would re-exec as a plain
    script and sys.path[0] would become the cli.py directory, shadowing
    the installed `mcp` SDK with our local `agntspace/mcp/` package.
    """
    log.info("Restarting server after setup...")
    orig_argv = getattr(sys, "orig_argv", None)
    if orig_argv:
        os.execv(orig_argv[0], orig_argv)
    else:
        os.execv(sys.executable, [sys.executable] + sys.argv)
