import chalk from 'chalk';
import fs from 'node:fs/promises';
import path from 'node:path';
import { findSkill, parseVersions } from '../utils/versions.js';
import { getSkillSrcDir } from '../utils/paths.js';
import { loadConfig } from '../utils/config.js';

async function downloadSingle(skillName, outputDir) {
  const skill = await findSkill(skillName);
  if (!skill) {
    console.error(chalk.red(`Skill "${skillName}" not found.`));
    console.error(chalk.gray('Run "sophhub list" to see all available skills.'));
    process.exit(1);
  }

  const destDir = path.join(outputDir, skillName);

  try {
    await fs.access(destDir);
    await fs.rm(destDir, { recursive: true, force: true });
  } catch {
    // dest does not exist
  }

  const srcDir = getSkillSrcDir(skillName);
  try {
    await fs.access(srcDir);
  } catch {
    throw new Error(`Skill src directory not found in package: ${srcDir}`);
  }

  await fs.cp(srcDir, destDir, { recursive: true });

  console.log(chalk.green(`  ✓ ${skill.name}`) + chalk.gray(` (${skill.version}) → ${destDir}`));
}

export function registerDownloadCommand(program) {
  program
    .command('download')
    .description('Download skill(s) to local directory')
    .argument('[skill-name]', 'Name of the skill to download')
    .option('-o, --output <dir>', 'Target directory (default: current directory)')
    .option('-t, --type <type>', 'Download all skills of the given type (builtin/store)')
    .action(async (skillName, opts) => {
      try {
        const config = await loadConfig();
        const outputDir = path.resolve(opts.output || config.defaultOutput || '.');
        await fs.mkdir(outputDir, { recursive: true });

        if (opts.type) {
          const typeFilter = opts.type.toLowerCase();

          const skills = await parseVersions();
          const filtered = skills.filter((s) => s.types.includes(typeFilter));

          if (filtered.length === 0) {
            console.log(chalk.yellow(`\n  No skills found for type "${typeFilter}".\n`));
            return;
          }

          console.log();
          console.log(chalk.cyan(`  Downloading all ${typeFilter} skills (${filtered.length})...`));
          console.log();

          let success = 0;
          for (const skill of filtered) {
            try {
              await downloadSingle(skill.name, outputDir);
              success++;
            } catch (err) {
              console.error(chalk.red(`  ✗ ${skill.name}: ${err.message}`));
            }
          }

          console.log();
          console.log(chalk.green(`  Done. ${success}/${filtered.length} skills downloaded to ${outputDir}`));
          console.log();
          return;
        }

        if (!skillName) {
          console.error(chalk.red('\n  Please specify a skill name or use --type to batch download.\n'));
          console.error(chalk.gray('  Examples:'));
          console.error(chalk.gray('    sophhub download <skill-name>'));
          console.error(chalk.gray('    sophhub download --type builtin'));
          console.error(chalk.gray('    sophhub download --type store\n'));
          process.exit(1);
        }

        console.log();
        console.log(chalk.gray(`  Downloading ${skillName}...`));

        await downloadSingle(skillName, outputDir);

        console.log();
      } catch (err) {
        console.error(chalk.red(`\n  Failed to download: ${err.message}\n`));
        process.exit(1);
      }
    });
}
