/**
 * Skill 注册表
 *
 * 管理所有可用的 Skills，支持：
 * - 注册/注销 Skills
 * - 按名称/分类/关键词查询
 * - 渲染 Skill 提示模板
 */

import type {
  Skill,
  SkillContext,
  SkillExecutionResult,
  SkillSearchResult,
  SkillRegistryConfig,
} from './types.js';
import { skillLoader } from './loader.js';
import { builtinSkills } from './builtin/index.js';

/**
 * Skill 注册表
 */
export class SkillRegistry {
  private skills = new Map<string, Skill>();
  private config: SkillRegistryConfig;
  private initialized = false;

  constructor(config: SkillRegistryConfig = {}) {
    this.config = {
      autoLoad: true,
      ...config,
    };
  }

  /**
   * 初始化注册表
   */
  async initialize(workdir: string = process.cwd()): Promise<void> {
    if (this.initialized) {
      return;
    }

    // 1. 注册内置 Skills
    for (const skill of builtinSkills) {
      this.register(skill);
    }

    // 2. 加载用户 Skills
    if (this.config.autoLoad) {
      const userDir =
        this.config.userSkillsDir || skillLoader.getUserSkillsDir();
      const userSkills = await skillLoader.loadFromDirectory(userDir, 'user');
      for (const skill of userSkills) {
        this.register(skill);
      }
    }

    // 3. 加载项目 Skills
    if (this.config.autoLoad) {
      const projectDir =
        this.config.projectSkillsDir || skillLoader.getProjectSkillsDir(workdir);
      const projectSkills = await skillLoader.loadFromDirectory(
        projectDir,
        'project'
      );
      for (const skill of projectSkills) {
        this.register(skill);
      }
    }

    this.initialized = true;
  }

  /**
   * 注册 Skill
   */
  register(skill: Skill): void {
    // 项目 Skills 优先级最高，可以覆盖同名的内置/用户 Skills
    const existing = this.skills.get(skill.name);
    if (existing) {
      // 优先级: project > user > builtin
      const priority = { project: 3, user: 2, builtin: 1 };
      if (priority[skill.source] < priority[existing.source]) {
        return; // 不覆盖更高优先级的 Skill
      }
    }
    this.skills.set(skill.name, skill);
  }

  /**
   * 注销 Skill
   */
  unregister(name: string): boolean {
    return this.skills.delete(name);
  }

  /**
   * 获取 Skill
   */
  get(name: string): Skill | undefined {
    return this.skills.get(name);
  }

  /**
   * 检查 Skill 是否存在
   */
  has(name: string): boolean {
    return this.skills.has(name);
  }

  /**
   * 获取所有 Skills
   */
  getAll(): Skill[] {
    return Array.from(this.skills.values());
  }

  /**
   * 获取启用的 Skills
   */
  getEnabled(): Skill[] {
    return this.getAll().filter((s) => s.enabled !== false);
  }

  /**
   * 按分类获取 Skills
   */
  getByCategory(category: string): Skill[] {
    return this.getEnabled().filter((s) => s.category === category);
  }

  /**
   * 获取所有分类
   */
  getCategories(): string[] {
    const categories = new Set<string>();
    for (const skill of this.getEnabled()) {
      if (skill.category) {
        categories.add(skill.category);
      }
    }
    return Array.from(categories).sort();
  }

  /**
   * 搜索 Skills
   */
  search(query: string, limit: number = 10): SkillSearchResult[] {
    const queryLower = query.toLowerCase();
    const results: SkillSearchResult[] = [];

    for (const skill of this.getEnabled()) {
      let score = 0;
      let matchReason = '';

      // 精确名称匹配
      if (skill.name.toLowerCase() === queryLower) {
        score = 100;
        matchReason = '名称精确匹配';
      }
      // 名称前缀匹配
      else if (skill.name.toLowerCase().startsWith(queryLower)) {
        score = 80;
        matchReason = '名称前缀匹配';
      }
      // 名称包含匹配
      else if (skill.name.toLowerCase().includes(queryLower)) {
        score = 60;
        matchReason = '名称包含匹配';
      }
      // 描述匹配
      else if (skill.description.toLowerCase().includes(queryLower)) {
        score = 40;
        matchReason = '描述匹配';
      }
      // 关键词匹配
      else if (
        skill.keywords?.some((k) => k.toLowerCase().includes(queryLower))
      ) {
        score = 30;
        matchReason = '关键词匹配';
      }
      // 分类匹配
      else if (skill.category?.toLowerCase().includes(queryLower)) {
        score = 20;
        matchReason = '分类匹配';
      }

      if (score > 0) {
        results.push({ skill, score, matchReason });
      }
    }

    // 按分数降序排序
    results.sort((a, b) => b.score - a.score);

    return results.slice(0, limit);
  }

