"""Hook API 路由 - Phase 7.5"""

from typing import Any

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

from app.agents.tools.hooks import HookType
from app.agents.tools.hooks.builtins import (
    AuditLogHook,
    DangerousConfirmationHook,
    SecurityScanHook,
)
from app.agents.tools.hooks.config import (
    HookConfigEntry,
    get_hook_config_persistence,
)
from app.agents.tools.hooks.manager import get_hook_manager

router = APIRouter(prefix="/api/hooks", tags=["Hooks"])


class HookInfo(BaseModel):
    """Hook 信息"""

    name: str
    hook_type: str
    description: str
    builtin: bool


class HookConfigUpdate(BaseModel):
    """更新 Hook 配置"""

    entries: list[HookConfigEntry]


class HookConfigResponse(BaseModel):
    """Hook 配置响应"""

    entries: list[dict[str, Any]]
    count: int


class HookStatusResponse(BaseModel):
    """Hook 状态响应"""

    name: str
    enabled: bool
    hook_type: str
    registered: bool


# 内置 Hook 注册表
BUILTIN_HOOKS: dict[str, dict[str, str]] = {
    "audit_log": {
        "name": "audit_log",
        "hook_type": "pre_tool_use,post_tool_use,tool_error",
        "description": "审计日志 Hook - 记录所有工具调用",
        "class": "AuditLogHook",
    },
    "dangerous_confirmation": {
        "name": "dangerous_confirmation",
        "hook_type": "pre_tool_use",
        "description": "危险操作确认 Hook - 拦截危险工具调用",
        "class": "DangerousConfirmationHook",
    },
    "security_scan": {
        "name": "security_scan",
        "hook_type": "post_tool_use",
        "description": "安全扫描 Hook - 检测敏感信息泄露",
        "class": "SecurityScanHook",
    },
}


@router.get("/available", response_model=list[HookInfo])
async def list_available_hooks() -> list[HookInfo]:
    """列出所有可用的内置 Hook"""
    return [
        HookInfo(
            name=info["name"],
            hook_type=info["hook_type"],
            description=info["description"],
            builtin=True,
        )
        for info in BUILTIN_HOOKS.values()
    ]


@router.get("/config", response_model=HookConfigResponse)
async def get_hook_config() -> HookConfigResponse:
    """获取当前 Hook 配置"""
    persistence = get_hook_config_persistence()
    entries = persistence.load_config()
    return HookConfigResponse(
        entries=[vars(e) if isinstance(e, HookConfigEntry) else e for e in entries],
        count=len(entries),
    )


@router.post("/config", response_model=HookConfigResponse)
async def update_hook_config(
    entries: list[HookConfigEntry],
) -> HookConfigResponse:
    """更新 Hook 配置"""
    persistence = get_hook_config_persistence()
    success = persistence.save_config(entries)
    if not success:
        raise HTTPException(status_code=500, detail="Failed to save hook config")

    # 应用配置到 HookManager
    manager = get_hook_manager()
    manager.clear()  # 清除旧配置
    persistence.apply_config()  # 应用新配置

    return HookConfigResponse(
        entries=[vars(e) if isinstance(e, HookConfigEntry) else e for e in entries],
        count=len(entries),
    )


@router.post("/apply-config", response_model=dict[str, Any])
async def apply_hook_config() -> dict[str, Any]:
    """应用配置文件到 HookManager"""
    persistence = get_hook_config_persistence()
    manager = get_hook_manager()
    manager.clear()
    count = persistence.apply_config()
    return {"applied": count, "message": f"Applied {count} hook configurations"}


@router.get("/status", response_model=list[HookStatusResponse])
async def get_hook_status() -> list[HookStatusResponse]:
    """获取所有已注册 Hook 的状态"""
    manager = get_hook_manager()
    all_hooks = manager.list_all()

    # 按名称索引已注册的 hooks
    registered: dict[str, dict[str, Any]] = {}
    for hook in all_hooks:
        registered[hook.name] = {
            "name": hook.name,
            "enabled": hook.enabled,
            "hook_type": hook.hook_type.value,
            "registered": True,
        }

    # 合并内置 Hook 信息
    result: list[HookStatusResponse] = []
    seen: set[str] = set()

    # 先添加已注册的
    for hook in all_hooks:
        result.append(
            HookStatusResponse(
                name=hook.name,
                enabled=hook.enabled,
                hook_type=hook.hook_type.value,
                registered=True,
            )
        )
        seen.add(hook.name)

    # 再添加内置但未注册的
    for name, info in BUILTIN_HOOKS.items():
        if name not in seen:
            result.append(
                HookStatusResponse(
                    name=name,
                    enabled=False,
                    hook_type=info["hook_type"],
                    registered=False,
                )
            )

    return result


@router.post("/{name}/enable", response_model=dict[str, str])
async def enable_hook(name: str) -> dict[str, str]:
    """启用指定 Hook"""
    manager = get_hook_manager()
    if manager.enable(name):
        return {"status": "enabled", "name": name}
    raise HTTPException(status_code=404, detail=f"Hook '{name}' not found")


@router.post("/{name}/disable", response_model=dict[str, str])
async def disable_hook(name: str) -> dict[str, str]:
    """禁用指定 Hook"""
    manager = get_hook_manager()
    if manager.disable(name):
        return {"status": "disabled", "name": name}
    raise HTTPException(status_code=404, detail=f"Hook '{name}' not found")


@router.post("/register-builtin", response_model=dict[str, str])
async def register_builtin_hook(
    name: str,
    hook_type: str = "pre_tool_use",
) -> dict[str, str]:
    """注册内置 Hook 到 HookManager"""
    from app.agents.tools.hooks.types import HookDefinition, HookTrigger

    manager = get_hook_manager()

    if name == "audit_log":
        hook_instance = AuditLogHook()
        handler = hook_instance.pre_tool_use
        hook_types = [HookType.PRE_TOOL_USE, HookType.POST_TOOL_USE, HookType.TOOL_ERROR]
    elif name == "dangerous_confirmation":
        hook_instance = DangerousConfirmationHook()
        handler = hook_instance.pre_tool_use
        hook_types = [HookType.PRE_TOOL_USE]
    elif name == "security_scan":
        hook_instance = SecurityScanHook()
        handler = hook_instance.post_tool_use
        hook_types = [HookType.POST_TOOL_USE]
    else:
        raise HTTPException(status_code=404, detail=f"Unknown builtin hook: {name}")

    registered = []
    for ht in hook_types:
        hook_def = HookDefinition(
            name=f"{name}_{ht.value}",
            hook_type=ht,
            trigger=HookTrigger(),
            handler=handler,
            priority=0,
            enabled=True,
            description=f"Built-in {name} hook",
        )
        manager.register(hook_def)
        registered.append(ht.value)

    return {
        "status": "registered",
        "name": name,
        "hook_types": ", ".join(registered),
    }
