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

function findErpKitRoot(cwd: string): string {
  let dir = path.resolve(cwd);
  const { root } = path.parse(dir);
  while (dir !== root) {
    if (fs.existsSync(path.join(dir, ".erp-kit"))) {
      return dir;
    }
    dir = path.dirname(dir);
  }
  return cwd;
}

function formatValidationErrors(parsed: unknown, fallbackError: z.ZodError): 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) {
      return `Invalid progress input for event "${event}":\n${z.prettifyError(variantResult.error)}`;
    }
  }

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

  return `Invalid progress input:\n${z.prettifyError(fallbackError)}\n\nValid events: ${validEvents.join(", ")}`;
}

export function runAppProgressLog(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));
  }

  // Progress entries require git context, so fail clearly outside a git repo
  let git: GitContext;
  try {
    git = getGitContext(cwd);
  } catch {
    return failure("Failed to resolve git context: not a git repository, or git is not installed");
  }

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

  const entryResult = ProgressEntry.safeParse(enriched);
  if (!entryResult.success) {
    return failure(
      `Invalid progress entry after enrichment:\n${z.prettifyError(entryResult.error)}`,
    );
  }

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

  if (dryRun) {
    return success();
  }

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

  return success();
}
