// Cedar Hills · Lyric collection · sign components
// Direction E — gallery-modern. Oversized swashy script as the hero,
// tracked uppercase sans support, lots of negative space.
//
// Shared utilities (PALETTES, E, Removable, signVars, useGuestList,
// useTableNumber, QRUploader) live in collection-shell.jsx + seating.jsx.

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

// ─────────── ScriptHero — script word with horizontal lines extending out ───────────
// The signature Lyric move: a thin horizontal line enters from the left edge,
// meets the script word at its x-height middle, the word flows, and another
// line continues out from the word to the right edge. The script word is
// sized as a portion of the available width so the lines have room to extend.
// Edit the word inline — auto-resizes and the lines flow with it.
function ScriptHero({ defaultText, max = 260, scale = 0.65 }) {
  const ref = useRef(null);

  const fit = useCallback(() => {
    const el = ref.current;
    if (!el) return;
    const wrap = el.closest('.sign-e__hero-wrap');
    if (!wrap) return;
    const totalW = wrap.clientWidth;
    if (!totalW) return;
    // Script word takes `scale` of available width; lines flex-fill the rest.
    const targetW = totalW * scale;
    // Measure natural width at a reference size, then compute fit size.
    el.style.fontSize = '100px';
    const natW = el.scrollWidth;
    if (!natW) return;
    const fitSize = Math.min(max, Math.floor((targetW / natW) * 100));
    el.style.fontSize = fitSize + 'px';
    // Expose the size so the line's vertical position can scale with it.
    wrap.style.setProperty('--hero-size', fitSize + 'px');
  }, [max, scale]);

  useLayoutEffect(() => {
    fit();
    // Refit after Mrs Saint Delafield finishes loading (was likely fallback at first paint)
    if (document.fonts?.ready) document.fonts.ready.then(() => requestAnimationFrame(fit));
  }, [fit]);

  return (
    <div className="sign-e__hero-wrap">
      <span className="sign-e__hero-line" aria-hidden="true" />
      <div
        ref={ref}
        className="sign-e__hero"
        contentEditable
        suppressContentEditableWarning
        onInput={fit}
        spellCheck={false}
      >
        {defaultText}
      </div>
      <span className="sign-e__hero-line" aria-hidden="true" />
    </div>
  );
}
function LyricFoot({ namesA = 'MARGARET', namesB = 'DANIEL', date = 'May 16, 2026' }) {
  return (
    <div className="sign-e__foot">
      <div className="sign-e__names">
        <E>{namesA}</E> <span className="sign-e__and">&amp;</span> <E>{namesB}</E>
      </div>
      <div className="sign-e__foot-date"><E>{date}</E></div>
    </div>
  );
}

// ─────────── WELCOME · 18×24″ poster ───────────
function WelcomeSign({ p, w = 540, h = 720 }) {
  const [shown, setShown] = useState({ eyebrow: true, foot: true });
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));

  return (
    <div className="sign sign--e sign--l-welcome" style={signVars(p, w, h)}>
      <div className="sign__inner">
        {shown.eyebrow && (
          <Removable onRemove={() => hide('eyebrow')}>
            <div className="sign-e__eyebrow">
              <div><E>WELCOME TO</E></div>
              <div><E>THE WEDDING OF</E></div>
            </div>
          </Removable>
        )}
        <ScriptHero defaultText="welcome" max={260} />
        {shown.foot && (
          <Removable onRemove={() => hide('foot')}>
            <LyricFoot />
          </Removable>
        )}
      </div>
    </div>
  );
}

// ─────────── BAR · 18×24″ poster ───────────
const DEFAULT_BAR_ITEMS = [
  { id: 'm', name: 'THE MARGARET', desc: 'gin · cucumber · elderflower · mint' },
  { id: 'd', name: 'THE DANIEL',   desc: 'rye · maple · orange bitters' },
  { id: 'w', name: 'WINE & BUBBLY', desc: 'cabernet · sauvignon blanc · prosecco' },
  { id: 'b', name: 'BEER & SOFT',   desc: 'pilsner · IPA · seltzer · lemonade' },
];

