/* ═══════════════════════════════════════════════════════════
   Orrery — shared interaction layer:
   • saves store (localStorage)         • useWheelScroll (frees scroll from the canvas)
   • CardDetail sheet (pills + paragraphs + save)   • Favorites panel
   • useCardUI() hook + SavesButton      • buildCard / buildPlanetCard
   Loaded after the wheel, before the takes.
═══════════════════════════════════════════════════════════ */

/* ── saves store ──────────────────────────────────────── */
const SAVE_KEY = 'ct-orrery-saves';
function loadSaves() { try { return JSON.parse(localStorage.getItem(SAVE_KEY) || '[]'); } catch (e) { return []; } }
let _saves = loadSaves();
const _subs = new Set();
function persistSaves() { try { localStorage.setItem(SAVE_KEY, JSON.stringify(_saves)); } catch (e) {} }
function toggleSave(card) {
  _saves = _saves.some((c) => c.id === card.id) ? _saves.filter((c) => c.id !== card.id) : [..._saves, card];
  persistSaves(); _subs.forEach((fn) => fn(_saves));
}
function useSaves() {
  const [s, setS] = React.useState(_saves);
  React.useEffect(() => { const fn = (v) => setS(v); _subs.add(fn); setS(_saves); return () => { _subs.delete(fn); }; }, []);
  return s;
}

/* ── free a scroll container from the design-canvas wheel capture ── */
function useWheelScroll(horizontal) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const onWheel = (e) => {
      e.stopPropagation();                 // keep the canvas from zooming/panning
      if (horizontal) {
        if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) { el.scrollLeft += e.deltaY; e.preventDefault(); }
      }
    };
    el.addEventListener('wheel', onWheel, { passive: !horizontal });
    return () => el.removeEventListener('wheel', onWheel);
  }, [horizontal]);
  return ref;
}

/* ── card builders ────────────────────────────────────── */
const SIGN_NAMES = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'];
function planetPosition(p) { const s = Math.floor(p.lon / 30) % 12; const d = Math.round(p.lon % 30); return d + '\u00b0 ' + SIGN_NAMES[s] + (p.retro ? '  \u00b7 \u211E retrograde' : ''); }
function buildCard(level, row, i) {
  return { kind: 'reading', id: level.id + ':' + i, horizon: level.scale, title: row.label, time: row.time,
    icon: row.icon, lens: row.lens, topics: row.topics || [], body: row.body || [row.text] };
}
function buildPlanetCard(key) {
  const p = window.ORRERY.planets[key];
  return { kind: 'planet', id: 'planet:' + key, horizon: 'Planet', title: p.title || p.name, time: planetPosition(p),
    icon: p.sym, topics: p.keywords || [], body: p.body || [] };
}
function buildHorizonCard(level) {
  return { kind: 'horizon', id: 'horizon:' + level.id, horizon: level.scale, title: level.span, time: level.when,
    icon: level.ruler, topics: (level.rows || []).map((r) => r.label), body: [level.gloss, ...(level.rows || []).map((r) => r.label + ' — ' + r.text)] };
}

