const fs = require("fs");
const path = require("path");
const { loadMatrix } = require("./route-engine");
const { validateExecutionIntent } = require("./contract");
const { loadDisabledSkills } = require("./disabled-skills");

function loadRegistry(rootDir) {
  const p = path.join(rootDir, "registry.json");
  if (!fs.existsSync(p)) return null;
  try {
    return JSON.parse(fs.readFileSync(p, "utf-8"));
  } catch (e) {
    return { parseError: e.message };
  }
}

function skillsOnDisk(rootDir) {
  const skillsDir = path.join(rootDir, "skills");
  if (!fs.existsSync(skillsDir)) return [];
  return fs
    .readdirSync(skillsDir)
    .filter((n) => fs.existsSync(path.join(skillsDir, n, "SKILL.md")));
}

function runDoctor(rootDir) {
  const issues = [];
  const warnings = [];
  const ok = [];

  const matrix = loadMatrix(rootDir);
  if (!matrix) issues.push("skill-routing-matrix.json missing or invalid");
  else ok.push(`matrix schema_version ${matrix.schema_version}`);

  const registry = loadRegistry(rootDir);
  if (!registry) issues.push("registry.json missing or invalid");
  else if (registry.parseError) issues.push(`registry.json parse error: ${registry.parseError}`);
  else ok.push("registry.json valid");

  if (matrix && registry && !registry.parseError) {
    const disk = new Set(skillsOnDisk(rootDir));
    const allReg = new Set([
      ...(registry.core || []),
      ...(registry.recommended || []),
      ...(registry.optional || []),
      ...(registry.project_added || [])
    ]);
    for (const name of registry.core || []) {
      if (!disk.has(name)) warnings.push(`core skill missing on disk: ${name}`);
    }
    for (const tt of matrix.task_types || []) {
      for (const s of tt.skills || []) {
        if (!allReg.has(s) && !disk.has(s)) {
          warnings.push(`task_type ${tt.id} references skill not in registry: ${s}`);
        }
      }
    }
    const ids = matrix.task_types.map((t) => t.id);
    if (new Set(ids).size !== ids.length) issues.push("duplicate task_type ids in matrix");
  }

  if (!fs.existsSync(path.join(rootDir, "AGENT.md"))) {
    warnings.push("AGENT.md missing — run capint init");
  }

  const disabledOverlay = loadDisabledSkills(rootDir);
  if (disabledOverlay.parseError) {
    warnings.push(`.capint/disabled-skills.json invalid — fix JSON or delete file`);
  }
  if (registry && !registry.parseError && disabledOverlay.disabled?.length) {
    for (const name of disabledOverlay.disabled) {
      if ((registry.core || []).includes(name)) {
        warnings.push(`core skill disabled: ${name} — capint skill enable ${name}`);
      }
    }
  }

  if (registry && !registry.parseError && registry.project_added?.length) {
    const disk = new Set(skillsOnDisk(rootDir));
    for (const name of registry.project_added) {
      if (!disk.has(name)) {
        warnings.push(`pinned skill missing on disk: ${name}`);
      }
    }
  }

  const policy = matrix?.provider_activation_policy;
  if (policy) {
    ok.push("provider_activation_policy present (default off)");
  } else {
    warnings.push("provider_activation_policy missing — memory/graph always local fallback");
  }

  const pass = issues.length === 0;
  let hint = pass ? "No auto-fix performed (by design)." : "Resolve issues manually; doctor does not mutate files.";
  if (!pass) {
    if (issues.some((i) => i.includes("matrix") || i.includes("registry"))) {
      hint = "Try: capint recover --list then capint recover --latest --apply";
    }
  } else if (warnings.some((w) => w.includes("disabled"))) {
    hint = "Re-enable core skills: capint skill enable <name>";
  }

  return {
    pass,
    exit_code: pass ? 0 : 1,
    issues,
    warnings,
    ok,
    auto_fix: false,
    hint
  };
}

function runStatus(rootDir) {
  const matrix = loadMatrix(rootDir);
  const registry = loadRegistry(rootDir);
  const doctor = runDoctor(rootDir);
  const contextPath = path.join(rootDir, ".capint", "context.json");
  let context = null;
  if (fs.existsSync(contextPath)) {
    try {
      context = JSON.parse(fs.readFileSync(contextPath, "utf-8"));
    } catch {
      context = { error: "invalid json" };
    }
  }

  return {
    capint_package: require(path.join(__dirname, "..", "..", "package.json")).version,
    matrix_version: matrix?.schema_version || null,
    matrix_updated: matrix?.updated_at || null,
    registry_schema: registry?.schema_version || null,
    skills_on_disk: skillsOnDisk(rootDir).length,
    core_skills: (registry?.core || []).length,
    doctor_pass: doctor.pass,
    provider_defaults: {
      memory: matrix?.provider_activation_policy?.memory_providers?.default || "off",
      graph: matrix?.provider_activation_policy?.graph_providers?.default || "off"
    },
    context,
    warnings_count: doctor.warnings.length,
    issues_count: doctor.issues.length
  };
}

module.exports = { runDoctor, runStatus, skillsOnDisk, loadRegistry };
