import { readdirSync, readFileSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { parse as parseYaml } from 'yaml';
import { RECOMMENDED_SKILLS } from '../constants.js';

export interface SkillEntry {
  name: string;
  description: string;
  version?: string;
  recommended: boolean;
  source: 'canonical' | 'local';
}

export function loadSkillsCatalog(mosaicHome: string): SkillEntry[] {
  const skills: SkillEntry[] = [];

  // Load canonical skills
  const canonicalDir = join(mosaicHome, 'skills');
  if (existsSync(canonicalDir)) {
    skills.push(...loadSkillsFromDir(canonicalDir, 'canonical'));
  }

  // Fallback to source repo
  const sourceDir = join(mosaicHome, 'sources', 'agent-skills', 'skills');
  if (skills.length === 0 && existsSync(sourceDir)) {
    skills.push(...loadSkillsFromDir(sourceDir, 'canonical'));
  }

  // Load local skills
  const localDir = join(mosaicHome, 'skills-local');
  if (existsSync(localDir)) {
    skills.push(...loadSkillsFromDir(localDir, 'local'));
  }

  return skills.sort((a, b) => a.name.localeCompare(b.name));
}

function loadSkillsFromDir(dir: string, source: 'canonical' | 'local'): SkillEntry[] {
  const entries: SkillEntry[] = [];

  let dirEntries;
  try {
    dirEntries = readdirSync(dir, { withFileTypes: true });
  } catch {
    return entries;
  }

  for (const entry of dirEntries) {
    if (!entry.isDirectory() || entry.name.startsWith('.')) continue;

    const skillMdPath = join(dir, entry.name, 'SKILL.md');
    if (!existsSync(skillMdPath)) continue;

    try {
      const content = readFileSync(skillMdPath, 'utf-8');
      const frontmatter = parseFrontmatter(content);

      entries.push({
        name: (frontmatter['name'] as string | undefined) ?? entry.name,
        description: (frontmatter['description'] as string | undefined) ?? '',
        version: frontmatter['version'] as string | undefined,
        recommended: RECOMMENDED_SKILLS.has(entry.name),
        source,
      });
    } catch {
      // Skip malformed skills
      entries.push({
        name: entry.name,
        description: '',
        recommended: RECOMMENDED_SKILLS.has(entry.name),
        source,
      });
    }
  }

  return entries;
}

function parseFrontmatter(content: string): Record<string, unknown> {
  const match = content.match(/^---\n([\s\S]*?)\n---/);
  if (!match?.[1]) return {};

  try {
    return (parseYaml(match[1]) as Record<string, unknown>) ?? {};
  } catch {
    // Fallback: simple key-value parsing
    const result: Record<string, string> = {};
    for (const line of match[1].split('\n')) {
      const kv = line.match(/^(\w[\w-]*)\s*:\s*(.+)/);
      if (kv?.[1] !== undefined && kv[2] !== undefined) {
        result[kv[1]] = kv[2].replace(/^['"]|['"]$/g, '');
      }
    }
    return result;
  }
}
