"""中控 AI FastAPI 路由."""
from __future__ import annotations

import asyncio
from typing import Callable

from fastapi import APIRouter, Body, File, Form, HTTPException, UploadFile
from pydantic import BaseModel, Field

from hub_ai.archive_quote import send_archive_quote_review
from hub_ai.chat import (
    get_chat_state,
    remove_chat_session,
    send_chat_message,
    start_new_chat,
    switch_chat_session,
)
from hub_ai.client import model_label
from hub_ai.config import trading_day_reset_hour
from hub_ai.context import build_daily_context
from hub_ai.store import get_latest_summary, list_summaries
from hub_ai.supervisor import send_supervisor_chat
from hub_ai.supervisor_store import get_supervisor_session_state
from hub_ai.summary import generate_daily_summary
from lib.hub.hub_trades_lib import current_trading_day
from settings_store import normalize_supervisor_settings


class ChatSendBody(BaseModel):
    message: str = ""
    trading_day: str = ""


class SummaryGenerateBody(BaseModel):
    trading_day: str = ""
    force: bool = False


class ChatNewBody(BaseModel):
    trading_day: str = ""
    bot_mode: str = "trading"


class ChatSwitchBody(BaseModel):
    session_id: str = Field(..., min_length=1)


class ArchiveQuoteChatBody(BaseModel):
    quote_date: str = ""
    content: str = ""


class SupervisorChatBody(BaseModel):
    message: str = ""
    trading_day: str = ""


def create_hub_ai_router(*, load_all_exchanges: Callable[[], list]) -> APIRouter:
    router = APIRouter(prefix="/api/ai", tags=["hub-ai"])

    def _day(raw: str = "") -> str:
        d = (raw or "").strip()[:10]
        return d or current_trading_day(reset_hour=trading_day_reset_hour())

    @router.get("/meta")
    def api_ai_meta():
        return {
            "ok": True,
            "model": model_label(),
            "trading_day_reset_hour": trading_day_reset_hour(),
            "trading_day": current_trading_day(reset_hour=trading_day_reset_hour()),
            "storage": {
                "summaries": "hub_ai_summaries.json",
                "chat": "hub_ai_chat.json",
            },
        }

    @router.get("/context")
    def api_ai_context(trading_day: str = ""):
        exchanges = load_all_exchanges()
        ctx = build_daily_context(exchanges, trading_day=_day(trading_day))
        return {"ok": True, **ctx}

    @router.get("/summary")
    def api_ai_summary_list(trading_day: str = ""):
        day = _day(trading_day) if trading_day.strip() else ""
        items = list_summaries(trading_day=day or None, limit=20)
        latest = get_latest_summary(_day(trading_day)) if trading_day.strip() else (
            items[0] if items else None
        )
        return {
            "ok": True,
            "trading_day": _day(trading_day) if trading_day.strip() else None,
            "summaries": items,
            "latest": latest,
            "model": model_label(),
        }

    @router.post("/summary/generate")
    def api_ai_summary_generate(body: SummaryGenerateBody = SummaryGenerateBody()):
        exchanges = load_all_exchanges()
        result = generate_daily_summary(
            exchanges,
            trading_day=_day(body.trading_day) if body.trading_day.strip() else None,
            force=bool(body.force),
        )
        if not result.get("ok"):
            raise HTTPException(status_code=502, detail=result.get("msg") or "生成失败")
        result.pop("context", None)
        return result

    @router.get("/chat/session")
    def api_ai_chat_session():
        state = get_chat_state()
        return {"ok": True, **state, "model": model_label()}

    @router.post("/chat/new")
    def api_ai_chat_new(body: ChatNewBody = ChatNewBody()):
        day = _day(body.trading_day)
        return start_new_chat(trading_day=day, bot_mode=body.bot_mode or "trading")

    @router.post("/chat/switch")
    def api_ai_chat_switch(body: ChatSwitchBody):
        try:
            return switch_chat_session(body.session_id.strip())
        except KeyError:
            raise HTTPException(status_code=404, detail="会话不存在")

    @router.delete("/chat/session/{session_id}")
    def api_ai_chat_delete(session_id: str):
        result = remove_chat_session(session_id.strip())
        if not result.get("ok"):
            raise HTTPException(status_code=404, detail="会话不存在")
        return result

    @router.post("/chat/archive-quote")
    def api_ai_chat_archive_quote(body: ArchiveQuoteChatBody = Body(...)):
        result = send_archive_quote_review(
            quote_date=body.quote_date,
            content=body.content,
        )
        if not result.get("ok"):
            raise HTTPException(status_code=502, detail=result.get("msg") or "发送失败")
        return result

    @router.post("/chat/send")
    async def api_ai_chat_send(
        message: str = Form(""),
        trading_day: str = Form(""),
        files: list[UploadFile] = File(default=[]),
    ):
        exchanges = load_all_exchanges()
        raw_attachments = []
        for f in files or []:
            if not f or not f.filename:
                continue
            data = await f.read()
            raw_attachments.append(
                {
                    "filename": f.filename,
                    "content_type": f.content_type or "",
                    "data": data,
                }
            )
        result = await asyncio.to_thread(
            send_chat_message,
            exchanges,
            message,
            trading_day=_day(trading_day) if trading_day.strip() else None,
            raw_attachments=raw_attachments,
        )
        if not result.get("ok"):
            raise HTTPException(status_code=502, detail=result.get("msg") or "发送失败")
        return result

    @router.get("/supervisor/session")
    def api_ai_supervisor_session(trading_day: str = ""):
        day = _day(trading_day)
        return get_supervisor_session_state(day)

    @router.get("/supervisor/rules")
    def api_ai_supervisor_rules():
        from settings_store import load_settings

        cfg = normalize_supervisor_settings(load_settings().get("supervisor"))
        return {"ok": True, "supervisor": cfg}

    @router.post("/supervisor/chat/send")
    def api_ai_supervisor_chat_send(body: SupervisorChatBody = SupervisorChatBody()):
        exchanges = load_all_exchanges()
        result = send_supervisor_chat(
            exchanges,
            body.message,
            trading_day=_day(body.trading_day) if body.trading_day.strip() else None,
        )
        if not result.get("ok"):
            raise HTTPException(status_code=502, detail=result.get("msg") or "发送失败")
        return result

    return router
