const { useState, useEffect, useMemo, useCallback } = React;

// ---------- Registry ----------
const REGISTRY = window.SCRIPT_REGISTRY;
const SCRIPT_KEYS = Object.keys(REGISTRY);

// ---------- Defaults ----------
const DEFAULT_NAMES = { alice: "Alice", ben: "Ben", cindy: "Cindy", david: "David" };
const LS_SCRIPT = "chillwari-alpha-script";

function lsIndexKey(k)  { return `chillwari-alpha-${k}-index`; }
function lsNamesKey(k)  { return `chillwari-alpha-${k}-names`; }

function loadIndex(scriptKey, total) {
  try {
    const v = parseInt(localStorage.getItem(lsIndexKey(scriptKey)) || "0", 10);
    return isNaN(v) ? 0 : Math.max(0, Math.min(total - 1, v));
  } catch { return 0; }
}

function loadNames(scriptKey) {
  try {
    const saved = JSON.parse(localStorage.getItem(lsNamesKey(scriptKey)) || "{}");
    return { ...DEFAULT_NAMES, ...saved };
  } catch { return { ...DEFAULT_NAMES }; }
}

// ---------- Name resolution ----------
function resolveNames(str, names) {
  if (str == null) return str;
  return String(str)
    .replaceAll("[alice]", names.alice || DEFAULT_NAMES.alice)
    .replaceAll("[ben]", names.ben || DEFAULT_NAMES.ben)
    .replaceAll("[cindy]", names.cindy || DEFAULT_NAMES.cindy)
    .replaceAll("[david]", names.david || DEFAULT_NAMES.david);
}

// ---------- Callouts ----------
const CALLOUT_STYLES = {
  warn:    { bg: "#fef7e6", border: "#e9c776", ink: "#7a5a0e", icon: "⚠", label: "金額填錯" },
  money:   { bg: "#e9f5ec", border: "#8fc29a", ink: "#1f5b31", icon: "$", label: "旅途中先結算" },
  coin:    { bg: "#eaf1fb", border: "#8fb1dc", ink: "#1d4273", icon: "◎", label: "多人付款" },
  reorder: { bg: "#f0eaf7", border: "#b39ed1", ink: "#4c2e78", icon: "↻", label: "補登 / 順序不對" },
};

// ---------- Small helpers ----------
function Row({ label, children, mono }) {
  return (
    <div className="field-row">
      <div className="field-label">{label}</div>
      <div className={"field-value" + (mono ? " mono" : "")}>{children}</div>
    </div>
  );
}

// ---------- Name mapping inputs ----------
function NameMapping({ names, setNames }) {
  const fields = [
    { key: "alice", label: "你（主測者）",      ph: "例：小安", role: "Alice" },
    { key: "ben",   label: "另一半",            ph: "例：小布", role: "Ben" },
    { key: "cindy", label: "朋友 1",            ph: "例：小克", role: "Cindy" },
    { key: "david", label: "朋友 2",            ph: "例：小德", role: "David" },
  ];
  return (
    <div className="name-mapping">
      <div className="name-mapping__head">
        <div className="name-mapping__title">填寫真實名字</div>
        <div className="name-mapping__sub">建完群組後填入成員的真名，後面所有關卡都會自動套用。</div>
      </div>
      <div className="name-mapping__grid">
        {fields.map(f => (
          <label key={f.key} className="name-field">
            <div className="name-field__label">
              {f.label}
              <span className="name-field__role">→ {f.role}</span>
            </div>
            <input
              type="text"
              placeholder={f.ph}
              value={names[f.key] || ""}
              onChange={e => setNames({ ...names, [f.key]: e.target.value })}
            />
          </label>
        ))}
      </div>
    </div>
  );
}