  /**
   * 渲染 Skill 提示模板
   */
  renderPrompt(
    skill: Skill,
    params: Record<string, unknown>,
    context?: SkillContext
  ): SkillExecutionResult {
    try {
      // 验证必需参数
      if (skill.parameters) {
        for (const [name, param] of Object.entries(skill.parameters)) {
          if (param.required && !(name in params)) {
            return {
              success: false,
              error: `缺少必需参数: ${name}`,
            };
          }
        }
      }

      // 构建变量映射
      const variables: Record<string, string> = {};

      // 添加参数值
      for (const [key, value] of Object.entries(params)) {
        variables[key] = String(value);
      }

      // 添加上下文变量
      if (context?.variables) {
        for (const [key, value] of Object.entries(context.variables)) {
          if (!(key in variables)) {
            variables[key] = value;
          }
        }
      }

      // 添加默认值
      if (skill.parameters) {
        for (const [name, param] of Object.entries(skill.parameters)) {
          if (!(name in variables) && param.default !== undefined) {
            variables[name] = String(param.default);
          }
        }
      }

      // 渲染模板
      let prompt = skill.promptTemplate;

      // 替换 {{variable}} 格式的变量
      prompt = prompt.replace(/\{\{(\w+)\}\}/g, (match, varName) => {
        if (varName in variables) {
          return variables[varName];
        }
        // 保留未匹配的变量（可能是用户意图保留）
        return match;
      });

      return {
        success: true,
        prompt,
      };
    } catch (error) {
      return {
        success: false,
        error: `渲染 Skill 提示失败: ${error instanceof Error ? error.message : String(error)}`,
      };
    }
  }

  /**
   * 执行 Skill（渲染模板并返回提示）
   */
  execute(
    name: string,
    params: Record<string, unknown>,
    context?: SkillContext
  ): SkillExecutionResult {
    const skill = this.get(name);

    if (!skill) {
      return {
        success: false,
        error: `Skill 不存在: ${name}`,
      };
    }

    if (skill.enabled === false) {
      return {
        success: false,
        error: `Skill 已禁用: ${name}`,
      };
    }

    return this.renderPrompt(skill, params, context);
  }

  /**
   * 重新加载 Skills
   */
  async reload(workdir: string = process.cwd()): Promise<void> {
    this.skills.clear();
    this.initialized = false;
    await this.initialize(workdir);
  }

  /**
   * 获取 Skill 统计信息
   */
  getStats(): {
    total: number;
    enabled: number;
    bySource: Record<string, number>;
    byCategory: Record<string, number>;
  } {
    const skills = this.getAll();
    const enabled = this.getEnabled();

    const bySource: Record<string, number> = {};
    const byCategory: Record<string, number> = {};

    for (const skill of skills) {
      bySource[skill.source] = (bySource[skill.source] || 0) + 1;
      if (skill.category) {
        byCategory[skill.category] = (byCategory[skill.category] || 0) + 1;
      }
    }

    return {
      total: skills.length,
      enabled: enabled.length,
      bySource,
      byCategory,
    };
  }
}

/**
 * 全局 Skill 注册表实例
 */
let skillRegistryInstance: SkillRegistry | null = null;

/**
 * 获取全局 Skill 注册表
 */
export function getSkillRegistry(): SkillRegistry {
  if (!skillRegistryInstance) {
    skillRegistryInstance = new SkillRegistry();
  }
  return skillRegistryInstance;
}

/**
 * 重置全局 Skill 注册表（用于测试）
 */
export function resetSkillRegistry(): void {
  skillRegistryInstance = null;
}