function BarSign({ p, w = 540, h = 720 }) {
  const [shown, setShown] = useState({ eyebrow: true, foot: true });
  const [items, setItems] = useState(DEFAULT_BAR_ITEMS);
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));
  const removeItem = (id) => setItems((arr) => arr.filter((it) => it.id !== id));
  const addItem = () => setItems((arr) => [
    ...arr,
    { id: 'x' + Date.now(), name: 'NEW POUR', desc: 'ingredients here' },
  ]);

  return (
    <div className="sign sign--e sign--l-bar" style={signVars(p, w, h)}>
      <div className="sign__inner">
        {shown.eyebrow && (
          <Removable onRemove={() => hide('eyebrow')}>
            <div className="sign-e__eyebrow">
              <div><E>HELP YOURSELF</E></div>
              <div><E>FROM THE BAR</E></div>
            </div>
          </Removable>
        )}
        <ScriptHero defaultText="cheers" max={260} />
        <div className="bar-menu bar-menu--lyric">
          {items.map((it) => (
            <div key={it.id} className="bar-item">
              <div className="bar-item__name"><E>{it.name}</E></div>
              <div className="bar-item__desc"><E>{it.desc}</E></div>
              <button type="button" className="bar-item__x" onClick={() => removeItem(it.id)} aria-label="Remove this drink" title="Remove this drink">
                <span aria-hidden="true">×</span>
              </button>
            </div>
          ))}
          <button type="button" className="bar-menu__add" onClick={addItem}>+ Add a drink</button>
        </div>
        {shown.foot && (
          <Removable onRemove={() => hide('foot')}>
            <LyricFoot />
          </Removable>
        )}
      </div>
    </div>
  );
}

// ─────────── CARDS & GIFTS · 8×10″ framed ───────────
function CardsSign({ p, w = 400, h = 500 }) {
  const [shown, setShown] = useState({ eyebrow: true, foot: true });
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));

  return (
    <div className="sign sign--e sign--l-small sign--l-cards" style={signVars(p, w, h)}>
      <div className="sign__inner">
        {shown.eyebrow && (
          <Removable onRemove={() => hide('eyebrow')}>
            <div className="sign-e__eyebrow">
              <div><E>LEAVE A NOTE</E></div>
              <div><E>FOR THE COUPLE</E></div>
            </div>
          </Removable>
        )}
        <div className="sign-e__center">
          <ScriptHero defaultText="cards" max={220} />
          <div className="sign-e__sub-eyebrow"><E>AND GIFTS</E></div>
        </div>
        {shown.foot && (
          <Removable onRemove={() => hide('foot')}>
            <LyricFoot />
          </Removable>
        )}
      </div>
    </div>
  );
}

// ─────────── UNPLUGGED · 8×10″ framed ───────────
function UnpluggedSign({ p, w = 400, h = 500 }) {
  const [shown, setShown] = useState({ eyebrow: true, foot: true });
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));

  return (
    <div className="sign sign--e sign--l-small sign--l-unplugged" style={signVars(p, w, h)}>
      <div className="sign__inner">
        {shown.eyebrow && (
          <Removable onRemove={() => hide('eyebrow')}>
            <div className="sign-e__eyebrow">
              <div><E>A QUIET MOMENT</E></div>
              <div><E>FOR THE CEREMONY</E></div>
            </div>
          </Removable>
        )}
        <div className="sign-e__center">
          <ScriptHero defaultText="unplugged" max={180} scale={0.85} />
          <div className="sign-e__sub-eyebrow"><E>PHOTOS TO FOLLOW</E></div>
        </div>
        {shown.foot && (
          <Removable onRemove={() => hide('foot')}>
            <LyricFoot />
          </Removable>
        )}
      </div>
    </div>
  );
}

// ─────────── IN LOVING MEMORY · 8×10″ framed ───────────
const DEFAULT_MEMORY_NAMES = [
  { id: 'n1', name: 'Eleanor Whitfield' },
  { id: 'n2', name: 'James Patrick Hayes' },
  { id: 'n3', name: 'Rose Margaret Aldridge' },
];

function MemorySign({ p, w = 400, h = 500 }) {
  const [shown, setShown] = useState({ eyebrow: true, foot: true });
  const [names, setNames] = useState(DEFAULT_MEMORY_NAMES);
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));
  const removeName = (id) => setNames((arr) => arr.filter((n) => n.id !== id));
  const addName = () => setNames((arr) => [...arr, { id: 'x' + Date.now(), name: 'Their Name Here' }]);

  return (
    <div className="sign sign--e sign--l-small sign--l-memory" style={signVars(p, w, h)}>
      <div className="sign__inner">
        {shown.eyebrow && (
          <Removable onRemove={() => hide('eyebrow')}>
            <div className="sign-e__eyebrow">
              <div><E>FOREVER WITH US</E></div>
            </div>
          </Removable>
        )}
        <ScriptHero defaultText="in memory" max={160} scale={0.85} />
        <div className="memory-list">
          {names.map((n) => (
            <div key={n.id} className="memory-item">
              <div className="memory-item__name"><E>{n.name}</E></div>
              <button type="button" className="memory-item__x" onClick={() => removeName(n.id)} aria-label="Remove this name" title="Remove this name">
                <span aria-hidden="true">×</span>
              </button>
            </div>
          ))}
          <button type="button" className="memory-list__add" onClick={addName}>+ Add a name</button>
        </div>
        {shown.foot && (
          <Removable onRemove={() => hide('foot')}>
            <LyricFoot />
          </Removable>
        )}
      </div>
    </div>
  );
}

