const fs = require("fs");
const path = require("path");
const { detectWorkspaceBoundary } = require("./workspace-boundary");

const GATEWAY_SKILL = "prismx-skill-gateway";

function matchedKeywords(text, taskType, matchKeywords) {
  if (!taskType?.keywords?.length) return [];
  return taskType.keywords.filter((kw) => matchKeywords(text, [kw]));
}

function filesToRead({ taskType, winner, rootDir }) {
  const files = [];
  const add = (rel) => {
    const norm = rel.replace(/\\/g, "/");
    if (!files.includes(norm)) files.push(norm);
  };

  add(`skills/${GATEWAY_SKILL}/SKILL.md`);

  if (taskType?.skills?.length) {
    for (const name of taskType.skills) {
      add(`skills/${name}/SKILL.md`);
    }
  }

  if (winner?.type === "skill" && winner.resource) {
    add(`skills/${winner.resource}/SKILL.md`);
  }

  const workflowName =
    winner?.type === "workflow"
      ? winner.resource
      : taskType?.workflow
        ? String(taskType.workflow).replace(/^\//, "")
        : null;

  if (workflowName && rootDir) {
    const wfPath = path.join(rootDir, "workflows", `${workflowName}.md`);
    if (fs.existsSync(wfPath)) add(`workflows/${workflowName}.md`);
  }

  return files.slice(0, 8);
}

function buildAlternatives(taskType, winner) {
  if (!taskType?.providers?.length) return [];
  return [...taskType.providers]
    .sort((a, b) => (b.confidence_base || 0) - (a.confidence_base || 0))
    .filter((p) => !(p.type === winner?.type && p.resource === winner?.resource))
    .slice(0, 4)
    .map((p) => ({
      resource: p.resource,
      type: p.type,
      confidence: p.confidence_base ?? null
    }));
}

function buildReasonSummary({ taskType, matched, winner, resolutionStatus }) {
  if (resolutionStatus === "not_installed" && winner?.resource) {
    return `Route selected ${winner.type}/${winner.resource} but it is not available on disk or is disabled.`;
  }
  if (taskType?.id) {
    const kw = matched.length ? matched.join(", ") : "task classification";
    return `Matched task_type "${taskType.id}" via keywords [${kw}]; winner ${winner?.type}/${winner?.resource}.`;
  }
  return `Default routing; winner ${winner?.type}/${winner?.resource}.`;
}

function extractFilesIntended(text) {
  const patterns = [
    /(?:^|[\s'"`])([\w.-]+(?:[\\/][\w.-]+)+\.(?:js|ts|tsx|jsx|mjs|cjs|json|md|php|py|go|rs|css|html|yaml|yml|toml|vue|svelte))/gi,
    /(?:^|[\s'"`])(src[\\/][^\s'"`,]+)/gi
  ];
  const found = [];
  for (const re of patterns) {
    for (const m of text.matchAll(re)) {
      const p = m[1].replace(/\\/g, "/");
      if (!found.includes(p) && !p.startsWith("http")) found.push(p);
    }
  }
  return found.slice(0, 8);
}

function buildExplanation({ text, routeResult, matrix, rootDir, matchKeywords, resolutionStatus, confirmDefaultOption }) {
  const taskType = routeResult.taskTypeResolved;
  const winner = routeResult.winner
    ? { type: routeResult.winner.type, resource: routeResult.winner.resource }
    : null;

  const matched = matchedKeywords(text, taskType, matchKeywords);
  const boundary = detectWorkspaceBoundary(text);
  const filesIntended =
    confirmDefaultOption === "plan_first" || boundary.violated ? extractFilesIntended(text) : [];

  const explanation = {
    task_type_id: taskType?.id || null,
    matched_keywords: matched,
    winner,
    files_to_read: filesToRead({ taskType, winner, rootDir }),
    reason_summary: buildReasonSummary({ taskType, matched, winner, resolutionStatus }),
    alternatives_considered: buildAlternatives(taskType, winner),
    resolver_order: matrix?.resolver_order || []
  };

  if (filesIntended.length) {
    explanation.files_intended = filesIntended;
  }
  if (boundary.violated || boundary.suspicious_paths.length) {
    explanation.workspace_boundary = {
      violated: boundary.violated,
      suspicious_paths: boundary.suspicious_paths,
      override_hint: boundary.override_hint
    };
  }

  return explanation;
}

function formatExplanationCard(explanation) {
  if (!explanation) return [];
  const lines = [];
  lines.push("");
  lines.push("## Explanation");
  lines.push("");
  lines.push(`Why: ${explanation.reason_summary}`);
  if (explanation.task_type_id) {
    lines.push(`Task type: ${explanation.task_type_id}`);
  }
  if (explanation.matched_keywords?.length) {
    lines.push(`Keywords: ${explanation.matched_keywords.join(", ")}`);
  }
  if (explanation.winner) {
    lines.push(`Winner: ${explanation.winner.type}/${explanation.winner.resource}`);
  }
  if (explanation.files_to_read?.length) {
    lines.push("Read:");
    for (const f of explanation.files_to_read) {
      lines.push(`  - ${f}`);
    }
  }
  if (explanation.files_intended?.length) {
    lines.push("Intended edits:");
    for (const f of explanation.files_intended) {
      lines.push(`  - ${f}`);
    }
  }
  if (explanation.workspace_boundary?.violated) {
    lines.push(`Boundary: refuse edits outside workspace — ${explanation.workspace_boundary.override_hint}`);
  }
  if (explanation.alternatives_considered?.length) {
    lines.push(
      `Alternatives: ${explanation.alternatives_considered.map((a) => `${a.type}/${a.resource}`).join(", ")}`
    );
  }
  return lines;
}

module.exports = { buildExplanation, formatExplanationCard, extractFilesIntended, GATEWAY_SKILL };
