"""Projects + UI preferences API."""
from __future__ import annotations

from typing import Any, Optional

from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel, Field

from app.services import projects, ui_preferences, nas_folders

router = APIRouter(tags=["projects-api"])


class ProjectCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=255)
    client_id: Optional[int] = None
    description: str = ""
    created_by: str = "ceo"
    project_type: str = "general"
    priority: str = "normal"


class ProjectUpdate(BaseModel):
    name: Optional[str] = None
    description: Optional[str] = None
    status: Optional[str] = None
    client_id: Optional[int] = None
    project_type: Optional[str] = None
    priority: Optional[str] = None


class AssetCreate(BaseModel):
    asset_type: str
    title: str
    ref_id: Optional[str] = None
    file_path: Optional[str] = None
    payload: dict[str, Any] = Field(default_factory=dict)
    created_by: str = "ceo"
    source_agent: Optional[str] = None


class LinkPhotoBody(BaseModel):
    project_id: int
    created_by: str = "ceo"


class LinkNasFileBody(BaseModel):
    title: str
    file_path: str
    asset_type: str = "document"


class PreferencesBody(BaseModel):
    dashboard_layout: Optional[list[str]] = None
    dashboard_widgets: Optional[dict[str, bool]] = None
    dashboard_kpis: Optional[list[str]] = None
    global_viz_mode: Optional[str] = None
    viz_modes: Optional[dict[str, str]] = None
    locale: Optional[str] = None


@router.get("/projects")
async def projects_page(request: Request):
    from fastapi.templating import Jinja2Templates
    from pathlib import Path
    templates = Jinja2Templates(directory=str(Path(__file__).resolve().parent.parent.parent / "templates"))
    return templates.TemplateResponse("projects.html", {"request": request, "page_title": "Projecten"})


@router.get("/api/projects/types")
def api_project_types() -> dict[str, Any]:
    return {"items": nas_folders.list_types()}


@router.get("/api/projects/stats")
def api_project_stats() -> dict[str, Any]:
    return {"ok": True, "stats": projects.project_stats()}


@router.get("/api/projects")
def api_list_projects(client_id: Optional[int] = None, limit: int = 50) -> dict[str, Any]:
    items = projects.list_projects(client_id=client_id, limit=limit)
    return {"items": items, "count": len(items)}


@router.post("/api/projects")
def api_create_project(body: ProjectCreate) -> dict[str, Any]:
    try:
        row = projects.create_project(
            body.name,
            client_id=body.client_id,
            description=body.description,
            created_by=body.created_by,
            project_type=body.project_type,
            priority=body.priority,
        )
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc
    return {"ok": True, "project": row}


@router.get("/api/projects/{project_id}")
def api_get_project(project_id: int) -> dict[str, Any]:
    row = projects.get_project(project_id)
    if not row:
        raise HTTPException(status_code=404, detail="Project not found")
    return {"project": row}


@router.patch("/api/projects/{project_id}")
def api_update_project(project_id: int, body: ProjectUpdate) -> dict[str, Any]:
    row = projects.update_project(project_id, **body.model_dump(exclude_none=True))
    if not row:
        raise HTTPException(status_code=404, detail="Project not found")
    return {"ok": True, "project": row}


@router.post("/api/projects/{project_id}/ensure-nas")
def api_ensure_nas(project_id: int) -> dict[str, Any]:
    row = projects.get_project(project_id)
    if not row:
        raise HTTPException(status_code=404, detail="Project not found")
    client_name = row.get("client_name")
    try:
        paths = nas_folders.ensure_project_folder(
            project_id,
            row["name"],
            row.get("client_id"),
            client_name,
            row.get("project_type") or "general",
        )
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc
    return {"ok": True, **paths}


@router.post("/api/projects/{project_id}/assets")
def api_add_asset(project_id: int, body: AssetCreate) -> dict[str, Any]:
    if not projects.get_project(project_id):
        raise HTTPException(status_code=404, detail="Project not found")
    try:
        asset = projects.add_asset(
            project_id,
            body.asset_type,
            body.title,
            ref_id=body.ref_id,
            file_path=body.file_path,
            payload=body.payload,
            created_by=body.created_by,
            source_agent=body.source_agent,
        )
    except Exception as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc
    return {"ok": True, "asset": asset}


@router.post("/api/projects/{project_id}/link-nas-file")
def api_link_nas_file(project_id: int, body: LinkNasFileBody) -> dict[str, Any]:
    if not projects.get_project(project_id):
        raise HTTPException(status_code=404, detail="Project not found")
    asset = projects.add_asset(
        project_id,
        body.asset_type,
        body.title,
        file_path=body.file_path,
        created_by="ceo",
    )
    return {"ok": True, "asset": asset}


@router.post("/api/projects/photos/{photo_id}/link")
def api_link_photo(photo_id: int, body: LinkPhotoBody) -> dict[str, Any]:
    try:
        projects.link_photo_to_project(photo_id, body.project_id, body.created_by)
    except ValueError as exc:
        raise HTTPException(status_code=404, detail=str(exc)) from exc
    return {"ok": True}


@router.get("/api/preferences/ui")
def api_get_ui_preferences() -> dict[str, Any]:
    return ui_preferences.get_preferences("ceo")


@router.put("/api/preferences/ui")
def api_save_ui_preferences(body: PreferencesBody) -> dict[str, Any]:
    allowed = {m["id"] for m in ui_preferences.VIZ_MODES}
    if body.global_viz_mode and body.global_viz_mode not in allowed:
        raise HTTPException(status_code=400, detail="Invalid viz mode")
    if body.locale and body.locale not in ("nl", "en"):
        raise HTTPException(status_code=400, detail="Invalid locale (nl or en)")
    prefs = ui_preferences.save_preferences(
        "ceo",
        dashboard_layout=body.dashboard_layout,
        dashboard_widgets=body.dashboard_widgets,
        dashboard_kpis=body.dashboard_kpis,
        global_viz_mode=body.global_viz_mode,
        viz_modes=body.viz_modes,
        locale=body.locale,
    )
    return {"ok": True, "preferences": prefs}
