/**
 * Command 加载器
 *
 * 负责从文件系统加载 Markdown 格式的 Command 定义。
 * 支持从以下位置加载：
 * 1. 内置 Commands（代码中定义）
 * 2. 用户 Commands（~/.config/ai-terminal/commands/）
 * 3. 项目 Commands（./.ai-terminal/commands/）
 */

import * as fs from 'fs/promises';
import * as path from 'path';
import * as yaml from 'yaml';
import type { Command, CommandFrontmatter } from './types.js';

/**
 * Command 加载器
 */
export class CommandLoader {
  /**
   * 从目录加载所有 Commands
   */
  async loadFromDirectory(
    dir: string,
    source: 'user' | 'project'
  ): Promise<Command[]> {
    const commands: Command[] = [];

    try {
      const exists = await fs
        .access(dir)
        .then(() => true)
        .catch(() => false);

      if (!exists) {
        return commands;
      }

      await this.scanDirectory(dir, dir, source, commands);
    } catch (error) {
      console.warn(`读取 Commands 目录失败: ${dir}`, error);
    }

    return commands;
  }

  /**
   * 递归扫描目录
   */
  private async scanDirectory(
    baseDir: string,
    currentDir: string,
    source: 'user' | 'project',
    commands: Command[]
  ): Promise<void> {
    const entries = await fs.readdir(currentDir, { withFileTypes: true });

    for (const entry of entries) {
      const fullPath = path.join(currentDir, entry.name);

      if (entry.isFile() && entry.name.endsWith('.md')) {
        try {
          const command = await this.loadFromFile(fullPath, baseDir, source);
          if (command) {
            commands.push(command);
          }
        } catch (error) {
          console.warn(`加载 Command 文件失败: ${fullPath}`, error);
        }
      } else if (entry.isDirectory() && !entry.name.startsWith('.')) {
        // 递归加载子目录（支持嵌套路径如 deploy/staging）
        await this.scanDirectory(baseDir, fullPath, source, commands);
      }
    }
  }

  /**
   * 从单个 Markdown 文件加载 Command
   */
  async loadFromFile(
    filePath: string,
    baseDir: string,
    source: 'user' | 'project'
  ): Promise<Command | null> {
    const content = await fs.readFile(filePath, 'utf-8');

    // 从文件路径推断命令名称
    // baseDir/deploy/staging.md → deploy/staging
    const relativePath = path.relative(baseDir, filePath);
    const name = relativePath.slice(0, -3); // 移除 .md 后缀

    return this.parseMarkdownCommand(content, name, source, filePath);
  }

  /**
   * 解析 Markdown 格式的 Command
   *
   * 格式示例：
   * ```markdown
   * ---
   * description: 代码审查
   * agent: explore
   * model: sonnet
   * subtask: true
   * ---
   *
   * You are a code reviewer...
   *
   * Input: $ARGUMENTS
   * ```
   */
  parseMarkdownCommand(
    content: string,
    name: string,
    source: 'user' | 'project' | 'builtin',
    sourcePath?: string
  ): Command | null {
    // 解析 frontmatter
    const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);

    let frontmatter: CommandFrontmatter = {};
    let template: string;

    if (frontmatterMatch) {
      const [, frontmatterStr, bodyContent] = frontmatterMatch;
      try {
        frontmatter = yaml.parse(frontmatterStr) as CommandFrontmatter;
      } catch (error) {
        console.warn(`解析 Command frontmatter 失败: ${sourcePath}`, error);
      }
      template = bodyContent.trim();
    } else {
      // 没有 frontmatter，整个内容作为模板
      template = content.trim();
    }

    if (!template) {
      return null;
    }

    return {
      name,
      description: frontmatter.description,
      template,
      agent: frontmatter.agent,
      model: frontmatter.model,
      subtask: frontmatter.subtask,
      source,
      sourcePath,
    };
  }

  /**
   * 获取用户 Commands 目录
   */
  getUserCommandsDir(): string {
    const home = process.env.HOME || process.env.USERPROFILE || '';
    return path.join(home, '.config', 'ai-terminal', 'commands');
  }

  /**
   * 获取项目 Commands 目录
   */
  getProjectCommandsDir(workdir: string = process.cwd()): string {
    return path.join(workdir, '.ai-terminal', 'commands');
  }
}

/**
 * 全局 Command 加载器实例
 */
export const commandLoader = new CommandLoader();
