/**
 * Command 注册表
 *
 * 管理所有可用的 Commands，支持：
 * - 注册/注销 Commands
 * - 按名称查询
 * - 搜索 Commands
 */

import type { Command, CommandSearchResult } from './types.js';
import { commandLoader } from './loader.js';
import { builtinCommands } from './builtin/index.js';

/**
 * Command 注册表
 */
export class CommandRegistry {
  private commands = new Map<string, Command>();
  private initialized = false;

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

    // 1. 注册内置 Commands
    for (const command of builtinCommands) {
      this.register(command);
    }

    // 2. 加载用户 Commands
    const userDir = commandLoader.getUserCommandsDir();
    const userCommands = await commandLoader.loadFromDirectory(userDir, 'user');
    for (const command of userCommands) {
      this.register(command);
    }

    // 3. 加载项目 Commands
    const projectDir = commandLoader.getProjectCommandsDir(workdir);
    const projectCommands = await commandLoader.loadFromDirectory(
      projectDir,
      'project'
    );
    for (const command of projectCommands) {
      this.register(command);
    }

    this.initialized = true;
  }

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

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

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

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

  /**
   * 获取所有 Commands
   */
  getAll(): Command[] {
    return Array.from(this.commands.values());
  }

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

    for (const command of this.commands.values()) {
      let score = 0;

      // 精确名称匹配
      if (command.name.toLowerCase() === queryLower) {
        score = 100;
      }
      // 名称前缀匹配
      else if (command.name.toLowerCase().startsWith(queryLower)) {
        score = 80;
      }
      // 名称包含匹配
      else if (command.name.toLowerCase().includes(queryLower)) {
        score = 60;
      }
      // 描述匹配
      else if (command.description?.toLowerCase().includes(queryLower)) {
        score = 40;
      }

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

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

    return results.slice(0, limit);
  }

  /**
   * 列出所有 Commands（用于帮助显示）
   */
  list(): Array<{ name: string; description?: string; source: string }> {
    return this.getAll()
      .map((cmd) => ({
        name: cmd.name,
        description: cmd.description,
        source: cmd.source,
      }))
      .sort((a, b) => a.name.localeCompare(b.name));
  }

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

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

    for (const command of commands) {
      bySource[command.source] = (bySource[command.source] || 0) + 1;
    }

    return {
      total: commands.length,
      bySource,
    };
  }
}

/**
 * 全局 Command 注册表实例
 */
let commandRegistryInstance: CommandRegistry | null = null;

/**
 * 获取全局 Command 注册表
 */
export function getCommandRegistry(): CommandRegistry {
  if (!commandRegistryInstance) {
    commandRegistryInstance = new CommandRegistry();
  }
  return commandRegistryInstance;
}

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