from __future__ import annotations

from typing import Annotated

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

from app.api.deps import (
    CurrentUserContext,
    get_current_user,
    get_db,
    require_platform_admin_user,
)
from app.core.config import get_settings as get_runtime_settings
from app.schemas.common import ErrorResponse
from app.schemas.settings import (
    ModelConnectivityTestRead,
    ModelConnectivityTestRequest,
    RuntimeModelConfigRead,
    SettingsCacheClearRead,
    SettingsRead,
    SettingsWrite,
)
from app.services.model_connectivity import probe_model_connectivity
from app.services.settings import SettingsService
from app.services.system_cache import SystemCacheService

router = APIRouter(prefix="/settings")
DbSession = Annotated[Session, Depends(get_db)]


def require_hermes_agent_token(
    authorization: Annotated[
        str | None,
        Header(description="Hermes 读取运行时模型配置时使用的 Bearer Token。"),
    ] = None,
) -> None:
    configured_token = str(get_runtime_settings().hermes_agent_shared_token or "").strip()
    if not configured_token:
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
            detail="Hermes 集成令牌未配置。",
        )

    normalized = str(authorization or "").strip()
    expected = f"Bearer {configured_token}"
    if normalized != expected:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Hermes 集成鉴权失败。",
        )


@router.get(
    "",
    response_model=SettingsRead,
    summary="读取系统设置",
    description="返回公司、管理员、模型、日志、邮件和 ONLYOFFICE 的设置快照。",
)
def get_settings(
    db: DbSession,
    _: Annotated[CurrentUserContext, Depends(get_current_user)],
) -> SettingsRead:
    return SettingsService(db).get_settings_snapshot()


@router.put(
    "",
    response_model=SettingsRead,
    summary="保存系统设置",
    description="保存系统设置，并同步运行时模型配置与 Hermes 使用的模型路由。",
    responses={
        status.HTTP_400_BAD_REQUEST: {
            "model": ErrorResponse,
            "description": "设置字段校验失败。",
        }
    },
)
def update_settings(
    payload: SettingsWrite,
    db: DbSession,
    _: Annotated[CurrentUserContext, Depends(require_platform_admin_user)],
) -> SettingsRead:
    try:
        return SettingsService(db).save_settings_snapshot(payload)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc


@router.post(
    "/model-connectivity",
    response_model=ModelConnectivityTestRead,
    summary="测试模型连通性",
    description="验证指定模型服务端点是否可用；当未传 API Key 且提供 slot 时会尝试复用已保存密钥。",
)
def test_model_connectivity(
    payload: ModelConnectivityTestRequest,
    db: DbSession,
    _: Annotated[CurrentUserContext, Depends(require_platform_admin_user)],
) -> ModelConnectivityTestRead:
    resolved_payload = payload

    if not payload.api_key and payload.slot:
        stored_api_key = SettingsService(db).load_saved_model_api_key(payload.slot)
        if stored_api_key:
            resolved_payload = payload.model_copy(update={"api_key": stored_api_key})

    return probe_model_connectivity(resolved_payload)


@router.post(
    "/cache/clear",
    response_model=SettingsCacheClearRead,
    summary="清理系统缓存",
    description=(
        "清理 OCR、模型失败冷却、知识库索引和运行时配置等进程内缓存，"
        "不删除业务文件或数据库记录。"
    ),
    responses={
        status.HTTP_403_FORBIDDEN: {
            "model": ErrorResponse,
            "description": "只有管理员可以清理系统缓存。",
        }
    },
)
def clear_system_cache(
    _: Annotated[CurrentUserContext, Depends(require_platform_admin_user)],
) -> SettingsCacheClearRead:
    return SystemCacheService().clear_all()


@router.get(
    "/runtime-models/{slot}",
    response_model=RuntimeModelConfigRead,
    dependencies=[Depends(require_hermes_agent_token)],
    summary="读取 Hermes 运行时模型配置",
    description="供 Hermes 进程读取主模型、备用模型、Embedding 或 Reranker 模型的运行时配置。",
    responses={
        status.HTTP_401_UNAUTHORIZED: {
            "model": ErrorResponse,
            "description": "Hermes 令牌校验失败。",
        },
        status.HTTP_404_NOT_FOUND: {
            "model": ErrorResponse,
            "description": "指定模型槽位不存在。",
        },
        status.HTTP_503_SERVICE_UNAVAILABLE: {
            "model": ErrorResponse,
            "description": "Hermes 集成令牌尚未配置。",
        },
    },
)
def get_runtime_model_config(
    slot: str,
    db: DbSession,
) -> RuntimeModelConfigRead:
    try:
        payload = SettingsService(db).get_runtime_model_config(slot)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc

    return RuntimeModelConfigRead(**payload)
