from __future__ import annotations

import urllib.parse

from fastapi import APIRouter, HTTPException, Request, WebSocket
from fastapi.responses import FileResponse

from ..chat.session import ChatSessionManager
from ..models import DecisionStatus
from ..state import StateManager
from ..types import DecisionInput, YoloInput
from .constants import WEB_DIR

router = APIRouter()


@router.get("/")
async def root() -> FileResponse:
    return FileResponse(WEB_DIR / "index.html")


@router.get("/manifest.json")
async def manifest() -> FileResponse:
    return FileResponse(
        WEB_DIR / "manifest.json",
        media_type="application/manifest+json",
    )


@router.get("/sw.js")
async def service_worker() -> FileResponse:
    return FileResponse(
        WEB_DIR / "sw.js",
        media_type="application/javascript",
    )


@router.get("/api/state")
async def get_state(request: Request) -> dict[str, object]:
    state_manager: StateManager = request.app.state.state_manager
    session_manager: ChatSessionManager = request.app.state.session_manager
    state = state_manager.state.to_dict()
    state["chat_sessions"] = session_manager.list_sessions()
    return state


@router.get("/api/health")
async def health_check(request: Request) -> dict[str, object]:
    connected_clients: list[WebSocket] = request.app.state.connected_clients
    state_manager: StateManager = request.app.state.state_manager
    return {
        "status": "ok",
        "version": "0.1.0",
        "connected_clients": len(connected_clients),
        "ble_connected": state_manager.state.ble_connected,
    }


@router.post("/api/approve")
async def approve_request(
    request: Request, decision_input: DecisionInput
) -> dict[str, str]:
    state_manager: StateManager = request.app.state.state_manager
    success = await state_manager.make_decision(
        decision_input.request_id, DecisionStatus.APPROVED
    )
    if not success:
        raise HTTPException(
            status_code=404, detail="Request not found or already decided"
        )
    return {"status": "approved"}


@router.post("/api/deny")
async def deny_request(request: Request, decision_input: DecisionInput) -> dict[str, str]:
    state_manager: StateManager = request.app.state.state_manager
    success = await state_manager.make_decision(
        decision_input.request_id, DecisionStatus.DENIED
    )
    if not success:
        raise HTTPException(
            status_code=404, detail="Request not found or already decided"
        )
    return {"status": "denied"}


@router.post("/api/yolo")
async def toggle_yolo(request: Request, yolo_input: YoloInput) -> dict[str, object]:
    state_manager: StateManager = request.app.state.state_manager
    await state_manager.set_yolo_mode(enabled=yolo_input.enabled)
    return {"status": "ok", "yolo_mode": yolo_input.enabled}


@router.post("/api/reset")
async def reset_session(request: Request) -> dict[str, str]:
    state_manager: StateManager = request.app.state.state_manager
    await state_manager.reset_session()
    return {"status": "ok"}


@router.get("/api/projects")
async def list_projects(request: Request) -> dict[str, object]:
    state_manager: StateManager = request.app.state.state_manager
    return {
        "projects": state_manager.state.get_project_list(),
        "active_project": state_manager.state.active_project,
    }


@router.get("/api/projects/{project_path:path}")
async def get_project_state(request: Request, project_path: str) -> dict[str, object]:
    state_manager: StateManager = request.app.state.state_manager
    decoded_path = urllib.parse.unquote(project_path)
    project_state = state_manager.get_project_state(decoded_path)
    return project_state.to_dict()


@router.post("/api/projects/active")
async def set_active_project(
    request: Request, data: dict[str, str | None]
) -> dict[str, object]:
    state_manager: StateManager = request.app.state.state_manager
    project_path = data.get("project_path")
    await state_manager.set_active_project(project_path)
    return {
        "status": "ok",
        "active_project": state_manager.state.active_project,
    }

