// ============================================================
// Shared components — sidebar, search, DM toggle, modals, editable text
// ============================================================

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

// -------- editable text wrapper --------
function Editable({ as: Tag = "span", path, className, children, multiline = false, placeholder }) {
  const dmMode = window.useDM ? window.useDM() : false;
  const [val, setVal] = useState(() => {
    const stored = localStorage.getItem("hc:edit:" + path);
    return stored !== null ? stored : children;
  });

  useEffect(() => {
    const stored = localStorage.getItem("hc:edit:" + path);
    if (stored === null) setVal(children);
  }, [children, path]);

  const ref = useRef(null);

  const onBlur = (e) => {
    const text = multiline ? e.target.innerText : e.target.innerText;
    setVal(text);
    if (text === children) localStorage.removeItem("hc:edit:" + path);
    else localStorage.setItem("hc:edit:" + path, text);
  };

  return (
    <Tag
      ref={ref}
      className={className}
      contentEditable={dmMode}
      suppressContentEditableWarning
      data-edit-path={path}
      onBlur={onBlur}
      style={{ whiteSpace: multiline ? "pre-wrap" : undefined }}
    >
      {val}
    </Tag>
  );
}

// -------- sidebar nav --------
const NAV_SECTIONS = [
  {
    label: "The campaign",
    items: [
      { id: "story", glyph: "❦", name: "Current Story" },
      { id: "sessions", glyph: "✸", name: "Session Recaps" },
    ],
  },
  {
    label: "The world",
    items: [
      { id: "world", glyph: "✧", name: "World of Thoria" },
      { id: "map", glyph: "✦", name: "Map" },
      { id: "locations", glyph: "⬢", name: "Locations" },
      { id: "factions", glyph: "✜", name: "Factions" },
    ],
  },
  {
    label: "The people",
    items: [
      { id: "pcs", glyph: "♛", name: "Player Characters" },
      { id: "npcs", glyph: "♟", name: "Non-Player Characters" },
    ],
  },
  {
    label: "The compendium",
    items: [
      { id: "bestiary", glyph: "✺", name: "Bestiary" },
      { id: "items", glyph: "◈", name: "Items & Artifacts" },
      { id: "rules", glyph: "§", name: "House Rules" },
    ],
  },
];

function Sidebar({ page, setPage, search, setSearch, searchOpen, setSearchOpen, searchResults }) {
  const inputRef = useRef(null);

  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-mark">The Hollow <em>Crown</em></div>
        <div className="brand-sub">A Thoria campaign wiki — session {window.CAMPAIGN.session}</div>
      </div>

      <div className="search">
        <span className="search-icon">⌕</span>
        <input
          ref={inputRef}
          type="text"
          placeholder="Search the wiki…"
          value={search}
          onFocus={() => setSearchOpen(true)}
          onChange={(e) => { setSearch(e.target.value); setSearchOpen(true); }}
          onBlur={() => setTimeout(() => setSearchOpen(false), 200)}
        />
        {searchOpen && search && (
          <div className="search-results">
            {searchResults.length === 0 ? (
              <div className="sr-empty">No matches in the records.</div>
            ) : (
              searchResults.map((r, i) => (
                <div
                  key={i}
                  className="search-result"
                  onMouseDown={() => { setPage(r.page); setSearch(""); setSearchOpen(false); }}
                >
                  <div className="sr-kind">{r.kind}</div>
                  <div className="sr-name">{r.name}</div>
                  <div className="sr-snippet">{r.snippet}</div>
                </div>
              ))
            )}
          </div>
        )}
      </div>

      {NAV_SECTIONS.map((sec) => (
        <div className="nav-section" key={sec.label}>
          <div className="nav-label">{sec.label}</div>
          {sec.items.map((it) => (
            <div
              key={it.id}
              className={"nav-item" + (page === it.id ? " active" : "")}
              onClick={() => setPage(it.id)}
            >
              <span className="nav-glyph">{it.glyph}</span>
              <span>{it.name}</span>
            </div>
          ))}
        </div>
      ))}
    </aside>
  );
}

// -------- DM password modal --------
function PasswordModal({ onSubmit, onClose, expected }) {
  const [val, setVal] = useState("");
  const [err, setErr] = useState("");
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  const submit = () => {
    if (val === expected) {
      onSubmit();
    } else {
      setErr("The moon does not know that word.");
      setVal("");
      inputRef.current?.focus();
    }
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="pwd-modal" onClick={(e) => e.stopPropagation()}>
        <div className="moon-emblem"></div>
        <h3>The Doubling</h3>
        <p className="hint">Speak the word, and see beyond the page.</p>
        <input
          ref={inputRef}
          type="password"
          value={val}
          onChange={(e) => { setVal(e.target.value); setErr(""); }}
          onKeyDown={(e) => e.key === "Enter" && submit()}
          placeholder="········"
        />
        <div className="pwd-err">{err}</div>
        <div className="pwd-actions">
          <button onClick={onClose}>Cancel</button>
          <button className="primary" onClick={submit}>Reveal</button>
        </div>
      </div>
    </div>
  );
}

// -------- DM-only inline block --------
function DMBlock({ title, children }) {
  return (
    <div className="dm-only">
      <div className="dm-block">
        {title && <h4>{title}</h4>}
        {children}
      </div>
    </div>
  );
}

// -------- Generic modal --------
function Modal({ onClose, children }) {
  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onClose]);

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={(e) => e.stopPropagation()}>
        <button className="modal-close" onClick={onClose}>×</button>
        {children}
      </div>
    </div>
  );
}

// -------- DM mode context --------
const DMContext = React.createContext(false);
window.useDM = () => React.useContext(DMContext);

// Expose
Object.assign(window, { Editable, Sidebar, PasswordModal, DMBlock, Modal, DMContext, NAV_SECTIONS });
