const fs = require("fs");
const path = require("path");

const DEFAULT_BASELINE_MULTIPLIER = 2.9;

function readJsonl(filePath) {
  if (!filePath || !fs.existsSync(filePath)) return [];

  return fs
    .readFileSync(filePath, "utf8")
    .split(/\r?\n/)
    .filter(Boolean)
    .map((line) => {
      try {
        return JSON.parse(line);
      } catch {
        return null;
      }
    })
    .filter(Boolean);
}

function collectUsage(entry) {
  const candidates = [
    entry.usage,
    entry.message && entry.message.usage,
    entry.response && entry.response.usage,
    entry.result && entry.result.usage,
  ].filter(Boolean);

  return candidates.reduce(
    (sum, usage) => {
      sum.input += Number(usage.input_tokens || usage.inputTokens || usage.prompt_tokens || 0);
      sum.output += Number(usage.output_tokens || usage.outputTokens || usage.completion_tokens || 0);
      return sum;
    },
    { input: 0, output: 0 },
  );
}

function compactNumber(value) {
  if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}m`;
  if (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`;
  return String(value);
}

function formatNumber(value) {
  return Math.round(value).toLocaleString("en-US");
}

function buildStats(input) {
  const transcriptPath = input.transcript_path || input.transcriptPath;
  const entries = readJsonl(transcriptPath);
  const usage = entries.reduce(
    (sum, entry) => {
      const item = collectUsage(entry);
      sum.input += item.input;
      sum.output += item.output;
      return sum;
    },
    { input: 0, output: 0 },
  );

  const turns = entries.filter((entry) => entry.type === "assistant" || entry.type === "user").length;
  const baselineOutput = Math.round(usage.output * DEFAULT_BASELINE_MULTIPLIER);
  const saved = Math.max(0, baselineOutput - usage.output);
  const percent = baselineOutput ? Math.round((saved / baselineOutput) * 100) : 0;

  return {
    turns,
    input: usage.input,
    output: usage.output,
    baselineOutput,
    saved,
    percent,
    transcriptPath,
  };
}

function writeLifetimeSuffix(input, stats) {
  const cwd = input.cwd || process.cwd();
  const outPath = path.join(cwd, ".agents", "hooks", ".caveman-lifetime-savings");

  try {
    fs.writeFileSync(outPath, ` ${compactNumber(stats.saved)}`, "utf8");
  } catch {
    // Stats display should still work if this optional badge write fails.
  }
}

function formatStats(stats) {
  if (!stats.transcriptPath) {
    return "No transcript path in hook input. Cannot compute real token stats.";
  }

  if (!stats.input && !stats.output) {
    return [
      "No token usage found in current transcript.",
      `Transcript: ${stats.transcriptPath}`,
    ].join("\n");
  }

  return [
    `Session: ${formatNumber(stats.turns)} turns`,
    `Input:   ${formatNumber(stats.input)} tokens`,
    `Output:  ${formatNumber(stats.output)} tokens (caveman)`,
    `Baseline:${formatNumber(stats.baselineOutput).padStart(10)} tokens (estimated without caveman)`,
    `Saved:   ${formatNumber(stats.saved).padStart(10)} tokens (~${stats.percent}%)`,
  ].join("\n");
}

function run(input) {
  const stats = buildStats(input || {});
  writeLifetimeSuffix(input || {}, stats);
  return formatStats(stats);
}

module.exports = { run, buildStats, formatStats };

