import path from "path";
import {
  buildCompactRunSummaryLines,
  buildDebugRunSummaryLines,
  formatDuration,
} from "../../runner/formatting.mjs";

export function createRunReporter({ outputMode = "compact", stdout = process.stdout, stderr = process.stderr } = {}) {
  const mode = outputMode || "compact";
  return {
    outputMode: mode,
    writeLine(line = "") {
      stdout.write(`${line}\n`);
    },
    writeDebugLine(line = "") {
      stdout.write(`${line}\n`);
    },
    phaseStarted(label) {
      if (mode !== "debug") return;
      stdout.write(`\n── ${label} ──\n`);
    },
    toolchainResolved(config, resolvedToolchain) {
      if (mode !== "debug") return;
      stdout.write(
        `[testkit] ${config.runtimeLabel || config.name}:${config.name} toolchain ${resolvedToolchain.summary}\n`
      );
    },
    localServiceStarting(config, command) {
      if (mode !== "debug") return;
      stdout.write(`Starting ${config.runtimeLabel}:${config.name}: ${command}\n`);
    },
    serviceSkipped(config, reason) {
      stdout.write(`SKIP ${config.name} ${reason}\n`);
    },
    plannedSkip(entry) {
      stdout.write(
        `SKIP ${entry.serviceName} ${entry.type} ${normalizePath(entry.file)} 0s ${shortenMessage(entry.reason || "skipped")}\n`
      );
    },
    taskStarted(task, targetConfig) {
      if (mode !== "debug") return;
      stdout.write(`RUN  ${targetConfig.name} ${task.type} ${task.file}\n`);
    },
    taskFinished(task, outcome) {
      if (mode === "json") return;
      const status = outcome.status === "skipped" ? "SKIP" : outcome.failed ? "FAIL" : "PASS";
      const duration = formatDuration(outcome.durationMs || 0);
      const detail =
        status === "FAIL"
          ? ` ${shortenMessage(outcome.error || firstFailureDetail(outcome) || "failed")}`
          : outcome.status === "not_run"
            ? ` ${shortenMessage(outcome.reason || "not run")}`
            : "";
      stdout.write(
        `${status} ${task.serviceName} ${displayTaskType(task)} ${normalizePath(task.file)} ${duration}${detail}\n`
      );
    },
    telemetry(message) {
      if (mode === "json") return;
      stdout.write(`${message}\n`);
    },
    runSummary(results, durationMs, knownFailureIssueValidation = null) {
      const lines =
        mode === "debug"
          ? buildDebugRunSummaryLines(results, durationMs, knownFailureIssueValidation)
          : buildCompactRunSummaryLines(results, durationMs, knownFailureIssueValidation);
      for (const line of lines) stdout.write(`${line}\n`);
    },
    error(message) {
      stderr.write(`${message}\n`);
    },
  };
}

function displayTaskType(task) {
  if (task.framework === "playwright") return "pw";
  if (task.type === "integration") return "int";
  return task.type;
}

function shortenMessage(message) {
  return String(message).replace(/\s+/g, " ").trim().slice(0, 180);
}

function firstFailureDetail(outcome) {
  return outcome.failureDetails?.[0]?.message || outcome.failureDetails?.[0]?.title || null;
}

function normalizePath(filePath) {
  return String(filePath).split(path.sep).join("/");
}
