#!/usr/bin/env node
/**
 * setup.js - Downloads/updates the JAE Image Skill reference library.
 *
 * Fully dynamic: reads manifest.json first to discover all categories.
 * New/renamed/removed categories are handled automatically — no hardcoding.
 *
 * Usage:
 *   node scripts/setup.js           # Download missing files only
 *   node scripts/setup.js --force   # Force re-download all references
 *   node scripts/setup.js --check   # Auto-update if stale (> 24h)
 *
 * Override source if needed:
 *   JAE_IMAGE_SKILL_BASE_URL=https://example.com/references node scripts/setup.js --force
 */

import { existsSync, mkdirSync, statSync, writeFileSync, readFileSync, readdirSync, unlinkSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const refsDir = join(__dirname, '..', 'references');
const stampFile = join(refsDir, '.last-updated');

const BASE_URL = (process.env.JAE_IMAGE_SKILL_BASE_URL || 'https://jaeswift.xyz/skills/JAE-image-skill/references').replace(/\/$/, '');
const STALE_HOURS = Number(process.env.JAE_IMAGE_SKILL_STALE_HOURS || 24);

function isStale() {
  if (!existsSync(stampFile)) return true;
  const ts = parseInt(readFileSync(stampFile, 'utf8').trim(), 10);
  return (Date.now() - ts) / 1000 / 3600 > STALE_HOURS;
}

async function fetchText(url) {
  if (typeof fetch !== 'function') {
    throw new Error('This installer requires Node.js 18+ with global fetch. Node 20+ is recommended.');
  }
  const res = await fetch(url);
  if (!res.ok) throw new Error(`HTTP ${res.status} — ${url}`);
  return res.text();
}

async function setup() {
  const args = process.argv.slice(2);
  const forceMode = args.includes('--force');
  const checkMode = args.includes('--check');

  if (checkMode && !isStale()) {
    return;
  }

  if (!existsSync(refsDir)) mkdirSync(refsDir, { recursive: true });

  const label = forceMode ? 'Updating' : 'Downloading';
  console.log(`[setup] ${label} JAE Image Skill reference library from ${BASE_URL} ...`);

  let categories;
  try {
    const manifestText = await fetchText(`${BASE_URL}/manifest.json`);
    const manifest = JSON.parse(manifestText);
    categories = manifest.categories;
    if (!Array.isArray(categories) || categories.length === 0) throw new Error('manifest has no categories');
    writeFileSync(join(refsDir, 'manifest.json'), manifestText, 'utf8');
    console.log(`  manifest: ${categories.length} categories, ${manifest.totalPrompts} prompts total`);
  } catch (err) {
    console.warn(`[setup] Could not fetch manifest: ${err.message}`);
    console.warn('[setup] Falling back to existing local manifest...');
    const localManifest = join(refsDir, 'manifest.json');
    if (!existsSync(localManifest)) {
      console.error('[setup] No manifest available. Install from the bundled repo/archive or retry with --force.');
      process.exit(0);
    }
    categories = JSON.parse(readFileSync(localManifest, 'utf8')).categories;
  }

  const validFiles = new Set([...categories.map(c => c.file), 'manifest.json', '.last-updated', '.gitkeep']);
  if (forceMode && existsSync(refsDir)) {
    for (const f of readdirSync(refsDir)) {
      if (!validFiles.has(f)) {
        unlinkSync(join(refsDir, f));
        console.log(`  removed stale: ${f}`);
      }
    }
  }

  let downloaded = 0, skipped = 0, failed = 0;
  for (const cat of categories) {
    const dest = join(refsDir, cat.file);
    if (!forceMode && existsSync(dest) && statSync(dest).size > 100) {
      skipped++;
      continue;
    }
    process.stdout.write(`  → ${cat.file} (${cat.title}, ${cat.count} prompts) ... `);
    try {
      const text = await fetchText(`${BASE_URL}/${cat.file}`);
      JSON.parse(text);
      writeFileSync(dest, text, 'utf8');
      console.log('✓');
      downloaded++;
    } catch (err) {
      console.log(`✗ (${err.message})`);
      failed++;
    }
  }

  if (failed === 0) writeFileSync(stampFile, String(Date.now()), 'utf8');

  if (downloaded > 0) {
    console.log(`[setup] Done! ${downloaded} file(s) ${forceMode ? 'updated' : 'downloaded'}. JAE Image Skill is ready.`);
  } else if (skipped === categories.length) {
    console.log('[setup] All references up to date. Use --force to refresh.');
  }
  if (failed > 0) console.warn(`[setup] ${failed} file(s) failed. Run again to retry.`);
}

setup().catch(err => {
  console.warn('[setup] Warning (non-fatal):', err.message);
  process.exit(0);
});
