import color from "picocolors";
import { initKeypress, onKey, stopKeypress } from "../keyboard.js";

function clearScreen() {
  process.stdout.write('\x1Bc');
}

export function createStepUI(options) {
  const { title, getSteps, onStepChange } = options;

  let steps = [];
  let results = [];
  let completed = new Set();
  let currentStep = 0;
  let currentOption = 0;
  let resolved = false;

  function initResults() {
    steps = typeof getSteps === "function" ? getSteps() : getSteps;
    results = steps.map(s => s.type === "multiselect" ? [...(s.default || [])] : s.default);
    completed = new Set();
    // 有默认值的步骤自动标记为已完成
    steps.forEach((s, i) => {
      if (s.default && s.default !== "none" && (!Array.isArray(s.default) || s.default.length > 0)) {
        completed.add(i);
      }
    });
    currentStep = 0;
    currentOption = 0;
    resolved = false;
  }

  function updateSteps(newSteps) {
    steps = newSteps;
    // 保留第一个步骤的结果，重置其他步骤为默认值
    const firstResult = results[0];
    results = steps.map((s, i) => {
      if (i === 0) return firstResult;
      return s.type === "multiselect" ? [...(s.default || [])] : s.default;
    });
    if (currentStep >= steps.length) currentStep = steps.length - 1;
  }

  function renderNav() {
    const nav = steps.map((step, i) => {
      if (step.disabled) return color.dim("□ " + step.name);
      if (i === currentStep) return color.bgCyan(color.black(" " + step.name + " "));
      return color.dim(step.name);
    });
    return "← " + nav.join("  ") + "  " + color.green("✓Submit") + " →";
  }

  function renderOptions() {
    const step = steps[currentStep];
    const lines = [color.cyan(step.message), ""];
    if (!step.options || !step.options.length) {
      lines.push(color.dim(step.emptyMessage || "无可用选项"));
      return lines.join("\n");
    }

    const termHeight = process.stdout.rows || 24;
    const maxVisible = Math.max(5, termHeight - 8);
    const total = step.options.length;

    let start = 0;
    if (total > maxVisible) {
      start = Math.max(0, Math.min(currentOption - Math.floor(maxVisible / 2), total - maxVisible));
    }
    const end = Math.min(start + maxVisible, total);

    if (start > 0) lines.push(color.dim("  ↑ 更多选项..."));

    for (let i = start; i < end; i++) {
      const opt = step.options[i];
      const isCurrent = i === currentOption;
      const isSelected = step.type === "multiselect"
        ? results[currentStep]?.includes(opt.value)
        : results[currentStep] === opt.value;
      const prefix = step.type === "multiselect"
        ? (isSelected ? color.green("◉ ") : "○ ")
        : (isSelected ? color.green("● ") : "○ ");
      const cursor = isCurrent ? color.cyan("❯ ") : "  ";
      const label = isCurrent ? color.cyan(opt.label) : opt.label;
      const check = isSelected ? color.green(" ✓") : "";
      lines.push(cursor + prefix + label + check);
    }

    if (end < total) lines.push(color.dim("  ↓ 更多选项..."));

    return lines.join("\n");
  }

  function render() {
    clearScreen();
    console.log(color.bgCyan(color.black(` ${title} `)));
    console.log("\n" + renderNav());
    console.log(color.dim("\n← → 切换步骤 | ↑ ↓ 选择 | Space 选中 | Tab 提交 | Esc 返回\n"));
    console.log(renderOptions());
  }

  function findPrevStep(from) {
    for (let i = from - 1; i >= 0; i--) {
      if (!steps[i].disabled) return i;
    }
    return from;
  }

  function findNextStep(from) {
    for (let i = from + 1; i < steps.length; i++) {
      if (!steps[i].disabled) return i;
    }
    return from;
  }

  function handleKey(key, resolve) {
    if (!key || resolved) return;

    const step = steps[currentStep];
    const optCount = step.options?.length || 0;

    switch (key.name) {
      case "left":
        const prevStep = findPrevStep(currentStep);
        if (prevStep !== currentStep) { currentStep = prevStep; currentOption = 0; }
        render();
        break;
      case "right":
        const nextStep = findNextStep(currentStep);
        if (nextStep !== currentStep) { currentStep = nextStep; currentOption = 0; }
        render();
        break;
      case "up":
        if (optCount) {
          currentOption = (currentOption - 1 + optCount) % optCount;
          render();
        }
        break;
      case "down":
        if (optCount) {
          currentOption = (currentOption + 1) % optCount;
          render();
        }
        break;
      case "space":
        if (optCount) {
          const opt = step.options[currentOption];
          if (step.type === "multiselect") {
            const list = results[currentStep];
            const idx = list.indexOf(opt.value);
            if (idx >= 0) list.splice(idx, 1);
            else list.push(opt.value);
          } else {
            results[currentStep] = opt.value;
          }
          completed.add(currentStep);
          if (onStepChange && currentStep === 0) {
            const newSteps = onStepChange(results[0]);
            if (newSteps) updateSteps(newSteps);
          }
          render();
        }
        break;
      case "return":
        if (optCount && step.type === "select") {
          results[currentStep] = step.options[currentOption].value;
          completed.add(currentStep);
          if (onStepChange && currentStep === 0) {
            const newSteps = onStepChange(results[0]);
            if (newSteps) updateSteps(newSteps);
          }
          const next = findNextStep(currentStep);
          if (next !== currentStep) { currentStep = next; currentOption = 0; }
          render();
        }
        break;
      case "tab":
        resolved = true;
        stopKeypress();
        setImmediate(() => resolve({ steps, results }));
        break;
      case "escape":
        resolved = true;
        stopKeypress();
        setImmediate(() => resolve(null));
        break;
      case "c":
        if (key.ctrl) {
          resolved = true;
          stopKeypress();
          setImmediate(() => resolve(null));
        }
        break;
    }
  }

  function runInteractive() {
    initResults();
    initKeypress();

    return new Promise(resolve => {
      render();
      onKey((str, key) => handleKey(key, resolve));
    });
  }

  function showSummary(lines) {
    clearScreen();
    console.log(color.bgCyan(color.black(` ${title} `)));
    console.log("\n" + color.green("配置完成！当前设置："));
    lines.forEach(line => console.log("  " + line));
    console.log();
  }

  return { runInteractive, showSummary, initResults };
}
