"""Context, session, and MCP endpoints — extracted from main.py."""

from __future__ import annotations

import structlog
from fastapi import APIRouter, HTTPException, Request

from proxym.cache import DeltaBuffer
from proxym.context import detect_project

from proxym.api._state import (
    get_delta_buffer,
    get_mcp_router,
    get_session_store,
    set_context_payload,
)

logger = structlog.get_logger()

router = APIRouter()


def get_context_store():
    return get_delta_buffer()


def get_mcp_registry():
    return get_mcp_router().registry


@router.post("/v1/context/delta")
async def receive_delta(request: Request):
    """Receive context delta from the file watcher client."""
    body = await request.json()
    has_legacy = body.get("payload") and body.get("version") is not None
    if not has_legacy and (not body.get("project_id") or not body.get("diff_text")):
        raise HTTPException(status_code=400, detail="invalid delta payload")

    buffer = DeltaBuffer()
    try:
        delta = buffer.compute_delta()
    except TypeError:
        delta = None

    payload = body.get("payload") or body.get("diff_text", "")
    set_context_payload(payload)

    store = get_context_store()
    update_project = getattr(store, "update_project", None)
    if callable(update_project):
        update_project(body.get("project_id"), body)

    return {
        "ok": True,
        "success": True,
        "version": body.get("version"),
        "token_estimate": body.get("token_estimate") or getattr(delta, "token_estimate", None),
    }


@router.post("/v1/context/detect")
async def detect_context(request: Request):
    """Detect project context from request body (messages + headers)."""
    body = await request.json()
    messages = body.get("messages", [])
    if not messages:
        system_prompt = body.get("system_prompt", "")
        paths = body.get("paths", [])
        derived = []
        if system_prompt:
            derived.append({"role": "system", "content": system_prompt})
        if paths:
            derived.append({"role": "user", "content": "\n".join(paths)})
        messages = derived
    headers = {k.lower(): v for k, v in request.headers.items()}
    ctx = detect_project(messages, headers=headers)
    return {
        "project_id": ctx.project_id,
        "project_name": ctx.project_name,
        "project_root": ctx.project_root,
        "stack": ctx.stack,
        "git_remote": ctx.git_remote,
    }


@router.get("/v1/sessions")
async def list_sessions():
    """List active agent sessions."""
    store = get_session_store()
    sessions = []
    for s in store.list_sessions():
        if isinstance(s, dict):
            sessions.append(s)
            continue
        sessions.append({
            "id": getattr(s, "id", getattr(s, "session_id", "")),
            "session_id": getattr(s, "session_id", getattr(s, "id", "")),
            "project_id": getattr(s, "project_id", ""),
            "age_seconds": round(getattr(s, "age_seconds", 0), 1),
            "idle_seconds": round(getattr(s, "idle_seconds", 0), 1),
            "history_length": len(getattr(s, "compressed_history", getattr(s, "history", []))),
            "active_files": getattr(s, "active_files", []),
        })
    return {"sessions": sessions}


@router.get("/v1/mcp/servers")
async def list_mcp_servers():
    """List registered MCP servers."""
    registry = get_mcp_registry()
    if isinstance(registry, dict):
        return {
            "servers": [
                {"name": name, **data}
                for name, data in registry.items()
            ],
        }
    servers = registry.list_servers(enabled_only=False)
    return {
        "servers": [
            {
                "name": s.name,
                "url": s.url,
                "transport": s.transport.value,
                "tools": s.tools,
                "enabled": s.enabled,
                "priority": s.priority,
                "description": s.description,
            }
            for s in servers
        ],
    }


@router.get("/v1/context/stats")
async def context_stats():
    """Return context store statistics."""
    store = get_context_store()
    get_stats = getattr(store, "get_stats", None)
    if callable(get_stats):
        stats = get_stats()
        if "projects_tracked" not in stats:
            stats = {
                **stats,
                "projects_tracked": stats.get("projects_tracked", 0),
                "files_tracked": stats.get("files_tracked", 0),
                "tokens_total": stats.get("tokens_total", stats.get("estimated_tokens", 0)),
            }
        return stats
    return {
        "projects_tracked": 0,
        "files_tracked": 0,
        "tokens_total": 0,
    }