// ---------- Breakdown table ----------
function Breakdown({ rows, names, hasItem }) {
  return (
    <table className="breakdown">
      <thead>
        <tr>
          <th>成員</th>
          {hasItem && <th>品項</th>}
          <th className="num">金額</th>
        </tr>
      </thead>
      <tbody>
        {rows.map((r, i) => (
          <tr key={i}>
            <td>{resolveNames(r[0], names)}</td>
            {hasItem && <td>{r[2] || ""}</td>}
            <td className="num mono">{hasItem ? r[1] : r[1]}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

// ---------- Task card ----------
function TaskCard({ task, names, setNames }) {
  const narrativeLines = (task.narrative || []).map(l => resolveNames(l, names));
  const isExpense = task.type === "expense";
  const isSettlement = task.type === "settlement";
  const hasItem = task.breakdown && task.breakdown[0] && task.breakdown[0].length >= 3;
  const callout = task.callout;
  const cStyle = callout ? CALLOUT_STYLES[callout.type] : null;

  const kindBadge =
    isExpense ? { label: "費用", cls: "badge--expense" }
    : isSettlement ? { label: "結算", cls: "badge--settlement" }
    : { label: "設定 / 檢查", cls: "badge--setup" };

  return (
    <article className="card">
      <header className="card__head">
        <span className={"badge " + kindBadge.cls}>{kindBadge.label}</span>
        <h1 className="card__title">{task.title}</h1>
      </header>

      <div className="card__narrative">
        {narrativeLines.map((l, i) => <p key={i}>{l}</p>)}
      </div>

      {isExpense && (
        <div className="card__fields">
          <Row label="模擬時間" mono>{task.time}</Row>
          <Row label="時區" mono>{task.tz}</Row>
          <Row label="付款人">{resolveNames(task.payer, names)}</Row>
          <Row label="分攤成員">{resolveNames(task.sharers, names)}</Row>
          <Row label="分帳方式">
            <span className={"strategy strategy--" + task.strategy.toLowerCase().replace(/[^a-z]/g, "")}>
              {task.strategy}
            </span>
          </Row>
          <Row label="金額" mono>{task.amount}</Row>
          <Row label="費用名稱">{task.label}</Row>
        </div>
      )}

      {task.breakdown && (
        <div className="card__breakdown">
          <div className="card__breakdown-label">
            {task.strategy === "Personal" ? "各自金額" : `${task.strategy} 明細`}
          </div>
          <Breakdown rows={task.breakdown} names={names} hasItem={hasItem} />
          {task.note && <div className="card__note">{resolveNames(task.note, names)}</div>}
        </div>
      )}

      {!task.breakdown && task.note && (
        <div className="card__note">{resolveNames(task.note, names)}</div>
      )}

      {callout && (
        <div
          className="callout"
          style={{
            background: cStyle.bg,
            borderColor: cStyle.border,
            color: cStyle.ink,
          }}
        >
          <div className="callout__icon" style={{ color: cStyle.ink }}>{cStyle.icon}</div>
          <div className="callout__body">
            <div className="callout__label">{cStyle.label}</div>
            <div className="callout__text">{resolveNames(callout.text, names)}</div>
          </div>
        </div>
      )}

      {task.nameMapping && <NameMapping names={names} setNames={setNames} />}
    </article>
  );
}

// ---------- Main App ----------
function App() {
  const [scriptKey, setScriptKeyState] = useState(() => {
    try {
      const saved = localStorage.getItem(LS_SCRIPT);
      return (saved && REGISTRY[saved]) ? saved : SCRIPT_KEYS[0];
    } catch { return SCRIPT_KEYS[0]; }
  });

  const script = REGISTRY[scriptKey];
  const tasks = script.tasks;
  const total = tasks.length;

  const [index, setIndex] = useState(() => loadIndex(scriptKey, total));

  const [names, setNamesState] = useState(() => loadNames(scriptKey));

  const setScriptKey = useCallback((key) => {
    try { localStorage.setItem(LS_SCRIPT, key); } catch {}
    setScriptKeyState(key);
  }, []);

  useEffect(() => {
    const newScript = REGISTRY[scriptKey];
    setIndex(loadIndex(scriptKey, newScript.tasks.length));
    setNamesState(loadNames(scriptKey));
  }, [scriptKey]);

  const setNames = useCallback((n) => {
    const toSave = {};
    ["alice", "ben", "cindy", "david"].forEach(k => { if (n[k]) toSave[k] = n[k]; });
    setNamesState(prev => ({ ...prev, ...n }));
    try { localStorage.setItem(lsNamesKey(scriptKey), JSON.stringify(toSave)); } catch {}
  }, [scriptKey]);

  const displayNames = useMemo(() => ({
    alice: (names.alice && names.alice.trim()) || DEFAULT_NAMES.alice,
    ben:   (names.ben   && names.ben.trim())   || DEFAULT_NAMES.ben,
    cindy: (names.cindy && names.cindy.trim()) || DEFAULT_NAMES.cindy,
    david: (names.david && names.david.trim()) || DEFAULT_NAMES.david,
  }), [names.alice, names.ben, names.cindy, names.david]);

  useEffect(() => {
    try { localStorage.setItem(lsIndexKey(scriptKey), String(index)); } catch {}
  }, [index, scriptKey]);

  const go = useCallback((delta) => {
    setIndex(i => Math.max(0, Math.min(total - 1, i + delta)));
  }, [total]);

  useEffect(() => {
    const onKey = (e) => {
      const t = e.target;
      if (t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA")) return;
      if (e.key === "ArrowRight" || e.key === " ") { e.preventDefault(); go(+1); }
      else if (e.key === "ArrowLeft") { e.preventDefault(); go(-1); }
      else if (e.key === "Home") { e.preventDefault(); setIndex(0); }
      else if (e.key === "End") { e.preventDefault(); setIndex(total - 1); }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [go, total]);

  const task = tasks[index];
  const progressPct = ((index + 1) / total) * 100;

  return (
    <div className="app" data-screen-label={`${String(task.id).padStart(2,"0")} ${task.title}`}>
      <div className="stage">
        <div className="stage__section">
          <span className="stage__section-dot" />
          {task.section}
        </div>
        <TaskCard task={task} names={{...names, ...displayNames}} setNames={setNames} />
      </div>

      <nav className="navbar">
        <button className="nav-btn" onClick={() => go(-1)} disabled={index === 0} aria-label="上一題">
          <span className="nav-btn__arrow">←</span>
          <span className="nav-btn__label">上一題</span>
        </button>

        <div className="nav-center">
          <div className="counter">
            <span className="counter__num mono">{String(index + 1).padStart(2, "0")}</span>
            <span className="counter__sep mono">/</span>
            <span className="counter__total mono">{total}</span>
          </div>
          <div className="progress"><div className="progress__bar" style={{ width: progressPct + "%" }} /></div>
        </div>

        <button className="nav-btn nav-btn--next" onClick={() => go(+1)} disabled={index === total - 1} aria-label="下一題">
          <span className="nav-btn__label">下一題</span>
          <span className="nav-btn__arrow">→</span>
        </button>
      </nav>

      <div className="brand">
        <div className="brand__mark">◆</div>
        <div className="brand__text">
          <div className="brand__name">Chillwari · Alpha 測試手冊</div>
          <div className="brand__sub">{script.label} · {script.sub}</div>
        </div>
        {SCRIPT_KEYS.length > 1 && (
          <div className="trip-switcher">
            {SCRIPT_KEYS.map(k => (
              <button
                key={k}
                className={"trip-tab" + (k === scriptKey ? " trip-tab--active" : "")}
                onClick={() => setScriptKey(k)}
              >
                {REGISTRY[k].label}
              </button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