// ─────────── TABLE NUMBER · 4×6″ tented frame ───────────
function TableNumberSign({ p, w = 360, h = 540 }) {
  const tn = useTableNumber('lyric-table');
  const [shown, setShown] = useState({ eyebrow: true, foot: true });
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));

  return (
    <>
      <div className="sign sign--e sign--l-small sign--l-tablenum" style={signVars(p, w, h)}>
        <div className="sign__inner">
          {shown.eyebrow && (
            <Removable onRemove={() => hide('eyebrow')}>
              <div className="sign-e__eyebrow">
                <div><E>TABLE</E></div>
              </div>
            </Removable>
          )}
          <div className="table-number">
            <div className="table-number__digits">{tn.n}</div>
          </div>
          {shown.foot && (
            <Removable onRemove={() => hide('foot')}>
              <LyricFoot />
            </Removable>
          )}
        </div>
      </div>
      <TableNumberStepper tn={tn} />
    </>
  );
}

// ─────────── PHOTO ALBUM (QR) · 8×10″ framed ───────────
function AlbumSign({ p, w = 400, h = 500 }) {
  const [shown, setShown] = useState({ eyebrow: true, caption: true, foot: true });
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));

  return (
    <div className="sign sign--e sign--l-small sign--l-album" style={signVars(p, w, h)}>
      <div className="sign__inner">
        {shown.eyebrow && (
          <Removable onRemove={() => hide('eyebrow')}>
            <div className="sign-e__eyebrow">
              <div><E>SHARE THE DAY</E></div>
            </div>
          </Removable>
        )}
        <ScriptHero defaultText="capture" max={180} />
        <div className="sign-e__qr-wrap">
          <QRUploader id="lyric-album" size={150} placeholder="Drop QR code" />
        </div>
        {shown.caption && (
          <Removable onRemove={() => hide('caption')}>
            <div className="sign-e__caption"><E>SCAN TO ADD YOUR PHOTOS</E></div>
          </Removable>
        )}
        {shown.foot && (
          <Removable onRemove={() => hide('foot')}>
            <LyricFoot />
          </Removable>
        )}
      </div>
    </div>
  );
}

// ─────────── SEATING CHART · 18×24″ poster ───────────
function SeatingChart({ p, w = 540, h = 720 }) {
  const gl = useGuestList('lyric-seating');
  const [shown, setShown] = useState({ eyebrow: true, foot: true });
  const hide = (k) => setShown((s) => ({ ...s, [k]: false }));

  return (
    <>
      <div className="sign sign--e sign--l-seating" style={signVars(p, w, h)}>
        <div className="sign__inner">
          {shown.eyebrow && (
            <Removable onRemove={() => hide('eyebrow')}>
              <div className="sign-e__eyebrow">
                <div><E>FIND YOUR SEAT</E></div>
              </div>
            </Removable>
          )}
          <ScriptHero defaultText="seating" max={220} />

          <div className="seating-list seating-list--lyric" style={seatingListStyle(gl.count)}>
            {gl.sortedGuests.map((g) => (
              <div key={g.id} className="seating-row">
                <span className="seating-row__name">{g.last}, {g.first}</span>
                <span className="seating-row__dots" aria-hidden="true" />
                <span className="seating-row__table">{g.table}</span>
              </div>
            ))}
          </div>

          {shown.foot && (
            <Removable onRemove={() => hide('foot')}>
              <LyricFoot />
            </Removable>
          )}
        </div>
      </div>
      <GuestEditor gl={gl} />
    </>
  );
}

Object.assign(window, { WelcomeSign, BarSign, CardsSign, UnpluggedSign, AlbumSign, MemorySign, TableNumberSign, SeatingChart });
window.CollectionWelcomes = window.CollectionWelcomes || {};
window.CollectionWelcomes.lyric = WelcomeSign;
