#!/usr/bin/env node
/**
 * @file One-off codemod: shifts every raw `blue-*`/`amber-*` Tailwind utility
 * one shade darker (100→200 ... 700→800), mirroring the 1-step darkening
 * already applied to the accent token (`#2563eb` blue-600 → `#1d4ed8`
 * blue-700). `blue` here is the "current stage" / info color (e.g.
 * PipelineMap's `current` state, unrelated to the `accent` CSS-variable
 * token); `amber` is the warning/pending/auto-detected color used across
 * badges, banners, and the pipeline's dashed "auto: <stage>" chip. `950` is
 * left alone — already the darkest step available.
 * @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
 */
import { readdirSync, readFileSync, writeFileSync, statSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";

const SHIFT = {
  50: 100,
  100: 200,
  200: 300,
  300: 400,
  400: 500,
  500: 600,
  600: 700,
  700: 800,
  800: 900,
};
const COLORS = ["blue", "amber"];
const PROPS = ["text", "bg", "border", "ring", "from", "to", "via", "fill"];

// Descending by `from` — JS enumerates integer-like object keys ascending
// regardless of source order, and shifting low-to-high would let an already
// -shifted "200" (from 100) get caught and shifted AGAIN by the 200 rule.
// Highest-first guarantees each original shade is only ever matched once.
const SHIFTS_DESC = Object.entries(SHIFT)
  .map(([from, to]) => [Number(from), to])
  .sort((a, b) => b[0] - a[0]);

function rewrite(text) {
  let out = text;
  for (const prop of PROPS) {
    for (const color of COLORS) {
      for (const [from, to] of SHIFTS_DESC) {
        const re = new RegExp(`\\b${prop}-${color}-${from}(\\/[0-9]+)?\\b`, "g");
        out = out.replace(re, (_m, opacity) => `${prop}-${color}-${to}${opacity || ""}`);
      }
    }
  }
  return out;
}

function walk(dir, files = []) {
  for (const entry of readdirSync(dir)) {
    const full = join(dir, entry);
    const st = statSync(full);
    if (st.isDirectory()) {
      if (entry === "node_modules") continue;
      walk(full, files);
    } else if (entry.endsWith(".tsx")) {
      files.push(full);
    }
  }
  return files;
}

const scriptDir = fileURLToPath(new URL(".", import.meta.url));
const root = join(scriptDir, "..", "client", "src");
const files = walk(root);
let changed = 0;
for (const file of files) {
  const before = readFileSync(file, "utf8");
  const after = rewrite(before);
  if (after !== before) {
    writeFileSync(file, after);
    changed++;
  }
}
console.log(`rewrote ${changed} file(s)`);
