import type { PilotDeckToolValidationIssue } from "../protocol/schema.js";

export type FormatValidationErrorOptions = {
  maxOutputTokens?: number;
  outputTruncated?: boolean;
};

/**
 * Format validation issues into a human-readable (and LLM-friendly) error
 * message. Formats missing, mistyped, and unexpected parameters so the
 * model sees exactly which parameters are missing, have the wrong type, or
 * are unexpected — enabling effective self-correction on the next turn.
 */
export function formatValidationError(
  toolName: string,
  issues: PilotDeckToolValidationIssue[],
  options?: FormatValidationErrorOptions,
): string {
  const errorParts: string[] = [];

  for (const issue of issues) {
    const param = issue.path.replace(/^\$\.?/, "");
    switch (issue.code) {
      case "required":
        errorParts.push(`The required parameter \`${param}\` is missing`);
        break;
      case "invalid_type":
        errorParts.push(`The parameter \`${param}\` has an invalid type: ${issue.message}`);
        break;
      case "unknown_property":
        errorParts.push(`An unexpected parameter \`${param}\` was provided`);
        break;
      case "invalid_enum":
        errorParts.push(`The parameter \`${param}\` has an invalid value: ${issue.message}`);
        break;
      default:
        errorParts.push(issue.message);
        break;
    }
  }

  if (errorParts.length === 0) {
    return `Tool ${toolName} input is invalid.`;
  }

  const label = errorParts.length > 1 ? "issues" : "issue";
  let message = `${toolName} failed due to the following ${label}:\n${errorParts.join("\n")}`;

  const FILE_TOOLS = new Set(["write_file", "edit_file", "edit_notebook", "bash"]);
  const hasRequiredMissing = issues.some((i) => i.code === "required");
  const tokenBudget = options?.maxOutputTokens;
  const tokenInfo = tokenBudget ? ` (current max_output_tokens: ${tokenBudget})` : "";

  if (hasRequiredMissing && FILE_TOOLS.has(toolName)) {
    if (options?.outputTruncated) {
      message += `\n\nThis was caused by your output being truncated (output token limit reached${tokenInfo}). `
        + "Keep each tool call's arguments well within the output token budget.";
    } else {
      message += "\n\nPlease ensure all required parameters are provided in the tool call.";
    }
  }

  if (
    toolName === "write_file" &&
    issues.some((i) => i.code === "required" && i.path.includes("content"))
    && options?.outputTruncated
  ) {
    message +=
      "\n\nHint: Please use an incremental, multi-step approach to write large files:\n"
      + "Step 1: Create the file with the first section using write_file (keep content short, ~50-100 lines max per call).\n"
      + "Step 2: Append subsequent sections using bash({command: \"cat <<'SECTION' >> /path/to/file\\n...next section...\\nSECTION\"}).\n"
      + "Step 3: Repeat Step 2 until the full file is written.\n"
      + "Important: Break the file into logical sections (imports, classes, functions, etc.) and write one section per step.";
  }

  return message;
}