// ===================== Crafting Buch — Editors =====================
// Modal-based CRUD forms for Items, Categories, Recipes, Locations
// Plus Sync (export/import) panel

const { useState: uS, useEffect: uE, useRef: uR } = React;

// -------- Curated color palettes for items (southwest) --------
const ITEM_COLOR_PALETTE = [
  "#c8a47c", "#e8c89a", "#9c7c58", "#d9a8a4", "#b04a3a", "#e0d4b8",
  "#6b8a9c", "#8a5a36", "#a86838", "#5e3e22", "#a47648", "#d4c8a4",
  "#b09c70", "#8a8a96", "#ecebe6", "#cfd8c2", "#7ba2a8", "#7a5836",
  "#6a4226", "#724a2a", "#3e2818", "#4c2e1c", "#5a3820", "#7a8862",
  "#2d7a82", "#c89234", "#b8542a", "#8a2418",
];

const ITEM_GROUPS = ["Rohmaterial", "Verarbeitet", "Hilfsstoffe", "Produkte"];
const SYMBOLS = ["diamond", "zigzag", "arrow", "sun", "feather"];

function uid() {
  return "x" + Math.random().toString(36).slice(2, 9);
}

// ---------- Item-Combobox: Autocomplete + inline anlegen ----------
function ItemCombobox({ value, items, onChange, onCreateItem, placeholder }) {
  const itemList = Object.entries(items).sort(([,a],[,b]) => a.name.localeCompare(b.name));
  const [query, setQuery] = uS(() => items[value]?.name || "");
  const [open, setOpen] = uS(false);
  const ref = uR(null);

  // Sync wenn value von außen gesetzt wird (z.B. nach item creation)
  uE(() => {
    if (value && items[value]) setQuery(items[value].name);
  }, [value]);

  uE(() => {
    const handler = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  const filtered = query.trim()
    ? itemList.filter(([,it]) => it.name.toLowerCase().includes(query.trim().toLowerCase()))
    : itemList;
  const exactMatch = itemList.find(([,it]) => it.name.toLowerCase() === query.trim().toLowerCase());
  const showCreate = query.trim().length > 0 && !exactMatch;

  const select = (id, name) => { onChange(id); setQuery(name); setOpen(false); };

  const handleCreate = () => {
    const name = query.trim();
    if (!name) return;
    const id = onCreateItem(name);
    select(id, name);
  };

  return (
    <div ref={ref} style={{ position: "relative", flex: 1 }}>
      <input
        className="form-input"
        value={query}
        placeholder={placeholder || "Item suchen oder neu anlegen…"}
        autoComplete="off"
        onChange={e => { setQuery(e.target.value); setOpen(true); onChange(""); }}
        onFocus={() => setOpen(true)}
      />
      {open && (filtered.length > 0 || showCreate) && (
        <div className="combo-dropdown">
          {filtered.slice(0, 12).map(([id, it]) => (
            <div key={id} className={"combo-opt" + (id === value ? " selected" : "")}
              onMouseDown={() => select(id, it.name)}>
              <span className="combo-badge" style={{ background: it.color || "#8a9870" }}>
                {it.glyph || it.name.slice(0, 2).toUpperCase()}
              </span>
              <span>{it.name}</span>
              <span className="combo-group">{it.group}</span>
            </div>
          ))}
          {showCreate && (
            <div className="combo-opt combo-create" onMouseDown={handleCreate}>
              <span className="combo-badge" style={{ background: "#8a9870" }}>+</span>
              <span>„{query.trim()}" neu anlegen</span>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ---------- Modal shell ----------
function Modal({ title, eyebrow, size, onClose, children, footer, conflictWarning }) {
  uE(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [onClose]);
  const cls = "modal" + (size ? " " + size : "");
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className={cls} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            {eyebrow && <div className="eyebrow">{eyebrow}</div>}
            <h3>{title}</h3>
          </div>
          <button className="modal-close" onClick={onClose} aria-label="close">×</button>
        </div>
        {conflictWarning && (
          <div className="conflict-pill">
            ⚠ {conflictWarning.by?.name || "Jemand"} hat diesen Eintrag gerade auch geändert.{" "}
            <button className="conflict-reload" onClick={onClose}>Server-Stand laden</button>
          </div>
        )}
        <hr className="modal-rule" />
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-foot">{footer}</div>}
      </div>
    </div>
  );
}

// ---------- Toast ----------
function useToast() {
  const [msg, setMsg] = uS(null);
  uE(() => {
    if (!msg) return;
    const t = setTimeout(() => setMsg(null), 2200);
    return () => clearTimeout(t);
  }, [msg]);
  const node = msg ? <div className="toast">{msg}</div> : null;
  return [node, setMsg];
}

// ---------- Item Editor ----------
function ItemEditor({ item, onSave, onClose, onDelete, conflictWarning, undoOpId, onUndo }) {
  const isNew = !item;
  const [form, setForm] = uS(item ? { ...item } : {
    id: uid(),
    name: "",
    glyph: "",
    color: ITEM_COLOR_PALETTE[0],
    group: "Rohmaterial",
    minStock: 0,
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const submit = () => {
    if (!form.name.trim()) return;
    onSave({
      ...form,
      name: form.name.trim(),
      glyph: (form.glyph.trim() || form.name.slice(0, 2)).toUpperCase().slice(0, 4),
    });
    onClose();
  };

  return (
    <Modal
      title={isNew ? "Neues Item" : "Item bearbeiten"}
      eyebrow={isNew ? "Vorratskammer" : form.group}
      onClose={onClose}
      conflictWarning={conflictWarning}
      footer={
        <React.Fragment>
          {!isNew && (
            <button className="btn ghost" style={{ color: "var(--bad)", borderColor: "var(--bad)" }}
              onClick={() => { onDelete(item.id); onClose(); }}>
              Löschen
            </button>
          )}
          {onUndo && undoOpId && (
            <button className="btn ghost" onClick={() => { onUndo(undoOpId); onClose(); }} title="Letzte eigene Änderung rückgängig">
              ↩ Rückgängig
            </button>
          )}
          <span className="spacer" />
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn" onClick={submit}>{isNew ? "Anlegen" : "Speichern"}</button>
        </React.Fragment>
      }
    >
      <div className="form-row">
        <label>Name</label>
        <input className="form-input" value={form.name}
          onChange={e => set("name", e.target.value)} placeholder="z.B. Bärenfett" />
      </div>
      <div className="form-row">
        <label>Kürzel</label>
        <input className="form-input mono" value={form.glyph} maxLength="4"
          onChange={e => set("glyph", e.target.value.toUpperCase())}
          placeholder="2-4 Zeichen, z.B. BF" />
      </div>
      <div className="form-row">
        <label>Kategorie</label>
        <select className="form-select" value={form.group}
          onChange={e => set("group", e.target.value)}>
          {ITEM_GROUPS.map(g => <option key={g} value={g}>{g}</option>)}
        </select>
      </div>
      <div className="form-row col">
        <label>Farbband</label>
        <div className="form-color-swatches">
          {ITEM_COLOR_PALETTE.map(c => (
            <span key={c}
              className={"swatch" + (c.toLowerCase() === form.color.toLowerCase() ? " on" : "")}
              style={{ background: c }}
              onClick={() => set("color", c)} />
          ))}
          <input type="color" value={form.color}
            onChange={e => set("color", e.target.value)} style={{ marginLeft: 8 }} />
        </div>
      </div>
      <div className="form-row">
        <label>Min. Bestand</label>
        <input className="form-input mono" type="number" min="0" value={form.minStock || 0}
          onChange={e => set("minStock", Math.max(0, parseInt(e.target.value, 10) || 0))}
          style={{ maxWidth: 80 }} title="Warnung wenn Bestand darunter fällt" />
      </div>
      <div className="form-row col">
        <label>Vorschau</label>
        <div style={{
          display: "flex", alignItems: "center", gap: 16, padding: 14,
          background: "var(--paper-light)", border: "1px solid rgba(80,50,20,0.2)"
        }}>
          <div className="inv-icon" style={{ width: 56, height: 56 }}>
            <div style={{ textAlign: "center" }}>
              <div style={{ width: 30, height: 4, background: form.color, margin: "0 auto 3px" }} />
              <div style={{ fontFamily: "IM Fell English SC, serif", fontSize: 14 }}>
                {form.glyph || form.name.slice(0,2).toUpperCase() || "??"}
              </div>
            </div>
          </div>
          <div>
            <div style={{ fontSize: 18 }}>{form.name || "Item-Name"}</div>
            <div style={{ fontFamily: "Special Elite, monospace", fontSize: 11, color: "var(--ink-fade)", letterSpacing: "0.15em" }}>
              {form.group.toUpperCase()}
            </div>
          </div>
        </div>
      </div>
    </Modal>
  );
}

// ---------- Category Editor ----------
function CategoryEditor({ category, onSave, onClose, onDelete }) {
  const isNew = !category;
  const [form, setForm] = uS(category ? { ...category } : {
    id: "cat_" + uid(),
    name: "",
    symbol: "diamond",
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const submit = () => {
    if (!form.name.trim()) return;
    onSave({ ...form, name: form.name.trim() });
    onClose();
  };

  return (
    <Modal
      title={isNew ? "Neue Kategorie" : "Kategorie bearbeiten"}
      eyebrow="Rezeptbuch"
      size="narrow"
      onClose={onClose}
      footer={
        <React.Fragment>
          {!isNew && (
            <button className="btn ghost" style={{ color: "var(--bad)", borderColor: "var(--bad)" }}
              onClick={() => { onDelete(category.id); onClose(); }}>
              Löschen
            </button>
          )}
          <span className="spacer" />
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn" onClick={submit}>{isNew ? "Anlegen" : "Speichern"}</button>
        </React.Fragment>
      }
    >
      <div className="form-row">
        <label>Name</label>
        <input className="form-input" value={form.name}
          onChange={e => set("name", e.target.value)} placeholder="z.B. Schmieden" />
      </div>
      <div className="form-row col">
        <label>Symbol</label>
        <div className="sym-grid">
          {SYMBOLS.map(s => (
            <button key={s} type="button"
              className={form.symbol === s ? "on" : ""}
              onClick={() => set("symbol", s)}>
              <CatSymbol name={s} size={22} />
            </button>
          ))}
        </div>
      </div>
    </Modal>
  );
}

// ---------- Recipe Editor ----------
function RecipeEditor({ recipe, items, categories, onSave, onClose, onDelete, onCreateItem, conflictWarning, undoOpId, onUndo }) {
  const isExisting = !!(recipe && recipe.id && recipe.ingredients);
  const [form, setForm] = uS(isExisting ? { ...recipe, ingredients: [...recipe.ingredients] } : {
    id: "r_" + uid(),
    cat: (recipe && recipe.cat) || categories[0]?.id || "",
    name: "",
    station: "Werkbank",
    time: "1 min",
    out: { item: "", qty: 1 },
    ingredients: [{ item: "", qty: 1 }],
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const updateIng = (idx, patch) => {
    setForm(f => ({ ...f, ingredients: f.ingredients.map((ing, i) => i === idx ? { ...ing, ...patch } : ing) }));
  };
  const removeIng = (idx) => {
    setForm(f => ({ ...f, ingredients: f.ingredients.filter((_, i) => i !== idx) }));
  };
  const addIng = () => {
    setForm(f => ({ ...f, ingredients: [...f.ingredients, { item: "", qty: 1 }] }));
  };

  const submit = () => {
    if (!form.name.trim()) return;
    const validIngs = form.ingredients.filter(ing => ing.item);
    if (validIngs.length === 0 || !form.out.item) return;
    onSave({ ...form, name: form.name.trim(), ingredients: validIngs });
    onClose();
  };

  return (
    <Modal
      title={isExisting ? "Rezept bearbeiten" : "Neues Rezept"}
      eyebrow={categories.find(c => c.id === form.cat)?.name || ""}
      size="wide"
      onClose={onClose}
      conflictWarning={conflictWarning}
      footer={
        <React.Fragment>
          {isExisting && (
            <button className="btn ghost" style={{ color: "var(--bad)", borderColor: "var(--bad)" }}
              onClick={() => { onDelete(recipe.id); onClose(); }}>
              Löschen
            </button>
          )}
          {onUndo && undoOpId && (
            <button className="btn ghost" onClick={() => { onUndo(undoOpId); onClose(); }} title="Letzte eigene Änderung rückgängig">
              ↩ Rückgängig
            </button>
          )}
          <span className="spacer" />
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn" onClick={submit}>{isExisting ? "Speichern" : "Anlegen"}</button>
        </React.Fragment>
      }
    >
      <div className="form-row">
        <label>Bezeichnung</label>
        <input className="form-input" value={form.name}
          onChange={e => set("name", e.target.value)} placeholder="z.B. Bärenfett auslassen" />
      </div>
      <div className="form-row">
        <label>Kategorie</label>
        <select className="form-select" value={form.cat}
          onChange={e => set("cat", e.target.value)}>
          {categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
        </select>
      </div>
      <div className="form-row">
        <label>Station</label>
        <div className="form-grid-2">
          <input className="form-input" value={form.station}
            onChange={e => set("station", e.target.value)} placeholder="z.B. Sattler" />
          <input className="form-input mono" value={form.time}
            onChange={e => set("time", e.target.value)} placeholder="Dauer, z.B. 4 min" />
        </div>
      </div>

      <hr className="modal-rule" style={{ margin: "18px 0" }} />

      <div className="form-row col">
        <label>Ergebnis</label>
        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
          <ItemCombobox
            value={form.out.item}
            items={items}
            onChange={id => set("out", { ...form.out, item: id })}
            onCreateItem={onCreateItem}
            placeholder="Ergebnis-Item…"
          />
          <span style={{ fontFamily: "Special Elite, monospace", fontSize: 11, color: "var(--ink-fade)", letterSpacing: "0.15em", whiteSpace: "nowrap" }}>
            ×
          </span>
          <input className="form-input mono" type="number" min="1"
            value={form.out.qty}
            onChange={e => set("out", { ...form.out, qty: Math.max(1, parseInt(e.target.value) || 1) })}
            style={{ width: 72, flexShrink: 0 }} />
        </div>
      </div>

      <div className="form-row col">
        <label>Zutaten</label>
        {form.ingredients.map((ing, idx) => (
          <div key={idx} className="ing-edit-row">
            <ItemCombobox
              value={ing.item}
              items={items}
              onChange={id => updateIng(idx, { item: id })}
              onCreateItem={onCreateItem}
              placeholder="Zutat suchen oder neu…"
            />
            <input className="form-input mono" type="number" min="1"
              value={ing.qty}
              onChange={e => updateIng(idx, { qty: Math.max(1, parseInt(e.target.value) || 1) })}
              style={{ width: 72, flexShrink: 0 }} />
            <button className="btn-icon" onClick={() => removeIng(idx)} title="entfernen">×</button>
          </div>
        ))}
        <button className="btn-add-row" onClick={addIng}>+ Zutat hinzufügen</button>
      </div>
    </Modal>
  );
}

// ---------- Location Editor ----------
const LOC_TYPES = ["Lager", "Händler", "Jagd", "Sammeln", "Versteck", "Treffpunkt"];

function LocationEditor({ location, onSave, onClose, onDelete, conflictWarning, undoOpId, onUndo }) {
  const isExisting = !!(location && location.id);
  const [form, setForm] = uS(isExisting ? { ...location } : {
    id: "l_" + uid(),
    name: "",
    type: "Lager",
    coords: "",
    desc: "",
    tags: [],
    danger: "sicher",
    x: (location && location.x != null) ? location.x : 50,
    y: (location && location.y != null) ? location.y : 50,
  });
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const [tagInput, setTagInput] = uS("");

  const addTag = () => {
    const t = tagInput.trim();
    if (!t || form.tags.includes(t)) return;
    set("tags", [...form.tags, t]);
    setTagInput("");
  };

  const submit = () => {
    if (!form.name.trim()) return;
    onSave({ ...form, name: form.name.trim(), coords: form.coords.trim(), desc: form.desc.trim() });
    onClose();
  };

  return (
    <Modal
      title={isExisting ? "Ort bearbeiten" : "Neuer Ort"}
      eyebrow={form.type}
      onClose={onClose}
      conflictWarning={conflictWarning}
      footer={
        <React.Fragment>
          {isExisting && (
            <button className="btn ghost" style={{ color: "var(--bad)", borderColor: "var(--bad)" }}
              onClick={() => { onDelete(location.id); onClose(); }}>
              Löschen
            </button>
          )}
          {onUndo && undoOpId && (
            <button className="btn ghost" onClick={() => { onUndo(undoOpId); onClose(); }} title="Letzte eigene Änderung rückgängig">
              ↩ Rückgängig
            </button>
          )}
          <span className="spacer" />
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn" onClick={submit}>{isExisting ? "Speichern" : "Anlegen"}</button>
        </React.Fragment>
      }
    >
      <div className="form-row">
        <label>Name</label>
        <input className="form-input" value={form.name}
          onChange={e => set("name", e.target.value)} placeholder="z.B. Camp am Fluss" />
      </div>
      <div className="form-row">
        <label>Art</label>
        <select className="form-select" value={form.type}
          onChange={e => set("type", e.target.value)}>
          {LOC_TYPES.map(t => <option key={t} value={t}>{t}</option>)}
        </select>
      </div>
      <div className="form-row">
        <label>Region / Koord.</label>
        <input className="form-input mono" value={form.coords}
          onChange={e => set("coords", e.target.value)} placeholder="z.B. Valentine, New Hanover" />
      </div>
      <div className="form-row col">
        <label>Beschreibung</label>
        <textarea className="form-textarea" value={form.desc}
          onChange={e => set("desc", e.target.value)} placeholder="Notizen, Hinweise, Preise…" />
      </div>
      <div className="form-row col">
        <label>Tags</label>
        <div style={{ display: "flex", gap: 8 }}>
          <input className="form-input" value={tagInput}
            onChange={e => setTagInput(e.target.value)}
            onKeyDown={e => { if (e.key === "Enter") { e.preventDefault(); addTag(); } }}
            placeholder="Tag eingeben + Enter" />
          <button className="btn ghost" onClick={addTag}>+</button>
        </div>
        {form.tags.length > 0 && (
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 8 }}>
            {form.tags.map(t => (
              <span key={t} className="loc-tag" style={{ display: "inline-flex", alignItems: "center", gap: 4 }}>
                {t}
                <button onClick={() => set("tags", form.tags.filter(x => x !== t))}
                  style={{ background: "transparent", border: 0, color: "inherit", cursor: "pointer", padding: 0, marginLeft: 4 }}>×</button>
              </span>
            ))}
          </div>
        )}
      </div>
      <div className="form-row col">
        <label>Gefahrenstufe</label>
        <div className="seg">
          <button className={form.danger === "sicher" ? "on danger-ok" : ""}
            onClick={() => set("danger", "sicher")}>Sicher</button>
          <button className={form.danger === "mittel" ? "on danger-mid" : ""}
            onClick={() => set("danger", "mittel")}>Mittel</button>
          <button className={form.danger === "gefährlich" ? "on danger-bad" : ""}
            onClick={() => set("danger", "gefährlich")}>Gefährlich</button>
        </div>
      </div>
      <div className="form-help" style={{ marginTop: 12 }}>
        Tipp: Position auf der Karte per Drag & Drop verschieben oder auf leere Stelle klicken.
      </div>
    </Modal>
  );
}

// ---------- Sync Panel ----------
function SyncPanel({ book, onImport, onClose, toast, syncStatus, syncSeq, syncQueueLength }) {
  const [tab, setTab] = uS("export");
  const [importText, setImportText] = uS("");
  const [importError, setImportError] = uS(null);

  const exportData = {
    items: book.items,
    categories: book.categories,
    recipes: book.recipes,
    locations: book.locations,
    stock: book.stock,
    exportedAt: new Date().toISOString(),
    version: 1,
  };
  const exportJson = JSON.stringify(exportData, null, 2);

  const exportCompact = btoa(unescape(encodeURIComponent(JSON.stringify({
    i: book.items, c: book.categories, r: book.recipes, l: book.locations, s: book.stock
  }))));

  const copy = (text, label) => {
    navigator.clipboard.writeText(text).then(() => toast(label + " kopiert"));
  };

  const download = () => {
    const blob = new Blob([exportJson], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `crafting-buch-${new Date().toISOString().slice(0,10)}.json`;
    a.click();
    URL.revokeObjectURL(url);
    toast("JSON heruntergeladen");
  };

  const onFile = (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = () => {
      setImportText(reader.result);
      setImportError(null);
    };
    reader.readAsText(file);
  };

  const tryImport = (mode) => {
    try {
      let parsed;
      if (mode === "code") {
        const decoded = decodeURIComponent(escape(atob(importText.trim())));
        const compact = JSON.parse(decoded);
        parsed = {
          items: compact.i, categories: compact.c, recipes: compact.r,
          locations: compact.l, stock: compact.s,
        };
      } else {
        parsed = JSON.parse(importText);
      }
      if (!parsed.items || !parsed.recipes) {
        throw new Error("Datei enthält kein gültiges Crafting-Buch.");
      }
      onImport(parsed);
      toast("Buch importiert");
      onClose();
    } catch (e) {
      setImportError(e.message || "Ungültiges Format");
    }
  };

  const stats = {
    items: Object.keys(book.items).length,
    categories: book.categories.length,
    recipes: book.recipes.length,
    locations: book.locations.length,
  };

  return (
    <Modal
      title="Buch teilen"
      eyebrow="Sync"
      size="wide"
      onClose={onClose}
      footer={
        <React.Fragment>
          <span className="spacer" />
          <button className="btn ghost" onClick={onClose}>Schließen</button>
        </React.Fragment>
      }
    >
      <div className="seg" style={{ marginBottom: 18 }}>
        <button className={tab === "export" ? "on" : ""} onClick={() => setTab("export")}>Exportieren</button>
        <button className={tab === "import" ? "on" : ""} onClick={() => setTab("import")}>Importieren</button>
        <button className={tab === "status" ? "on" : ""} onClick={() => setTab("status")}>Status</button>
      </div>

      {tab === "export" && (
        <React.Fragment>
          <div className="sync-meta">
            <div><div className="label">Items</div><div>{stats.items}</div></div>
            <div><div className="label">Rezepte</div><div>{stats.recipes}</div></div>
            <div><div className="label">Kategorien</div><div>{stats.categories}</div></div>
            <div><div className="label">Orte</div><div>{stats.locations}</div></div>
            <div style={{ marginLeft: "auto" }}>
              <div className="label">Stand</div>
              <div>{new Date(book.updatedAt || Date.now()).toLocaleString("de-DE")}</div>
            </div>
          </div>

          <div className="form-row col">
            <label>Share-Code (kompakt)</label>
            <div className="sync-code" style={{ maxHeight: 80 }}>{exportCompact}</div>
            <div style={{ display: "flex", gap: 8, marginTop: 8 }}>
              <button className="btn" onClick={() => copy(exportCompact, "Share-Code")}>Code kopieren</button>
              <div className="form-help" style={{ marginTop: 4, alignSelf: "center" }}>
                Diesen Code kannst du via Discord/WhatsApp an deine Freunde schicken.
              </div>
            </div>
          </div>

          <div className="form-row col" style={{ marginTop: 18 }}>
            <label>Volle JSON-Datei</label>
            <div className="sync-code">{exportJson}</div>
            <div style={{ display: "flex", gap: 8, marginTop: 8 }}>
              <button className="btn ghost" onClick={() => copy(exportJson, "JSON")}>JSON kopieren</button>
              <button className="btn ghost" onClick={download}>Als Datei herunterladen</button>
            </div>
          </div>
        </React.Fragment>
      )}

      {tab === "import" && (
        <React.Fragment>
          <div className="form-row col">
            <label>Share-Code oder JSON einfügen</label>
            <textarea className="form-textarea" style={{ minHeight: 220, fontFamily: "Special Elite, monospace", fontSize: 11 }}
              value={importText}
              onChange={e => { setImportText(e.target.value); setImportError(null); }}
              placeholder="Share-Code oder JSON hier einfügen…" />
          </div>
          <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
            <button className="btn" onClick={() => tryImport("code")}
              disabled={!importText.trim()}>Code importieren</button>
            <button className="btn ghost" onClick={() => tryImport("json")}
              disabled={!importText.trim()}>JSON importieren</button>
            <label className="btn ghost" style={{ cursor: "pointer", margin: 0 }}>
              Datei wählen…
              <input type="file" accept=".json,application/json" style={{ display: "none" }}
                onChange={onFile} />
            </label>
          </div>
          {importError && (
            <div style={{ marginTop: 12, padding: 10, background: "var(--bad-bg)",
              border: "1px solid var(--bad)", color: "var(--bad)",
              fontFamily: "Special Elite, monospace", fontSize: 12 }}>
              {importError}
            </div>
          )}
          <div className="form-help" style={{ marginTop: 14 }}>
            ⚠ Beim Import wird dein aktuelles Buch ersetzt. Vorher ggf. exportieren.
          </div>
        </React.Fragment>
      )}

      {tab === "status" && (
        <React.Fragment>
          <div className="sync-meta">
            <div>
              <div className="label">Verbindung</div>
              <div style={{ textTransform: "uppercase", letterSpacing: "0.1em", fontSize: 13 }}>
                {syncStatus === "connected" ? "● Live" : syncStatus === "reconnecting" ? "◌ Verbinde…" : "○ Offline"}
              </div>
            </div>
            <div>
              <div className="label">Letzte Seq.</div>
              <div>{syncSeq || "—"}</div>
            </div>
            <div>
              <div className="label">Warteschlange</div>
              <div>{syncQueueLength || 0} Op(s)</div>
            </div>
            <div style={{ marginLeft: "auto" }}>
              <div className="label">Server</div>
              <div style={{ fontFamily: "Special Elite, monospace", fontSize: 11 }}>{window.location.host}</div>
            </div>
          </div>

          <div className="form-row" style={{ marginTop: 18 }}>
            <label>Manuell neu syncen</label>
            <button className="btn ghost" onClick={() => {
              fetch("/book").then(r => r.json()).then(d => {
                if (d?.book) {
                  toast("Buch neu geladen");
                  onClose();
                }
              }).catch(() => toast("Fehler beim Laden"));
            }}>
              Neu laden
            </button>
          </div>
          <div className="form-help" style={{ marginTop: 14 }}>
            Live-Sync läuft über WebSocket. Bei Verbindungsabbruch werden Aktionen lokal gepuffert
            und beim nächsten Verbinden automatisch abgeschickt.
          </div>
        </React.Fragment>
      )}
    </Modal>
  );
}

// Expose to window for use in app.jsx
Object.assign(window, {
  Modal, ItemEditor, CategoryEditor, RecipeEditor, LocationEditor,
  SyncPanel, useToast, uid, ITEM_GROUPS, SYMBOLS,
});
