"""System and health endpoints."""

import os

from fastapi import APIRouter, Depends, Query, Request
from fastapi.responses import RedirectResponse

from peon_mcp.common.dependencies import get_db
from peon_mcp.db import row_to_dict
from peon_mcp.common.schemas import OkResponse
from peon_mcp.system.schemas import (
    GitHubAppInstallation,
    GitHubAppStatusResponse,
    HeartbeatUpsert,
    LoopsResponse,
    SystemInfoResponse,
)

router = APIRouter(tags=["System"])


@router.get("/api/health")
async def health_check():
    """Health check endpoint. Returns auth_required status."""
    return {
        "status": "ok",
        "auth_required": bool(os.environ.get("PEON_API_KEY")) or bool(os.environ.get("GITHUB_APP_CLIENT_ID")),
    }


@router.get("/api/system-info", response_model=SystemInfoResponse)
async def system_info():
    try:
        import importlib.metadata
        version = importlib.metadata.version("peon-mcp")
    except Exception:
        version = "dev"

    return {
        "version": version,
    }


@router.put("/api/loops/{loop_id}")
async def upsert_heartbeat(loop_id: str, body: HeartbeatUpsert, db=Depends(get_db)):
    """Upsert a heartbeat row so the UI can show this loop as active."""
    await db.execute(
        "INSERT INTO loop_heartbeats"
        " (id, project_id, pid, hostname, discord_status, started_at, last_heartbeat)"
        " VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)"
        " ON CONFLICT (id) DO UPDATE SET"
        "   project_id = EXCLUDED.project_id,"
        "   pid = EXCLUDED.pid,"
        "   hostname = EXCLUDED.hostname,"
        "   discord_status = EXCLUDED.discord_status,"
        "   last_heartbeat = CURRENT_TIMESTAMP",
        (loop_id, body.project_id, body.pid, body.hostname, body.discord_status),
    )
    await db.commit()
    return {"ok": True}


@router.delete("/api/loops/{loop_id}", response_model=OkResponse)
async def delete_heartbeat(loop_id: str, db=Depends(get_db)):
    """Remove the heartbeat row on clean shutdown."""
    await db.execute("DELETE FROM loop_heartbeats WHERE id = ?", (loop_id,))
    await db.commit()
    return {"ok": True}


@router.get("/api/loops", response_model=LoopsResponse)
async def list_loops(
    project_id: str | None = Query(default=None),
    db=Depends(get_db),
):
    query = (
        "SELECT * FROM loop_heartbeats"
        " WHERE last_heartbeat >= NOW() - INTERVAL '90 seconds'"
    )
    params: list = []
    if project_id:
        query += " AND project_id = ?"
        params.append(project_id)
    query += " ORDER BY started_at DESC"
    rows = await db.execute_fetchall(query, params)
    loops = [row_to_dict(r) for r in rows]
    return {
        "active_count": len(loops),
        "loops": loops,
    }


# ---------------------------------------------------------------------------
# GitHub App status
# ---------------------------------------------------------------------------

_GITHUB_APP_SLUG = "peon-grukk"  # App slug on github.com


@router.get("/api/github-app/status", response_model=GitHubAppStatusResponse)
async def github_app_status(request: Request, db=Depends(get_db)):
    """Return the GitHub App configuration status and installations.

    When the caller is authenticated via a session cookie, installations are
    scoped to those the user has access to (via ``GET /user/installations``).
    For API-key auth or unauthenticated requests, all app installations are
    returned.
    """
    from peon_mcp.github_app import get_provider

    provider = get_provider()
    if provider is None:
        return GitHubAppStatusResponse(configured=False)

    installations: list[GitHubAppInstallation] = []
    try:
        auth_method = getattr(request.state, "auth_method", None)
        if auth_method == "session":
            installations = await _user_scoped_installations(request, db, provider)
        else:
            inst_map = provider.get_installations()
            for owner, inst_id in inst_map.items():
                installations.append(
                    GitHubAppInstallation(
                        owner=owner,
                        installation_id=inst_id,
                        token_status=provider.get_token_status(inst_id),
                    )
                )
    except Exception:
        pass  # Return configured=True with empty installations

    install_url = f"https://github.com/apps/{_GITHUB_APP_SLUG}/installations/new"

    return GitHubAppStatusResponse(
        configured=True,
        app_id=provider.app_id,
        installations=installations,
        install_url=install_url,
    )


async def _user_scoped_installations(
    request: Request, db, provider
) -> list[GitHubAppInstallation]:
    """Return only installations the authenticated user has access to.

    Uses the installation cache module to avoid per-request GitHub API calls.
    """
    from peon_mcp.common.installation_cache import get_user_org_logins

    user = getattr(request.state, "user", None)
    if not user:
        return []
    user_id = user.get("user_id")
    if not user_id:
        return []

    session_token = request.cookies.get("peon_session")
    if not session_token:
        return []

    # Ensure token is valid (refreshes if expired)
    from peon_mcp.auth.tokens import ensure_valid_token

    encrypted_token = await ensure_valid_token(db, session_token)
    if not encrypted_token:
        return []

    org_logins = await get_user_org_logins(
        db, user_id, encrypted_token
    )

    # Map org logins back to installations with token status
    installations: list[GitHubAppInstallation] = []
    inst_map = provider.get_installations()
    for org in org_logins:
        inst_id = inst_map.get(org)
        if inst_id:
            installations.append(
                GitHubAppInstallation(
                    owner=org,
                    installation_id=inst_id,
                    token_status=provider.get_token_status(inst_id),
                )
            )

    return installations


@router.get("/api/github-app/callback")
async def github_app_callback(
    installation_id: int | None = Query(default=None),
    setup_action: str | None = Query(default=None),
):
    """Post-install redirect from GitHub App setup.

    Invalidates the installation cache so newly installed orgs are discovered,
    then redirects to the UI settings page.
    """
    from peon_mcp.github_app import get_provider

    provider = get_provider()
    if provider is not None:
        provider.invalidate_installations()

    ui_origin = os.environ.get("PEON_UI_ORIGIN", "").rstrip("/")
    if not ui_origin:
        # Fall back to relative redirect (works when UI is served from same origin)
        ui_origin = ""

    redirect_url = f"{ui_origin}/settings/github?installed=true"
    return RedirectResponse(url=redirect_url, status_code=302)
