// src/lib/updo/interactiveSelect.ts
import {
  createPrompt,
  ExitPromptError,
  isDownKey,
  isEnterKey,
  isSpaceKey,
  isUpKey,
  useKeypress,
  useRef,
  useState
} from "@inquirer/core";
import chalk from "chalk";
import semver from "semver";
function compareVersion(value) {
  if (!value || value === "mixed") return void 0;
  return semver.minVersion(value)?.version;
}
function diffColor(from, to, fallback) {
  const fromV = compareVersion(from);
  const toV = compareVersion(to);
  if (!fromV || !toV) return fallback;
  const diff = semver.diff(fromV, toV);
  if (diff === "major" || diff === "premajor") return chalk.red;
  if (diff === "minor" || diff === "preminor") return chalk.yellow;
  return chalk.green;
}
function versionColor(version, current, mixedBaseline) {
  if (!version) return chalk.gray;
  if (current === "mixed") {
    if (!mixedBaseline || version === mixedBaseline) return chalk.green;
    return diffColor(mixedBaseline, version, chalk.green);
  }
  if (!current || version === current) return chalk.gray;
  return diffColor(current, version, chalk.gray);
}
function pad(raw, colored, width) {
  return colored + " ".repeat(Math.max(0, width - raw.length));
}
function dot(selected) {
  return selected ? chalk.green("\u25CF") : chalk.dim("\u25CB");
}
function renderHeader(w) {
  const header = [
    "  ",
    chalk.bold("Package".padEnd(w.name)),
    chalk.bold("Current".padEnd(w.current)),
    chalk.bold("  Wanted".padEnd(w.wanted + 2)),
    chalk.bold("  Latest".padEnd(w.latest + 2)),
    chalk.bold("  Next/RC".padEnd(w.next + 2))
  ].join("  ");
  const totalWidth = w.name + w.current + w.wanted + w.latest + w.next + 24;
  return `${header}
${chalk.gray("\u2500".repeat(totalWidth))}`;
}
function renderRow(dep, selection, active, w) {
  const pointer = active ? chalk.cyan("\u276F") : " ";
  const rawName = dep.name;
  const name = active ? chalk.white(rawName) : chalk.gray(rawName);
  const rawCurrent = dep.current ?? "-";
  const current = chalk.gray(rawCurrent);
  const rawWanted = dep.wanted ?? "-";
  const wantedColorFn = dep.wanted ? versionColor(dep.wanted, dep.current) : chalk.gray;
  const wantedDot = dep.wanted ? dot(selection === 0) : " ";
  const wanted = `${wantedDot} ${pad(rawWanted, wantedColorFn(rawWanted), w.wanted)}`;
  const rawLatest = dep.latest ?? "-";
  const latestColorFn = dep.latest ? versionColor(dep.latest, dep.current, dep.wanted) : chalk.gray;
  const latestDot = dep.latest ? dot(selection === 1) : " ";
  const latest = `${latestDot} ${pad(rawLatest, latestColorFn(rawLatest), w.latest)}`;
  const rawNext = dep.next ?? "-";
  const nextColorFn = dep.next ? versionColor(dep.next, dep.current, dep.wanted) : chalk.gray;
  const nextDot = dep.next ? dot(selection === 2) : " ";
  const next = `${nextDot} ${pad(rawNext, nextColorFn(rawNext), w.next)}`;
  return `${pointer} ${pad(rawName, name, w.name)}  ${pad(rawCurrent, current, w.current)}  ${wanted}  ${latest}  ${next}`;
}
function getAvailableSelections(dep) {
  const available = [-1];
  if (dep.wanted) available.push(0);
  if (dep.latest && dep.latest !== dep.wanted) available.push(1);
  if (dep.next) available.push(2);
  return available;
}
function getTargetVersion(dep, selection) {
  if (selection === 0) return dep.wanted;
  if (selection === 1) return dep.latest;
  if (selection === 2) return dep.next;
  return void 0;
}
function computeWidths(rows) {
  let name = 7;
  let current = 7;
  let wanted = 6;
  let latest = 6;
  let next = 7;
  for (const dep of rows) {
    name = Math.max(name, dep.name.length);
    current = Math.max(current, (dep.current ?? "-").length);
    wanted = Math.max(wanted, (dep.wanted ?? "-").length);
    latest = Math.max(latest, (dep.latest ?? "-").length);
    next = Math.max(next, (dep.next ?? "-").length);
  }
  return {
    current,
    latest,
    name,
    next,
    wanted
  };
}
function renderPage(rows, cursor, selections, w, pageSize) {
  const total = rows.length;
  let start = 0;
  if (total > pageSize) {
    start = Math.max(0, Math.min(cursor - Math.floor(pageSize / 2), total - pageSize));
  }
  const end = Math.min(start + pageSize, total);
  const lines = [];
  for (let i = start; i < end; i++) {
    lines.push(renderRow(rows[i], selections[i], i === cursor, w));
  }
  if (total > pageSize) {
    if (start > 0) lines.unshift(chalk.dim("  \u2191 more"));
    if (end < total) lines.push(chalk.dim("  \u2193 more"));
  }
  return lines.join("\n");
}
var updoPrompt = createPrompt((config, done) => {
  const { rows } = config;
  const [cursor, setCursor] = useState(0);
  const [tick, setTick] = useState(0);
  const availableSelectionsRef = useRef(rows.map((r) => getAvailableSelections(r)));
  const selectionsRef = useRef(rows.map(() => -1));
  const widthsRef = useRef(computeWidths(rows));
  useKeypress((key) => {
    if (key.name === "escape" || key.ctrl && key.name === "c") {
      done([]);
      return;
    }
    if (isEnterKey(key)) {
      const results = [];
      for (const [i, dep] of rows.entries()) {
        const version = getTargetVersion(dep, selectionsRef.current[i]);
        if (version) {
          results.push({
            name: dep.name,
            targetRange: version,
            workspaces: dep.workspaces
          });
        }
      }
      done(results);
      return;
    }
    if (isUpKey(key)) {
      setCursor(Math.max(0, cursor - 1));
    } else if (isDownKey(key)) {
      setCursor(Math.min(rows.length - 1, cursor + 1));
    } else if (isSpaceKey(key)) {
      const available = availableSelectionsRef.current[cursor];
      const currentSel = selectionsRef.current[cursor];
      const currentIdx = available.indexOf(currentSel);
      const nextIdx = (currentIdx + 1) % available.length;
      selectionsRef.current[cursor] = available[nextIdx];
      setTick(tick + 1);
    }
  });
  const w = widthsRef.current;
  const header = renderHeader(w);
  const page = renderPage(rows, cursor, selectionsRef.current, w, 20);
  const selectedCount = selectionsRef.current.filter((s) => s >= 0).length;
  const status = chalk.gray(`  ${selectedCount} selected  \u2191/\u2193 navigate  space cycle version  enter confirm`);
  return `${header}
${page}
${status}`;
});
async function interactiveSelect(deps) {
  const updatable = deps.filter((d) => d.updateAvailable);
  if (updatable.length === 0) {
    console.log(chalk.green("\nAll packages are up to date!"));
    return [];
  }
  if (!process.stdout.isTTY) {
    console.log(chalk.yellow("Non-interactive environment detected, skipping selection."));
    return [];
  }
  try {
    return await updoPrompt({ rows: updatable });
  } catch (error) {
    if (error instanceof ExitPromptError) {
      return [];
    }
    throw error;
  }
}
export {
  interactiveSelect
};
//# sourceMappingURL=interactiveSelect.mjs.map