/* ========================================================================
   LUMINA — Sticky Notes overlay
   Self-mounting · draggable · per-note panel anchors · list/single view
   ======================================================================== */
(function () {
  const { useState, useEffect, useRef } = React;
  const STORE = "lumina_sticky_notes_v1";
  const NOTE_COLORS = ["#ffd84a", "#ff9a3a", "#ff5ad6", "#4be6ff", "#7cff4f", "#b785ff"];
  const ANCHORS = [
    { id: "any",         label: "Anywhere (always visible)" },
    { id: "stage",       label: "Stage" },
    { id: "composition", label: "Live Loops" },
    { id: "slideshow",   label: "Slideshow" },
    { id: "scene3d",     label: "3D Scene" },
    { id: "text",        label: "Boards" },
    { id: "mapping",     label: "Output Map" },
    { id: "nodes",       label: "Nodes" },
    { id: "generative",  label: "Generative" },
  ];

  function loadNotes() {
    try { return JSON.parse(localStorage.getItem(STORE) || "[]"); }
    catch (e) { return []; }
  }
  function saveNotes(n) { localStorage.setItem(STORE, JSON.stringify(n)); }

  // Detect current workspace by looking at WorkspaceTabs active button
  function currentWorkspace() {
    const tabs = document.querySelectorAll(".stage .nbtn");
    for (const t of tabs) {
      const bg = getComputedStyle(t).backgroundImage;
      if (bg.includes("radial-gradient") && bg.includes("c87016")) {
        const label = t.textContent.trim().toLowerCase();
        const m = ANCHORS.find(a => label.includes(a.label.toLowerCase().split(" ")[0]));
        if (m) return m.id;
      }
    }
    return null;
  }

  function StickyNotes() {
    const [notes, setNotes] = useState(loadNotes());
    const [open, setOpen] = useState(false);
    const [mode, setMode] = useState("single"); // single | list | hidden
    const [activeIdx, setActiveIdx] = useState(0);
    const [editingId, setEditingId] = useState(null);
    const [workspace, setWorkspace] = useState(null);

    useEffect(() => { saveNotes(notes); }, [notes]);

    // Track current workspace
    useEffect(() => {
      const upd = () => setWorkspace(currentWorkspace());
      const id = setInterval(upd, 600);
      return () => clearInterval(id);
    }, []);

    const visibleNotes = notes.filter(n => !n.archived &&
      (n.anchor === "any" || n.anchor === workspace));

    const addNote = () => {
      const id = "n" + Date.now();
      const n = {
        id, text: "", color: NOTE_COLORS[notes.length % NOTE_COLORS.length],
        x: 100 + Math.random() * 200, y: 100 + Math.random() * 80,
        w: 220, h: 160, anchor: workspace || "any", archived: false,
      };
      setNotes(arr => [...arr, n]);
      setEditingId(id);
      setActiveIdx(visibleNotes.length); // newly added
      setMode("single");
    };
    const updNote = (id, patch) =>
      setNotes(arr => arr.map(n => n.id === id ? { ...n, ...patch } : n));
    const delNote = (id) => setNotes(arr => arr.filter(n => n.id !== id));

    return (
      <>
        {/* Toggle button (always visible bottom-left under playlist) */}
        <button
          onClick={() => setOpen(o => !o)}
          style={{
            position: "fixed", left: 18, bottom: 170, zIndex: 593,
            padding: "10px 14px", border: "none", borderRadius: 8,
            background: visibleNotes.length
              ? "linear-gradient(180deg, #ffd84a, #b8860b)"
              : "linear-gradient(180deg, var(--panel-hi), var(--panel))",
            color: visibleNotes.length ? "#1a0a02" : "var(--ink-dim)",
            fontFamily: "var(--font-display)", fontWeight: 800, fontSize: 11,
            letterSpacing: "0.18em", textTransform: "uppercase",
            cursor: "pointer",
            boxShadow: visibleNotes.length
              ? "inset 0 1px 0 rgba(255,255,255,0.4), 0 0 14px rgba(255,216,74,0.5)"
              : "var(--nshadow-out-sm)",
            display: "flex", alignItems: "center", gap: 8,
          }}>
          📝 Notes {visibleNotes.length ? `· ${visibleNotes.length}` : ""}
        </button>

        {/* Panel with controls */}
        {open && (
          <ControlPanel
            count={notes.length} visibleCount={visibleNotes.length} mode={mode}
            workspace={workspace}
            onAdd={addNote} onMode={setMode} onClose={() => setOpen(false)}
            onCycle={(dir) => setActiveIdx(i => (i + dir + visibleNotes.length) % Math.max(1, visibleNotes.length))}
            activeIdx={activeIdx}
          />
        )}

        {/* Notes display */}
        {mode !== "hidden" && visibleNotes.map((n, i) => {
          if (mode === "single" && i !== activeIdx % visibleNotes.length) return null;
          return (
            <Sticky key={n.id} note={n} editing={editingId === n.id}
              onUpd={(patch) => updNote(n.id, patch)}
              onEdit={() => setEditingId(n.id)}
              onBlur={() => setEditingId(null)}
              onDel={() => delNote(n.id)} />
          );
        })}
      </>
    );
  }

  function ControlPanel({ count, visibleCount, mode, workspace, onAdd, onMode, onClose, onCycle, activeIdx }) {
    return (
      <div style={{
        position: "fixed", left: 200, bottom: 170, zIndex: 594,
        background: "linear-gradient(180deg, var(--panel-hi), var(--panel-lo))",
        borderRadius: 8, padding: 10,
        boxShadow: "0 20px 50px rgba(0,0,0,0.7), 0 0 0 1px rgba(255,216,74,0.3)",
        minWidth: 260,
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
          <span style={{
            fontFamily: "var(--font-display)", fontWeight: 800, fontSize: 11,
            letterSpacing: "0.18em", textTransform: "uppercase", color: "#ffd84a",
            textShadow: "0 0 4px #b8860b",
            flex: 1,
          }}>📝 Sticky Notes</span>
          <button data-lum-close="1" className="nbtn compact" onClick={onClose} style={{ padding: "2px 7px" }}>×</button>
        </div>
        <div className="cap" style={{ marginBottom: 4 }}>
          {visibleCount} of {count} · here {workspace ? `(${workspace})` : ""}
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 4, marginBottom: 8 }}>
          <button className={`nbtn compact ${mode === "single" ? "glow pressed" : ""}`}
            style={{ padding: "5px", fontSize: 9 }}
            onClick={() => onMode("single")}>One at a time</button>
          <button className={`nbtn compact ${mode === "list" ? "glow pressed" : ""}`}
            style={{ padding: "5px", fontSize: 9 }}
            onClick={() => onMode("list")}>Show all</button>
          <button className={`nbtn compact ${mode === "hidden" ? "glow pressed" : ""}`}
            style={{ padding: "5px", fontSize: 9 }}
            onClick={() => onMode("hidden")}>Hide</button>
        </div>
        {mode === "single" && visibleCount > 1 && (
          <div style={{ display: "flex", gap: 4, marginBottom: 8 }}>
            <button className="nbtn compact" style={{ flex: 1, padding: "4px", fontSize: 9 }}
              onClick={() => onCycle(-1)}>◀ Prev</button>
            <span style={{
              flex: 1, textAlign: "center",
              fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--accent)",
              padding: "5px",
            }}>{(activeIdx % visibleCount) + 1} / {visibleCount}</span>
            <button className="nbtn compact" style={{ flex: 1, padding: "4px", fontSize: 9 }}
              onClick={() => onCycle(1)}>Next ▶</button>
          </div>
        )}
        <button className="nbtn glow pressed" onClick={onAdd}
          style={{ width: "100%", padding: "8px", fontWeight: 700 }}>
          + Add Note {workspace ? `→ ${workspace}` : ""}
        </button>
      </div>
    );
  }

  function Sticky({ note, editing, onUpd, onEdit, onBlur, onDel }) {
    const ref = useRef(null);
    const taRef = useRef(null);

    useEffect(() => {
      if (editing && taRef.current) taRef.current.focus();
    }, [editing]);

    const startDrag = (e) => {
      if (["BUTTON", "TEXTAREA", "INPUT", "SELECT"].includes(e.target.tagName)) return;
      const start = { x: e.clientX, y: e.clientY };
      const sp = { x: note.x, y: note.y };
      const onMove = (m) => onUpd({ x: sp.x + (m.clientX - start.x), y: sp.y + (m.clientY - start.y) });
      const onUp = () => { window.removeEventListener("mousemove", onMove); window.removeEventListener("mouseup", onUp); };
      window.addEventListener("mousemove", onMove);
      window.addEventListener("mouseup", onUp);
    };
    const startResize = (e) => {
      e.stopPropagation();
      const start = { x: e.clientX, y: e.clientY };
      const ss = { w: note.w, h: note.h };
      const onMove = (m) => onUpd({ w: Math.max(160, ss.w + (m.clientX - start.x)), h: Math.max(100, ss.h + (m.clientY - start.y)) });
      const onUp = () => { window.removeEventListener("mousemove", onMove); window.removeEventListener("mouseup", onUp); };
      window.addEventListener("mousemove", onMove);
      window.addEventListener("mouseup", onUp);
    };

    return (
      <div ref={ref}
        style={{
          position: "fixed", left: note.x, top: note.y,
          width: note.w, minHeight: note.h, zIndex: 592,
          background: `linear-gradient(160deg, ${note.color}, ${note.color}cc)`,
          color: "#1a0a02",
          borderRadius: 4,
          boxShadow: `0 8px 24px rgba(0,0,0,0.5), 0 2px 0 rgba(0,0,0,0.2), 0 0 0 1px rgba(0,0,0,0.15) inset`,
          fontFamily: "Caveat, 'Comic Sans MS', cursive, sans-serif",
          transform: "rotate(-0.4deg)",
          display: "flex", flexDirection: "column",
        }}>
        {/* Header */}
        <div onMouseDown={startDrag} style={{
          padding: "5px 8px", display: "flex", alignItems: "center", gap: 6,
          cursor: "move", userSelect: "none",
          borderBottom: "1px solid rgba(0,0,0,0.1)",
        }}>
          <span style={{ fontSize: 11, opacity: 0.7 }}>📌</span>
          <select value={note.anchor} onChange={e => onUpd({ anchor: e.target.value })}
            style={{
              flex: 1, background: "transparent", border: "none", outline: "none",
              color: "rgba(0,0,0,0.7)", fontFamily: "var(--font-mono)", fontSize: 9,
              padding: 0, cursor: "pointer",
            }}>
            {ANCHORS.map(a => <option key={a.id} value={a.id}>{a.label}</option>)}
          </select>
          <input type="color" value={note.color}
            onChange={e => onUpd({ color: e.target.value })}
            style={{ width: 18, height: 14, border: "none", background: "transparent", padding: 0, cursor: "pointer" }} />
          <button onClick={onDel}
            style={{
              border: "none", background: "transparent", cursor: "pointer",
              color: "rgba(0,0,0,0.6)", padding: 0, fontSize: 13, lineHeight: 1,
            }}>×</button>
        </div>
        {/* Body */}
        {editing ? (
          <textarea ref={taRef}
            value={note.text}
            onChange={e => onUpd({ text: e.target.value })}
            onBlur={onBlur}
            placeholder="Type your note..."
            style={{
              flex: 1, padding: "10px 12px",
              background: "transparent", border: "none", outline: "none",
              color: "#1a0a02", resize: "none",
              fontFamily: "Caveat, 'Comic Sans MS', cursive, sans-serif",
              fontSize: 18, lineHeight: 1.4,
            }} />
        ) : (
          <div onClick={onEdit}
            style={{
              flex: 1, padding: "10px 12px",
              fontSize: 18, lineHeight: 1.4,
              cursor: "text",
              whiteSpace: "pre-wrap", wordWrap: "break-word",
              opacity: note.text ? 1 : 0.5,
            }}>
            {note.text || "Click to edit…"}
          </div>
        )}
        {/* Resize handle */}
        <div onMouseDown={startResize}
          style={{
            position: "absolute", right: 0, bottom: 0,
            width: 14, height: 14, cursor: "nwse-resize",
            background: "linear-gradient(135deg, transparent 50%, rgba(0,0,0,0.2) 50%)",
          }} />
      </div>
    );
  }

  function mount() {
    if (!window.React || !window.ReactDOM) { setTimeout(mount, 100); return; }
    let host = document.getElementById("__sticky_notes_panel");
    if (!host) {
      host = document.createElement("div");
      host.id = "__sticky_notes_panel";
      document.body.appendChild(host);
    }
    // Load Caveat font for handwritten feel
    if (!document.getElementById("__caveat_font")) {
      const l = document.createElement("link");
      l.id = "__caveat_font"; l.rel = "stylesheet";
      l.href = "https://fonts.googleapis.com/css2?family=Caveat:wght@500;700&display=swap";
      document.head.appendChild(l);
    }
    ReactDOM.createRoot(host).render(<StickyNotes />);
  }
  if (document.readyState === "complete" || document.readyState === "interactive") setTimeout(mount, 1000);
  else document.addEventListener("DOMContentLoaded", () => setTimeout(mount, 1000));
})();
