from __future__ import annotations

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session

from app.api.deps import (
    CurrentUserContext,
    get_current_user,
    get_db,
    get_optional_current_user,
)
from app.schemas.common import ErrorResponse
from app.schemas.orchestrator import (
    ConversationDeleteResponse,
    ConversationLookupResponse,
    OrchestratorRequest,
    OrchestratorResponse,
)
from app.services.agent_conversations import AgentConversationService
from app.services.orchestrator import OrchestratorService

router = APIRouter(prefix="/orchestrator")
DbSession = Annotated[Session, Depends(get_db)]
CurrentUser = Annotated[CurrentUserContext, Depends(get_current_user)]
OptionalCurrentUser = Annotated[
    CurrentUserContext | None,
    Depends(get_optional_current_user),
]


@router.post(
    "/run",
    response_model=OrchestratorResponse,
    summary="运行 Orchestrator 统一调度",
    description="统一接收用户消息、定时任务和系统事件，完成语义解析、权限判断、路由和占位执行。",
    responses={
        status.HTTP_400_BAD_REQUEST: {
            "model": ErrorResponse,
            "description": "请求缺少 message 或 task_id，无法启动调度。",
        }
    },
)
def run_orchestrator(
    payload: OrchestratorRequest,
    db: DbSession,
    current_user: OptionalCurrentUser,
) -> OrchestratorResponse:
    if current_user is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="请先登录后再使用智能助手。",
            headers={"WWW-Authenticate": "Bearer"},
        )
    if payload.source in {"schedule", "system_event"} and not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="只有平台管理员可以从外部触发调度或系统事件。",
        )
    try:
        return OrchestratorService(db).run(payload, current_user=current_user)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc


@router.get(
    "/conversations/latest",
    response_model=ConversationLookupResponse,
    summary="查询当前用户最近会话",
    description="返回当前用户最近一段可恢复的对话会话及完整消息历史。",
)
def get_latest_conversation(
    db: DbSession,
    current_user: CurrentUser,
    user_id: Annotated[
        str | None,
        Query(description="兼容旧客户端；服务端始终使用当前登录用户。"),
    ] = None,
    session_type: Annotated[
        str | None,
        Query(description="会话类型，例如 expense / knowledge。"),
    ] = None,
    prefer_recoverable: Annotated[
        bool,
        Query(description="是否优先返回最近一条可恢复的会话。"),
    ] = False,
) -> ConversationLookupResponse:
    service = AgentConversationService(db)
    conversation = service.get_latest_conversation_for_user(
        user_id=current_user.username,
        tenant_id=current_user.tenant_id,
        source="user_message",
        session_type=session_type,
        prefer_recoverable=prefer_recoverable,
    )
    if conversation is None:
        return ConversationLookupResponse(found=False, conversation=None)

    return ConversationLookupResponse(
        found=True,
        conversation=service.serialize_conversation(conversation, include_messages=True),
    )


@router.delete(
    "/conversations/{conversation_id}",
    response_model=ConversationDeleteResponse,
    summary="删除当前用户单个会话",
    description="删除当前用户在智能体工作台中的单个会话，用于清空当前 session 内容。",
)
def delete_single_conversation(
    conversation_id: str,
    db: DbSession,
    current_user: CurrentUser,
    user_id: Annotated[
        str | None,
        Query(description="兼容旧客户端；服务端始终使用当前登录用户。"),
    ] = None,
) -> ConversationDeleteResponse:
    del user_id
    deleted_count = AgentConversationService(db).delete_conversation(
        conversation_id=conversation_id,
        user_id=current_user.username,
        tenant_id=current_user.tenant_id,
        source="user_message",
    )
    return ConversationDeleteResponse(deleted_count=deleted_count)


@router.delete(
    "/conversations",
    response_model=ConversationDeleteResponse,
    summary="删除当前用户全部会话",
    description="删除当前用户在智能体工作台中的全部历史会话，用于显式开启全新对话。",
)
def delete_user_conversations(
    db: DbSession,
    current_user: CurrentUser,
    user_id: Annotated[
        str | None,
        Query(description="兼容旧客户端；服务端始终使用当前登录用户。"),
    ] = None,
    session_type: Annotated[
        str | None,
        Query(description="可选，会话类型，例如 expense / knowledge。"),
    ] = None,
) -> ConversationDeleteResponse:
    deleted_count = AgentConversationService(db).delete_user_conversations(
        user_id=current_user.username,
        tenant_id=current_user.tenant_id,
        source="user_message",
        session_type=session_type,
    )
    return ConversationDeleteResponse(deleted_count=deleted_count)
