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

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

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

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

      if (!exists) {
        return skills;
      }

      const entries = await fs.readdir(dir, { withFileTypes: true });

      for (const entry of entries) {
        if (entry.isFile()) {
          const ext = path.extname(entry.name).toLowerCase();
          if (['.yaml', '.yml', '.json', '.md'].includes(ext)) {
            const filePath = path.join(dir, entry.name);
            try {
              const skill = await this.loadFromFile(filePath, source);
              if (skill) {
                skills.push(skill);
              }
            } catch (error) {
              console.warn(`加载 Skill 文件失败: ${filePath}`, error);
            }
          }
        } else if (entry.isDirectory()) {
          // 递归加载子目录
          const subDir = path.join(dir, entry.name);
          const subSkills = await this.loadFromDirectory(subDir, source);
          skills.push(...subSkills);
        }
      }
    } catch (error) {
      console.warn(`读取 Skills 目录失败: ${dir}`, error);
    }

    return skills;
  }

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

    let skillData: SkillFile | null = null;

    if (ext === '.md') {
      // Markdown 格式：从 frontmatter 和内容中解析
      skillData = this.parseMarkdownSkill(content, filePath);
    } else if (ext === '.yaml' || ext === '.yml') {
      // YAML 格式
      skillData = yaml.parse(content) as SkillFile;
    } else if (ext === '.json') {
      // JSON 格式
      skillData = JSON.parse(content) as SkillFile;
    }

    if (!skillData?.skill) {
      return null;
    }

    // 验证必需字段
    const { skill } = skillData;
    if (!skill.name || !skill.promptTemplate) {
      console.warn(`Skill 文件缺少必需字段: ${filePath}`);
      return null;
    }

    return {
      ...skill,
      source,
      sourcePath: filePath,
      enabled: skill.enabled ?? true,
    };
  }

  /**
   * 解析 Markdown 格式的 Skill
   *
   * 格式示例：
   * ```markdown
   * ---
   * name: code-review
   * description: 代码审查
   * parameters:
   *   focus:
   *     type: string
   *     description: 审查重点
   * ---
   *
   * # 代码审查
   *
   * 请审查以下代码，重点关注 {{focus}}：
   *
   * {{code}}
   * ```
   */
  private parseMarkdownSkill(
    content: string,
    filePath: string
  ): SkillFile | null {
    // 解析 frontmatter
    const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);

    if (!frontmatterMatch) {
      // 没有 frontmatter，使用文件名作为 name，整个内容作为 promptTemplate
      const name = path.basename(filePath, path.extname(filePath));
      return {
        skill: {
          name,
          description: `Skill: ${name}`,
          promptTemplate: content.trim(),
        },
      };
    }

    const [, frontmatterStr, bodyContent] = frontmatterMatch;

    try {
      const frontmatter = yaml.parse(frontmatterStr) as Partial<Skill>;

      // 如果 frontmatter 中没有 promptTemplate，使用 body 内容
      const promptTemplate = frontmatter.promptTemplate || bodyContent.trim();

      // 从文件名获取默认 name
      const defaultName = path.basename(filePath, path.extname(filePath));

      return {
        skill: {
          name: frontmatter.name || defaultName,
          displayName: frontmatter.displayName,
          description: frontmatter.description || `Skill: ${defaultName}`,
          category: frontmatter.category,
          promptTemplate,
          parameters: frontmatter.parameters,
          keywords: frontmatter.keywords,
          version: frontmatter.version,
          author: frontmatter.author,
          enabled: frontmatter.enabled,
        },
      };
    } catch (error) {
      console.warn(`解析 Skill frontmatter 失败: ${filePath}`, error);
      return null;
    }
  }

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

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

/**
 * 全局 Skill 加载器实例
 */
export const skillLoader = new SkillLoader();
