const EXECUTION_INTENT_KEYS = [
  "intent",
  "capability",
  "resolution",
  "memory",
  "plan",
  "confirm",
  "confirm_question",
  "confirm_options",
  "confirm_default_option",
  "fallback"
];

const OPTIONAL_KEYS = [
  "verification_required",
  "verification_hints",
  "verification_profile",
  "route_explain",
  "explanation",
  "provider_activation",
  "context_pack",
  "orchestration",
  "resolution_status",
  "resolution_hint",
  "workspace_boundary",
  "overlay_error",
  "local_adapters"
];

function validateExplanationShape(explanation, errors) {
  if (explanation == null) return;
  if (typeof explanation !== "object") {
    errors.push("explanation must be object");
    return;
  }
  if (typeof explanation.reason_summary !== "string") {
    errors.push("explanation.reason_summary must be string");
  }
  if (!Array.isArray(explanation.files_to_read)) {
    errors.push("explanation.files_to_read must be array");
  }
  if (explanation.files_intended != null && !Array.isArray(explanation.files_intended)) {
    errors.push("explanation.files_intended must be array when present");
  }
  if (explanation.workspace_boundary != null) {
    const wb = explanation.workspace_boundary;
    if (typeof wb.violated !== "boolean") {
      errors.push("explanation.workspace_boundary.violated must be boolean");
    }
  }
}

function validateWorkspaceBoundary(wb, errors) {
  if (wb == null) return;
  if (typeof wb !== "object") {
    errors.push("workspace_boundary must be object");
    return;
  }
  if (typeof wb.violated !== "boolean") errors.push("workspace_boundary.violated must be boolean");
  if (!Array.isArray(wb.suspicious_paths)) {
    errors.push("workspace_boundary.suspicious_paths must be array");
  }
}

function validateExecutionIntent(ei) {
  const errors = [];
  if (!ei || typeof ei !== "object") {
    return { valid: false, errors: ["execution_intent must be an object"] };
  }
  for (const key of EXECUTION_INTENT_KEYS) {
    if (!(key in ei)) errors.push(`missing required key: ${key}`);
  }
  if (typeof ei.intent !== "string") errors.push("intent must be string");
  if (typeof ei.capability !== "string") errors.push("capability must be string");
  if (typeof ei.resolution !== "string") errors.push("resolution must be string");
  if (!["none", "optional", "required"].includes(ei.memory)) {
    errors.push("memory must be none|optional|required");
  }
  if (!["auto", "confirm", "override"].includes(ei.plan)) {
    errors.push("plan must be auto|confirm|override");
  }
  if (ei.confirm && typeof ei.confirm !== "object") errors.push("confirm must be object");
  if (ei.workspace_boundary?.violated && ei.confirm?.mode !== "blocked") {
    errors.push("workspace boundary violation requires confirm.mode blocked");
  }
  if (Array.isArray(ei.confirm_options)) {
    for (const o of ei.confirm_options) {
      if (!o.id || !o.label) errors.push("confirm_options entries need id and label");
    }
  }
  if (typeof ei.verification_required === "boolean" && ei.verification_required) {
    if (!Array.isArray(ei.verification_hints) || ei.verification_hints.length === 0) {
      errors.push("verification_required=true requires verification_hints array");
    }
  }
  validateExplanationShape(ei.explanation, errors);
  validateWorkspaceBoundary(ei.workspace_boundary, errors);
  if (ei.orchestration != null && typeof ei.orchestration !== "object") {
    errors.push("orchestration must be object when present");
  }
  return { valid: errors.length === 0, errors };
}

function stripVolatile(result) {
  const copy = JSON.parse(JSON.stringify(result));
  delete copy.installed_count;
  delete copy.events;
  delete copy.event_log;
  if (copy.execution_intent?.route_explain) {
    copy.execution_intent.route_explain = { ...copy.execution_intent.route_explain, ts: "<stripped>" };
  }
  return copy;
}

module.exports = {
  EXECUTION_INTENT_KEYS,
  OPTIONAL_KEYS,
  validateExecutionIntent,
  stripVolatile
};
