"""Hook 类型定义 - Phase 6.2

Hook 拦截系统类型定义。
"""

from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Callable


class HookType(Enum):
    """Hook 类型"""

    PRE_TOOL_USE = "pre_tool_use"  # 工具执行前
    POST_TOOL_USE = "post_tool_use"  # 工具执行后
    TOOL_ERROR = "tool_error"  # 工具执行出错
    TOOL_SKIP = "tool_skip"  # 工具跳过（条件执行）


class HookStage(Enum):
    """Hook 执行阶段"""

    BEFORE = "before"
    AFTER = "after"
    ON_ERROR = "on_error"


@dataclass
class HookTrigger:
    """Hook 触发条件"""

    tool_names: list[str] | None = None  # 只对特定工具生效，None 表示全部
    categories: list[str] | None = None  # 只对特定类别生效
    conditions: dict[str, Any] | None = None  # 自定义条件


@dataclass
class HookDefinition:
    """Hook 定义"""

    name: str
    hook_type: HookType
    trigger: HookTrigger
    handler: Callable[..., Any]  # Hook 处理函数
    priority: int = 0  # 优先级，数字越大越先执行
    enabled: bool = True
    description: str = ""


@dataclass
class HookResult:
    """Hook 执行结果"""

    hook_name: str
    success: bool
    continue_execution: bool = True  # False 表示中断执行
    modified_input: Any = None  # 修改后的输入
    modified_output: Any = None  # 修改后的输出
    error: str | None = None
    metadata: dict[str, Any] = field(default_factory=dict)


@dataclass
class ExecutionContext:
    """工具执行上下文"""

    tool_name: str
    tool_input: dict[str, Any]
    user_id: str | None = None
    session_id: str | None = None
    metadata: dict[str, Any] = field(default_factory=dict)

    # 执行结果（由 HookExecutor 填充）
    result: Any = None
    error: Exception | None = None
    start_time: float | None = None
    end_time: float | None = None


# Hook 处理函数类型
HookHandler = Callable[[ExecutionContext, HookDefinition], HookResult]

# Pre-hook: 在工具执行前调用，可以修改输入或决定是否跳过
PreToolHook = Callable[[ExecutionContext], tuple[bool, dict[str, Any] | None]]
# post-hook: 在工具执行后调用，可以修改输出
PostToolHook = Callable[[ExecutionContext, Any], Any]
# Error hook: 在工具出错时调用
ErrorToolHook = Callable[[ExecutionContext, Exception], HookResult | None]
# Skip hook: 决定是否跳过工具执行
SkipToolHook = Callable[[ExecutionContext], bool]
