import asyncio
import json
from pathlib import Path

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from starlette.responses import Response

from app.db import close_pool, fetch_all, init_pool
from app.routes import (
    retail,
    agents,
    analytics,
    documents,
    api,
    clients,
    dashboard,
    deals,
    herman,
    studio,
    marketing,
    monitor,
    products,
    reports,
    suppliers,
    voice,
    settings,
    browser,
    hermes,
    beurs,
    packaging,
    ops,
    ops_api,
    revenue_cockpit,
    export_intel,
)
from app.routes.revenue_cockpit import api as revenue_cockpit_api
from app.routes.admin_api import admin_router, ai_router, herman_api, voice_api
from app.routes.settings_api import settings_router
from app.routes.agents_api import router as agents_api_router
from app.routes.marketing_api import router as marketing_api_router
from app.routes.projects_api import router as projects_api_router

BASE_DIR = Path(__file__).resolve().parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))


class NoCacheStaticFiles(StaticFiles):
    """Serve static assets without browser/SW long-lived caching."""

    async def get_response(self, path: str, scope) -> Response:
        response = await super().get_response(path, scope)
        if path.endswith((".css", ".js", ".html")) or "/css/" in path or "/js/" in path:
            response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
            response.headers["Pragma"] = "no-cache"
            response.headers["Expires"] = "0"
        return response


app = FastAPI(title="Foodlinkk Command Center", version="2.5.0")
app.mount("/static", NoCacheStaticFiles(directory=str(BASE_DIR / "static")), name="static")

for r in (
    dashboard.router,
    beurs.router,
    agents.router,
    marketing.router,
    retail.router,
    clients.router,
    deals.router,
    products.router,
    suppliers.router,
    monitor.router,
    analytics.router,
    documents.router,
    reports.router,
    voice.router,
    settings.router,
    browser.router,
    herman.router,
    studio.router,
    hermes.router,
    packaging.router,
    ops.router,
    revenue_cockpit.router,
    export_intel.router,
    revenue_cockpit_api,
    api.router,
    ops_api.router,
    admin_router,
    ai_router,
    herman_api,
    voice_api,
    settings_router,
    agents_api_router,
    marketing_api_router,
    projects_api_router,
):
    app.include_router(r)


@app.on_event("startup")
def on_startup() -> None:
    init_pool()


@app.on_event("shutdown")
def on_shutdown() -> None:
    close_pool()


@app.websocket("/ws/agents")
async def ws_agents(websocket: WebSocket) -> None:
    await websocket.accept()
    last_payload: str | None = None
    try:
        while True:
            try:
                rows = fetch_all(
                    """SELECT id, agent_name, event_type, title, body, status, created_at
                       FROM agent_events ORDER BY created_at DESC LIMIT 50"""
                )
                for row in rows:
                    if row.get("created_at") is not None:
                        row["created_at"] = row["created_at"].isoformat()
                payload = json.dumps({"events": rows})
            except Exception as exc:
                payload = json.dumps({"error": str(exc), "events": []})
            if payload != last_payload:
                await websocket.send_text(payload)
                last_payload = payload
            await asyncio.sleep(3)
    except WebSocketDisconnect:
        return


@app.websocket("/ws/feed")
async def ws_feed(websocket: WebSocket) -> None:
    await websocket.accept()
    try:
        while True:
            snapshot = {"type": "heartbeat", "events": []}
            try:
                snapshot["events"] = fetch_all(
                    "SELECT agent_name, event_type, title, status, created_at FROM agent_events ORDER BY created_at DESC LIMIT 15"
                )
                for row in snapshot["events"]:
                    if row.get("created_at"):
                        row["created_at"] = row["created_at"].isoformat()
            except Exception as exc:
                snapshot["error"] = str(exc)
            await websocket.send_text(json.dumps(snapshot))
            await asyncio.sleep(5)
    except WebSocketDisconnect:
        return
