/**
 * Hook 系统类型定义
 *
 * 参考 open-code 的 hook 实现
 */

import type { Tool, ToolResult } from '../types/index.js';

/**
 * Hook 类型枚举
 */
export type HookType =
  | 'tool.execute.before' // 工具执行前
  | 'tool.execute.after' // 工具执行后
  | 'session.start' // 会话开始
  | 'session.end' // 会话结束
  | 'message.before' // 消息发送前
  | 'message.after' // 消息接收后
  | 'file.edited' // 文件被编辑后
  | 'file.created' // 文件被创建后
  | 'file.deleted'; // 文件被删除后

/**
 * 工具执行前 Hook 的输入
 */
export interface ToolExecuteBeforeInput {
  tool: string;
  sessionId: string;
  callId: string;
  args: Record<string, unknown>;
}

/**
 * 工具执行前 Hook 的输出（可修改）
 */
export interface ToolExecuteBeforeOutput {
  args: Record<string, unknown>;
  /** 设为 true 可阻止工具执行 */
  skip?: boolean;
  /** 跳过时返回的结果 */
  skipResult?: ToolResult;
}

/**
 * 工具执行后 Hook 的输入
 */
export interface ToolExecuteAfterInput {
  tool: string;
  sessionId: string;
  callId: string;
  args: Record<string, unknown>;
  duration: number; // 执行时长（毫秒）
}

/**
 * 工具执行后 Hook 的输出（可修改）
 */
export interface ToolExecuteAfterOutput {
  result: ToolResult;
}

/**
 * 会话开始 Hook 的输入
 */
export interface SessionStartInput {
  sessionId: string;
  workdir: string;
}

/**
 * 会话结束 Hook 的输入
 */
export interface SessionEndInput {
  sessionId: string;
  messageCount: number;
  duration: number; // 会话时长（毫秒）
}

/**
 * 消息前 Hook 的输入
 */
export interface MessageBeforeInput {
  sessionId: string;
  content: string;
}

/**
 * 消息前 Hook 的输出（可修改）
 */
export interface MessageBeforeOutput {
  content: string;
  /** 设为 true 可阻止消息发送 */
  skip?: boolean;
}

/**
 * 消息后 Hook 的输入
 */
export interface MessageAfterInput {
  sessionId: string;
  content: string;
  toolCalls: number;
}

/**
 * 文件变更 Hook 的输入
 */
export interface FileChangeInput {
  path: string;
  tool: string;
  sessionId: string;
}

/**
 * 文件变更 Hook 的输出
 */
export interface FileChangeOutput {
  /** 执行的命令结果 */
  commandResults?: Array<{
    command: string[];
    success: boolean;
    output?: string;
    error?: string;
  }>;
}

/**
 * Shell 命令配置
 */
export interface ShellCommandConfig {
  /** 命令数组，第一个元素是命令，后面是参数 */
  command: string[];
  /** 环境变量 */
  environment?: Record<string, string>;
  /** 超时时间（毫秒），默认 30000 */
  timeout?: number;
  /** 工作目录，默认使用当前目录 */
  cwd?: string;
}

/**
 * 文件 Hook 配置
 * 支持 glob 模式匹配文件
 */
export interface FileHookConfig {
  /** glob 模式 -> 命令配置列表 */
  [pattern: string]: ShellCommandConfig[];
}

/**
 * Hook 配置
 */
export interface HookConfig {
  /** 文件编辑后执行的 hook */
  file_edited?: FileHookConfig;
  /** 文件创建后执行的 hook */
  file_created?: FileHookConfig;
  /** 文件删除后执行的 hook */
  file_deleted?: FileHookConfig;
  /** 会话完成后执行的命令 */
  session_completed?: ShellCommandConfig[];
}

/**
 * Hook 函数类型
 */
export type HookFunction<Input, Output> = (
  input: Input,
  output: Output
) => Promise<void>;

/**
 * Hook 定义接口
 */
export interface Hooks {
  'tool.execute.before'?: HookFunction<ToolExecuteBeforeInput, ToolExecuteBeforeOutput>;
  'tool.execute.after'?: HookFunction<ToolExecuteAfterInput, ToolExecuteAfterOutput>;
  'session.start'?: (input: SessionStartInput) => Promise<void>;
  'session.end'?: (input: SessionEndInput) => Promise<void>;
  'message.before'?: HookFunction<MessageBeforeInput, MessageBeforeOutput>;
  'message.after'?: (input: MessageAfterInput) => Promise<void>;
  'file.edited'?: HookFunction<FileChangeInput, FileChangeOutput>;
  'file.created'?: HookFunction<FileChangeInput, FileChangeOutput>;
  'file.deleted'?: HookFunction<FileChangeInput, FileChangeOutput>;
}

/**
 * 插件输入
 */
export interface PluginInput {
  /** 当前工作目录 */
  workdir: string;
  /** 会话 ID */
  sessionId?: string;
}

/**
 * 插件定义
 * 一个插件是一个函数，接收 PluginInput 返回 Hooks
 */
export type Plugin = (input: PluginInput) => Promise<Hooks>;

/**
 * Hook 事件
 */
export interface HookEvent {
  type: HookType;
  timestamp: number;
  data: unknown;
}

/**
 * Hook 事件监听器
 */
export type HookEventListener = (event: HookEvent) => void;
