const fs = require("fs");
const path = require("path");
const { runDoctor } = require("./doctor");
const { loadMatrix } = require("./route-engine");

const EXPECTED_AGENT_MARKERS = ["Execution Intent", "confirm", "parseIntent"];

function fileExists(rootDir, rel) {
  return fs.existsSync(path.join(rootDir, rel));
}

function readText(rootDir, rel) {
  const p = path.join(rootDir, rel);
  if (!fs.existsSync(p)) return null;
  return fs.readFileSync(p, "utf-8");
}

function runAudit(rootDir) {
  const doctor = runDoctor(rootDir);
  const matrix = loadMatrix(rootDir);
  const findings = [];
  const recommendations = [];

  const agentMd = readText(rootDir, "AGENT.md");
  const designMd = readText(rootDir, "design.md");
  const handoffMd = readText(rootDir, "HANDOFF.md");
  const manifestPath = path.join(rootDir, ".capint", "scaffold-manifest.json");

  if (!agentMd) {
    findings.push({ level: "warning", code: "missing_agent_md", message: "AGENT.md missing" });
    recommendations.push("capint init --preset minimal");
  } else {
    for (const marker of EXPECTED_AGENT_MARKERS) {
      if (!agentMd.includes(marker)) {
        findings.push({
          level: "info",
          code: "agent_contract_drift",
          message: `AGENT.md missing expected marker: ${marker}`
        });
      }
    }
  }

  if (!designMd) {
    findings.push({ level: "warning", code: "missing_design_md", message: "design.md missing" });
    recommendations.push("capint init --preset minimal");
  }

  if (fileExists(rootDir, ".capint/context.json") && !handoffMd) {
    findings.push({
      level: "info",
      code: "handoff_optional",
      message: "prismx-compatible context present but HANDOFF.md missing"
    });
    recommendations.push("capint scaffold --preset prismx-compatible");
  }

  if (fs.existsSync(manifestPath)) {
    try {
      const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
      const conflicts = (manifest.files || []).filter((f) => f.action === "conflict").length;
      if (conflicts > 0) {
        findings.push({
          level: "warning",
          code: "scaffold_conflicts",
          message: `${conflicts} scaffold conflict(s) unresolved — review *.capint.new.md files`
        });
      }
    } catch {
      findings.push({ level: "issue", code: "bad_scaffold_manifest", message: "scaffold-manifest.json invalid JSON" });
    }
  }

  if (matrix) {
    const withoutPattern = (matrix.task_types || []).filter((t) => !t.orchestration_pattern).map((t) => t.id);
    if (withoutPattern.length) {
      findings.push({
        level: "info",
        code: "matrix_patterns_incomplete",
        message: `task_types without orchestration_pattern: ${withoutPattern.join(", ")}`
      });
    }
  }

  for (const issue of doctor.issues) {
    findings.push({ level: "issue", code: "doctor", message: issue });
  }
  for (const w of doctor.warnings) {
    findings.push({ level: "warning", code: "doctor", message: w });
  }

  const issueCount = findings.filter((f) => f.level === "issue").length;
  const warningCount = findings.filter((f) => f.level === "warning").length;

  return {
    mode: "read_only",
    side_effects: false,
    pass: issueCount === 0,
    exit_code: issueCount === 0 ? 0 : 1,
    summary: { issues: issueCount, warnings: warningCount, info: findings.filter((f) => f.level === "info").length },
    findings,
    recommendations: [...new Set(recommendations)],
    doctor_pass: doctor.pass
  };
}

module.exports = { runAudit };
