"""Hive admin panel API routes.

Provides REST API and WebSocket endpoints for the admin panel.
Mounted at /admin/hive/ (configurable via .hive/config.yaml).
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any

from fastapi import APIRouter, WebSocket, WebSocketDisconnect
from pydantic import BaseModel

hive_router = APIRouter(tags=["hive-admin"])

# Module-level state -- initialized by mount_hive()
_hive_state: dict[str, Any] = {}


class ApprovalAction(BaseModel):
    """Request body for approval/rejection."""

    action: str  # "approve" | "reject" | "defer"
    reason: str = ""


class ChatMessage(BaseModel):
    """Request body for chat messages."""

    message: str


# ---- Status Endpoints ----


@hive_router.get("/api/status")
async def get_status() -> dict[str, Any]:
    """Get overall Hive status."""
    ceo = _hive_state.get("ceo")
    if ceo is None:
        return {"status": "not_initialized", "agents": []}
    return {
        "status": "active",
        "agents": ceo.get_all_agent_statuses(),
        "version": "1.0.0",
    }


@hive_router.get("/api/health")
async def get_health() -> dict[str, Any]:
    """Get application health snapshot."""
    hive_dir = _hive_state.get("hive_dir")
    if hive_dir is None:
        return {"error": "Hive not initialized"}

    health_path = Path(hive_dir) / "metrics" / "health.json"
    if health_path.exists():
        data: dict[str, Any] = json.loads(health_path.read_text(encoding="utf-8"))
        return data
    return {"status": "no_data", "score": 0}


@hive_router.get("/api/health/trends")
async def get_health_trends() -> dict[str, Any]:
    """Get historical health data."""
    hive_dir = _hive_state.get("hive_dir")
    if hive_dir is None:
        return {"error": "Hive not initialized"}

    trends_path = Path(hive_dir) / "metrics" / "trends.json"
    if trends_path.exists():
        data: dict[str, Any] = json.loads(trends_path.read_text(encoding="utf-8"))
        return data
    return {"retention_days": 30, "data_points": []}


# ---- Agent Endpoints ----


@hive_router.get("/api/agents")
async def list_agents() -> list[dict[str, Any]]:
    """List all agent statuses."""
    ceo = _hive_state.get("ceo")
    if ceo is None:
        return []
    statuses: list[dict[str, Any]] = ceo.get_all_agent_statuses()
    return statuses


# ---- Backlog / Kanban Endpoints ----


@hive_router.get("/api/backlog")
async def list_backlog() -> list[dict[str, Any]]:
    """List all backlog items."""
    hive_dir = _hive_state.get("hive_dir")
    if hive_dir is None:
        return []

    items_dir = Path(hive_dir) / "backlog" / "items"
    items: list[dict[str, Any]] = []
    if items_dir.exists():
        for item_file in sorted(items_dir.glob("HIVE-*.md")):
            items.append(
                {
                    "id": item_file.stem,
                    "filename": item_file.name,
                    "content": item_file.read_text(encoding="utf-8")[:500],
                }
            )
    return items


# ---- Approval Queue Endpoints ----


@hive_router.get("/api/approvals")
async def list_approvals() -> list[dict[str, Any]]:
    """List pending approval items."""
    ceo = _hive_state.get("ceo")
    if ceo is None:
        return []
    queue: list[dict[str, Any]] = ceo.get_approval_queue()
    return queue


@hive_router.post("/api/approvals/{item_id}/approve")
async def approve_item(item_id: str) -> dict[str, Any]:
    """Approve a pending item."""
    ceo = _hive_state.get("ceo")
    if ceo is None:
        return {"error": "Hive not initialized"}
    success = ceo.approve_item(item_id)
    return {"item_id": item_id, "status": "approved" if success else "not_found"}


@hive_router.post("/api/approvals/{item_id}/reject")
async def reject_item(item_id: str, body: ApprovalAction) -> dict[str, Any]:
    """Reject a pending item with reason."""
    ceo = _hive_state.get("ceo")
    if ceo is None:
        return {"error": "Hive not initialized"}
    success = ceo.reject_item(item_id, body.reason)
    return {"item_id": item_id, "status": "rejected" if success else "not_found"}


# ---- Chat Endpoints ----


@hive_router.post("/api/chat")
async def send_chat(body: ChatMessage) -> dict[str, Any]:
    """Send a chat message to Hive CEO."""
    # In full implementation, this routes to the CEO agent with LLM context
    return {
        "response": f"Chat received: '{body.message}'. Full LLM-powered chat coming in Phase 2.",
        "agent": "hive-ceo",
    }


@hive_router.get("/api/chat/history")
async def get_chat_history() -> list[dict[str, Any]]:
    """Get chat message history."""
    return []  # Loaded from .hive/memory/ in full implementation


# ---- Activity Log Endpoints ----


@hive_router.get("/api/activity")
async def list_activity() -> list[dict[str, Any]]:
    """List recent activity log entries."""
    return []  # Populated by agent actions in full implementation


# ---- Configuration Endpoints ----


@hive_router.get("/api/config")
async def get_config() -> dict[str, Any]:
    """Get current Hive configuration (sanitized, no secrets)."""
    hive_dir = _hive_state.get("hive_dir")
    if hive_dir is None:
        return {"error": "Hive not initialized"}

    config_path = Path(hive_dir) / "config.yaml"
    if config_path.exists():
        return {"config_file": str(config_path), "status": "loaded"}
    return {"status": "no_config"}


# ---- Codebase Endpoints ----


@hive_router.get("/api/codebase")
async def get_codebase_summary() -> dict[str, Any]:
    """Get codebase map summary."""
    hive_dir = _hive_state.get("hive_dir")
    if hive_dir is None:
        return {"error": "Hive not initialized"}

    map_path = Path(hive_dir) / "codebase-map.json"
    if map_path.exists():
        data = json.loads(map_path.read_text(encoding="utf-8"))
        return {
            "stats": data.get("stats", {}),
            "hot_files": data.get("hot_files", []),
            "generated": data.get("generated", "unknown"),
        }
    return {"status": "not_indexed"}


@hive_router.post("/api/reindex")
async def trigger_reindex() -> dict[str, Any]:
    """Trigger a full codebase reindex."""
    analyst = _hive_state.get("analyst")
    if analyst is None:
        return {"error": "Analyst agent not initialized"}
    result = analyst.index_codebase()
    return {
        "status": "reindexed",
        "files": result.get("stats", {}).get("total_files", 0),
        "lines": result.get("stats", {}).get("total_lines", 0),
    }


# ---- Evolution Endpoints ----


@hive_router.get("/api/evolution")
async def get_evolution_log() -> dict[str, Any]:
    """Get evolution log."""
    hive_dir = _hive_state.get("hive_dir")
    if hive_dir is None:
        return {"error": "Hive not initialized"}

    evo_path = Path(hive_dir) / "evolution-log.md"
    if evo_path.exists():
        return {"content": evo_path.read_text(encoding="utf-8")}
    return {"content": "No evolution log found."}


# ---- WebSocket ----


@hive_router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
    """WebSocket for real-time updates (health, activity, chat)."""
    await websocket.accept()
    try:
        while True:
            data = await websocket.receive_text()
            # Echo for now; full implementation would route to agents
            await websocket.send_text(json.dumps({"echo": data}))
    except WebSocketDisconnect:
        pass


def mount_hive(
    workspace_root: Path,
    ceo: Any = None,
    analyst: Any = None,
) -> None:
    """Initialize Hive admin panel state.

    Called during application startup to wire agent instances to routes.
    """
    _hive_state["workspace_root"] = str(workspace_root)
    _hive_state["hive_dir"] = str(workspace_root / ".hive")
    _hive_state["ceo"] = ceo
    _hive_state["analyst"] = analyst
