const fs = require("fs");
const path = require("path");

const BACKUP_DIR = ".capint/backups";
const RESTORABLE = [
  { prefix: "skill-routing-matrix.", target: "skill-routing-matrix.json" },
  { prefix: "registry.", target: "registry.json" }
];

function backupDir(rootDir) {
  return path.join(rootDir, BACKUP_DIR);
}

function listBackups(rootDir) {
  const dir = backupDir(rootDir);
  if (!fs.existsSync(dir)) {
    return { backups: [], groups: [] };
  }

  const entries = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
  const byStamp = new Map();

  for (const file of entries) {
    for (const spec of RESTORABLE) {
      if (!file.startsWith(spec.prefix)) continue;
      const stamp = file.slice(spec.prefix.length, -".json".length);
      if (!byStamp.has(stamp)) {
        byStamp.set(stamp, { stamp, files: [], mtime: 0 });
      }
      const abs = path.join(dir, file);
      const stat = fs.statSync(abs);
      const group = byStamp.get(stamp);
      group.files.push({ file, target: spec.target, path: abs, mtime: stat.mtimeMs });
      group.mtime = Math.max(group.mtime, stat.mtimeMs);
    }
  }

  const groups = [...byStamp.values()]
    .map((g) => ({
      stamp: g.stamp,
      mtime: g.mtime,
      files: g.files.map((f) => ({ file: f.file, target: f.target }))
    }))
    .sort((a, b) => b.mtime - a.mtime);

  return { backups: entries.sort(), groups };
}

function pickLatestGroup(groups) {
  return groups[0] || null;
}

function planRecover(rootDir, { stamp = null, latest = false } = {}) {
  const { groups } = listBackups(rootDir);
  if (!groups.length) {
    return { error: "No backups found — run capint upgrade --apply first", groups: [] };
  }

  let group = null;
  if (latest || !stamp) {
    group = pickLatestGroup(groups);
  } else {
    group = groups.find((g) => g.stamp === stamp || g.stamp.includes(stamp));
  }

  if (!group) {
    return { error: `No backup group matching stamp: ${stamp}`, groups };
  }

  const actions = [];
  for (const f of group.files) {
    const src = path.join(backupDir(rootDir), f.file);
    const dest = path.join(rootDir, f.target);
    actions.push({ from: src, to: dest, target: f.target, exists: fs.existsSync(src) });
  }

  return { ok: true, stamp: group.stamp, actions, groups };
}

function applyRecover(rootDir, plan) {
  if (plan.error) return plan;

  const restored = [];
  for (const action of plan.actions) {
    if (!action.exists) continue;
    fs.copyFileSync(action.from, action.to);
    restored.push(action.target);
  }

  return { ok: true, stamp: plan.stamp, restored, dry_run: false };
}

module.exports = { listBackups, planRecover, applyRecover, BACKUP_DIR };