/* ── one-tap save/favorite toggle (sits on any card) ──── */
function SaveToggle({ card, label }) {
  const saves = useSaves();
  const saved = saves.some((c) => c.id === card.id);
  return (
    <button className={'ork-bm' + (saved ? ' on' : '')} title={saved ? 'Remove from favorites' : 'Save to favorites'}
      aria-label={saved ? 'Remove from favorites' : 'Save to favorites'}
      onClick={(e) => { e.stopPropagation(); toggleSave(card); }}>
      <svg viewBox="0 0 14 14" fill={saved ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="1.4"><path d="M3 1.6h8v10.8L7 9.4l-4 3z" strokeLinejoin="round" /></svg>
      {label && <span>{saved ? 'Saved' : 'Save'}</span>}
    </button>
  );
}

function CIcon({ id, cls }) { return <svg className={cls} viewBox="0 0 16 16" style={{ overflow: 'visible' }} aria-hidden="true"><use href={'#' + id} /></svg>; }

/* ── detail card (floats over the dimmed artboard) ────── */
const BackArrow = () => (<svg viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M8.5 2.5 4 7l4.5 4.5" /></svg>);

function CardDetail({ card, onClose }) {
  const saves = useSaves();
  const saved = saves.some((c) => c.id === card.id);
  const bodyRef = useWheelScroll(false);
  return (
    <div className="ork-ov ork-ovfade" onClick={onClose}>
      <div className="ork-ov-card" onClick={(e) => e.stopPropagation()}>
        <div className="ork-ov-top">
          <button className="ork-ov-back" onClick={onClose}><BackArrow /> Back</button>
          <span className="ork-ov-kick">{card.kind === 'planet' ? 'Planet \u00b7 in context' : card.horizon}</span>
        </div>
        <div className="ork-ov-body" ref={bodyRef}>
          <div className="ork-ov-titlewrap">
            <span className={'ork-ov-icn' + (card.kind === 'planet' ? ' big' : '')}><CIcon id={card.icon} /></span>
            <h3 className="ork-ov-title">{card.title}</h3>
          </div>
          {card.time && card.time !== '\u2014' && <div className="ork-ov-time">{card.time}</div>}
          {card.topics.length > 0 && (
            <div className="ork-ov-pills">{card.topics.map((t) => <span key={t} className="ork-pill">{t}</span>)}</div>
          )}
          {card.body.map((p, i) => <p key={i} className="ork-ov-p">{p}</p>)}
        </div>
        <div className="ork-ov-foot">
          <button className={'ork-save' + (saved ? ' on' : '')} onClick={() => toggleSave(card)}>
            <svg viewBox="0 0 14 14" fill={saved ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="1.4"><path d="M3 1.6h8v10.8L7 9.4l-4 3z" strokeLinejoin="round" /></svg>
            {saved ? 'Saved to favorites' : 'Save to favorites'}
          </button>
          <button className="ork-ov-dismiss" onClick={onClose}>Back to wheel</button>
        </div>
      </div>
    </div>
  );
}

/* ── favorites panel (floats over the dimmed artboard) ── */
function SavesPanel({ onOpen, onClose }) {
  const saves = useSaves();
  const bodyRef = useWheelScroll(false);
  return (
    <div className="ork-ov ork-ovfade" onClick={onClose}>
      <div className="ork-ov-card" onClick={(e) => e.stopPropagation()}>
        <div className="ork-ov-top">
          <button className="ork-ov-back" onClick={onClose}><BackArrow /> Back</button>
          <span className="ork-ov-kick">★ Favorites · {saves.length}</span>
        </div>
        <div className="ork-ov-body" ref={bodyRef}>
          {saves.length === 0 && <div className="ork-saves-empty">No saved cards yet. Open any reading or planet and tap <b>Save to favorites</b> — they’ll collect here for you.</div>}
          <div className="ork-saves-list">
            {saves.map((c) => (
              <div key={c.id} className="ork-savecard">
                <button className="ork-savecard-main" onClick={() => onOpen(c)}>
                  <span className="ork-savecard-icn"><CIcon id={c.icon} /></span>
                  <span className="ork-savecard-tt">
                    <span className="ork-savecard-h">{c.kind === 'planet' ? 'Planet' : c.horizon}</span>
                    <span className="ork-savecard-l">{c.title}</span>
                  </span>
                </button>
                <button className="ork-savecard-x" onClick={() => toggleSave(c)} aria-label="Remove">Remove</button>
              </div>
            ))}
          </div>
        </div>
        <div className="ork-ov-foot">
          <button className="ork-ov-dismiss" onClick={onClose}>Back to wheel</button>
        </div>
      </div>
    </div>
  );
}

function SavesButton({ onClick }) {
  const saves = useSaves();
  return (
    <button className="ork-saves-btn" onClick={onClick}>
      <svg viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.4"><path d="M3 1.6h8v10.8L7 9.4l-4 3z" strokeLinejoin="round" /></svg>
      Favorites{saves.length ? ' \u00b7 ' + saves.length : ''}
    </button>
  );
}

/* ── per-take controller ──────────────────────────────── */
function useCardUI() {
  const [card, setCard] = React.useState(null);
  const [showSaves, setShowSaves] = React.useState(false);
  const open = (c) => { setShowSaves(false); setCard(c); };
  const openPlanet = (key) => open(buildPlanetCard(key));
  const openSaves = () => { setCard(null); setShowSaves(true); };
  const close = () => { setCard(null); setShowSaves(false); };
  const node = (
    <React.Fragment>
      {card && <CardDetail card={card} onClose={close} />}
      {showSaves && <SavesPanel onOpen={open} onClose={close} />}
    </React.Fragment>
  );
  return { open, openPlanet, openSaves, close, node, savesBtn: <SavesButton onClick={openSaves} /> };
}

Object.assign(window, { useSaves, useWheelScroll, buildCard, buildPlanetCard, buildHorizonCard, SaveToggle, CardDetail, SavesPanel, SavesButton, useCardUI, CIcon });
