import fs from "node:fs";
import path from "node:path";
import { ProgressInput, ProgressEntry, InputSchemaMap, EventType } from "../../../progress/schema";
import { type CommandResult, success, failure } from "../../lib/command-result";
import { getGitContext } from "./git-context";

function formatValidationErrors(
  parsed: unknown,
  fallbackIssues: { path: PropertyKey[]; message: string }[],
): string {
  const validEvents = EventType.options;
  const input = parsed as Record<string, unknown> | null;
  const event = input?.event;

  if (typeof event === "string" && event in InputSchemaMap) {
    const variantResult = InputSchemaMap[event].safeParse(parsed);
    if (!variantResult.success) {
      const details = variantResult.error.issues
        .map((i) => {
          const path = i.path.join(".");
          return path ? `${path}: ${i.message}` : i.message;
        })
        .join(", ");
      return `Invalid progress input for event "${event}": ${details}`;
    }
  }

  if (typeof event === "string" && !(event in InputSchemaMap)) {
    return `Unknown event type "${event}". Valid events: ${validEvents.join(", ")}`;
  }

  const details = fallbackIssues
    .map((i) => {
      const path = i.path.join(".");
      return path ? `${path}: ${i.message}` : i.message;
    })
    .join(", ");
  return `Invalid progress input: ${details}. Valid events: ${validEvents.join(", ")}`;
}

export function runProgressLog(jsonInput: string, dryRun: boolean, cwd: string): CommandResult {
  let parsed: unknown;
  try {
    parsed = JSON.parse(jsonInput);
  } catch {
    return failure("Invalid JSON input");
  }

  const inputResult = ProgressInput.safeParse(parsed);
  if (!inputResult.success) {
    return failure(formatValidationErrors(parsed, inputResult.error.issues));
  }

  const enriched = {
    ...inputResult.data,
    timestamp: new Date().toISOString(),
    git: getGitContext(cwd),
  };

  const entryResult = ProgressEntry.safeParse(enriched);
  if (!entryResult.success) {
    const issues = entryResult.error.issues
      .map((i) => `${i.path.join(".")}: ${i.message}`)
      .join(", ");
    return failure(`Invalid progress entry after enrichment: ${issues}`);
  }

  const line = JSON.stringify(entryResult.data);
  console.log(line);

  if (dryRun) {
    return success();
  }

  const erpKitDir = path.join(cwd, ".erp-kit");
  fs.mkdirSync(erpKitDir, { recursive: true });
  fs.appendFileSync(path.join(erpKitDir, "progress.jsonl"), line + "\n", "utf-8");

  return success();
}
