/* Catalog tab — single place to edit the lists used across the app
   (Task types, Types). Writes the same localStorage keys the calculator
   companion + Designer Tables read, so edits flow everywhere. */
(function () {
const { useState, useEffect } = React;

const TT_KEY = "nove8_tasktypes_v1";
const TY_KEY = "nove8_types_v1";
const FN_KEY = "nove8_funnels_v1";
const TL_KEY = "nove8_tools_v1";
const PALETTE = ["#f0625a", "#6c79f6", "#16b277", "#f59e0b", "#ec4899", "#0ea5e9", "#8b5cf6", "#14b8a6", "#ef4444", "#65a30d"];
const DEF_TT = [
  { id: "cs", label: "creatives S", color: "#f0625a" },
  { id: "cm", label: "creatives M", color: "#6c79f6" },
  { id: "smm", label: "SMM", color: "#16b277" },
  { id: "product", label: "Product", color: "#f59e0b" },
  { id: "hrpr", label: "HR/PR", color: "#ec4899" },
  { id: "meetings", label: "Meetings", color: "#0ea5e9" },
];
const DEF_TY = [
  { id: "motion", label: "motion", color: "#6c79f6" },
  { id: "graphic", label: "graphic", color: "#16b277" },
];
const DEF_FN = [];
const DEF_TL = [];
const uid = (p) => p + "_" + Date.now().toString(36) + Math.floor(Math.random() * 1000).toString(36);
function load(key, def) {
  try { const r = localStorage.getItem(key); if (r) { const a = JSON.parse(r); if (Array.isArray(a) && a.length) return a; } } catch (e) {}
  return def;
}

function Section({ title, hint, items, onAdd, onRemove, onColor, onMove, readOnly }) {
  const [val, setVal] = useState("");
  const add = () => { if (val.trim()) { onAdd(val.trim()); setVal(""); } };
  return (
    <div className="cat-card">
      <div className="cat-card-head"><h3>{title}</h3><span className="cat-count">{items.length}</span></div>
      {hint && <div className="cat-hint">{hint}</div>}
      <div className="cat-chips">
        {items.map((it, i) => (
          <span className="cat-chip" key={it.id}>
            {!readOnly && onMove && (
              <button className="cat-move" disabled={i === 0} title="Move left — the order applies everywhere (e.g. matrix columns)"
                onClick={() => onMove(it.id, -1)}>‹</button>
            )}
            {onColor
              ? <input type="color" className="cat-dot cat-dot-input" value={it.color || "#c2c8d0"}
                  title="Change colour — applies for everyone"
                  onChange={(e) => onColor(it.id, e.target.value)} />
              : <span className="cat-dot" style={{ background: it.color || "#c2c8d0" }}></span>}
            {it.label || it.name}
            {!readOnly && onMove && (
              <button className="cat-move" disabled={i === items.length - 1} title="Move right — the order applies everywhere (e.g. matrix columns)"
                onClick={() => onMove(it.id, 1)}>›</button>
            )}
            {!readOnly && <button onClick={() => onRemove(it.id)} title="Remove">×</button>}
          </span>
        ))}
        {items.length === 0 && <span className="cat-empty">Empty</span>}
      </div>
      {!readOnly && (
        <div className="cat-add">
          <input value={val} placeholder="New item…" onChange={(e) => setVal(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") add(); }} />
          <button className="cat-btn" disabled={!val.trim()} onClick={add}>Add</button>
        </div>
      )}
    </div>
  );
}

function CalcSection({ calcs }) {
  return (
    <div className="cat-card">
      <div className="cat-card-head">
        <h3>Calculators</h3>
        <span className="cat-count">{calcs ? calcs.filter((c) => !c.hidden).length : "…"}</span>
      </div>
      <div className="cat-hint">One per product × type · managed on the Story Points screen (“All calculators”).</div>
      <div className="cat-calcs">
        {!calcs && <span className="cat-empty">Loading…</span>}
        {calcs && calcs.length === 0 && <span className="cat-empty">None yet</span>}
        {(calcs || []).map((c) => (
          <div className={"cat-calc" + (c.hidden ? " cat-calc-hidden" : "")} key={c.id}>
            <span className="cat-calc-name">{c.name}</span>
            <span className="cat-calc-meta">{c.items} items · {c.groups} groups{c.hidden ? " · product removed" : ""}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function CatalogTab({ products, onProductColor }) {
  const [taskTypes, setTaskTypes] = useState(() => load(TT_KEY, DEF_TT));
  const [types, setTypes] = useState(() => load(TY_KEY, DEF_TY));
  const [funnels, setFunnels] = useState(() => load(FN_KEY, DEF_FN));
  const [tools, setTools] = useState(() => load(TL_KEY, DEF_TL));
  // Calculators (one per Product × Type) live in the calculator's own config —
  // listed here for reference; they are managed on the Story Points screen.
  const [calcs, setCalcs] = useState(null);
  useEffect(() => {
    let alive = true;
    fetch("/api/config", { cache: "no-store" })
      .then((r) => (r.ok ? r.json() : null))
      .then((j) => {
        if (!alive) return;
        const cfg = (j && (j.config || j.state || j)) || {};
        const list = Array.isArray(cfg.calculators) ? cfg.calculators : [];
        const groups = Array.isArray(cfg.groups) ? cfg.groups : [];
        const tasks = Array.isArray(cfg.tasks) ? cfg.tasks : [];
        setCalcs(list.map((c) => {
          const gs = groups.filter((g) => g.calcId === c.id);
          const ids = new Set(gs.map((g) => g.id));
          return {
            id: c.id,
            name: c.name || "Calculator",
            hidden: !!c.hidden,
            groups: gs.length,
            items: tasks.filter((t) => ids.has(t.groupId)).length,
          };
        }));
      })
      .catch(() => { if (alive) setCalcs([]); });
    return () => { alive = false; };
  }, []);
  useEffect(() => { try { localStorage.setItem(TT_KEY, JSON.stringify(taskTypes)); } catch (e) {} }, [taskTypes]);
  useEffect(() => { try { localStorage.setItem(TY_KEY, JSON.stringify(types)); } catch (e) {} }, [types]);
  useEffect(() => { try { localStorage.setItem(FN_KEY, JSON.stringify(funnels)); } catch (e) {} }, [funnels]);
  useEffect(() => { try { localStorage.setItem(TL_KEY, JSON.stringify(tools)); } catch (e) {} }, [tools]);

  // Shared catalog lives on the server. Admin/manager edits publish the whole
  // document (write-through, debounced — colour dragging fires rapidly); the
  // shell's background poll delivers it to everyone else.
  const firstRun = React.useRef(true);
  const pubTimer = React.useRef(null);
  useEffect(() => {
    if (firstRun.current) { firstRun.current = false; return; }
    try { localStorage.setItem("nove8_catalog_edit_ts", String(Date.now())); } catch (e) {}
    let role = "";
    try { role = localStorage.getItem("nove8_shell_role") || ""; } catch (e) {}
    if (role !== "admin" && role !== "manager") return;
    if (pubTimer.current) clearTimeout(pubTimer.current);
    pubTimer.current = setTimeout(() => {
      fetch("/api/catalog", {
        method: "PUT",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ taskTypes, types, funnels, tools }),
      }).catch(() => {});
    }, 600);
  }, [taskTypes, types, funnels, tools]);

  // Refresh when the shell applies a newer server catalog.
  useEffect(() => {
    const reload = () => {
      firstRun.current = true; // don't echo the applied server state back
      setTaskTypes(load(TT_KEY, DEF_TT));
      setTypes(load(TY_KEY, DEF_TY));
      setFunnels(load(FN_KEY, DEF_FN));
      setTools(load(TL_KEY, DEF_TL));
    };
    window.addEventListener("nove8-catalog-changed", reload);
    return () => window.removeEventListener("nove8-catalog-changed", reload);
  }, []);

  const addTT = (label) => setTaskTypes((ts) => [...ts, { id: uid("tt"), label, color: PALETTE[ts.length % PALETTE.length] }]);
  const rmTT = (id) => setTaskTypes((ts) => ts.filter((t) => t.id !== id));
  const colorTT = (id, color) => setTaskTypes((ts) => ts.map((t) => t.id === id ? { ...t, color } : t));
  const addTY = (label) => setTypes((ts) => [...ts, { id: uid("ty"), label, color: PALETTE[(ts.length + 3) % PALETTE.length] }]);
  const rmTY = (id) => setTypes((ts) => ts.filter((t) => t.id !== id));
  const colorTY = (id, color) => setTypes((ts) => ts.map((t) => t.id === id ? { ...t, color } : t));
  const addTL = (label) => setTools((ts) => [...ts, { id: uid("tl"), label, color: PALETTE[(ts.length + 1) % PALETTE.length] }]);
  const rmTL = (id) => setTools((ts) => ts.filter((t) => t.id !== id));
  const colorTL = (id, color) => setTools((ts) => ts.map((t) => t.id === id ? { ...t, color } : t));
  const addFN = (label) => setFunnels((fs) => [...fs, { id: uid("fn"), label, color: PALETTE[(fs.length + 5) % PALETTE.length] }]);
  const rmFN = (id) => setFunnels((fs) => fs.filter((f) => f.id !== id));
  const colorFN = (id, color) => setFunnels((fs) => fs.map((f) => f.id === id ? { ...f, color } : f));
  // reorder within a list — the stored order drives everything downstream
  // (matrix columns, dropdowns), so moving a chip re-publishes the catalog
  const mover = (setter) => (id, dir) => setter((list) => {
    const i = list.findIndex((x) => x.id === id);
    const j = i + dir;
    if (i < 0 || j < 0 || j >= list.length) return list;
    const next = list.slice();
    const tmp = next[i]; next[i] = next[j]; next[j] = tmp;
    return next;
  });
  const moveTT = mover(setTaskTypes);
  const moveTY = mover(setTypes);
  const moveFN = mover(setFunnels);
  const moveTL = mover(setTools);

  return (
    <div className="cat">
      <div className="cat-toolbar">
        <h1>Catalog</h1>
        <p>Lists used by the calculator and Designer Tables · edits apply everywhere instantly</p>
      </div>
      <div className="cat-body">
        <Section title="Task types" hint="Calculator → “Task type” · Designer Tables matrix columns (in this order — use ‹ › to arrange)." items={taskTypes} onAdd={addTT} onRemove={rmTT} onColor={colorTT} onMove={moveTT} />
        <Section title="Types" hint="Calculator → “Type” · weekly view." items={types} onAdd={addTY} onRemove={rmTY} onColor={colorTY} onMove={moveTY} />
        <Section title="Funnels" hint="Calculator → “Funnel” (Graphic only) · Designer Tables “Funnel” column." items={funnels} onAdd={addFN} onRemove={rmFN} onColor={colorFN} onMove={moveFN} />
        <Section title="Tools" hint="Innovation Managers\u2019 tables \u2192 \u201cTool name\u201d column." items={tools} onAdd={addTL} onRemove={rmTL} onColor={colorTL} onMove={moveTL} />
        <CalcSection calcs={calcs} />
        <Section title="Products" hint="Managed in the Designers tab \u00b7 colours are editable here (admin)." items={products} readOnly onColor={onProductColor || undefined} />
      </div>
    </div>
  );
}

window.CatalogTab = CatalogTab;
})();
