/* =============================================================================
   SheetHead — brand components
   The mark is a playing card wearing a jester's cap (a "sheet" with a "head"), the pip on its face is the spade.
   Also here: the suit-pip icon language, printed "face cards" used as menu tiles, and the shared screen furniture.
   Presentation only. Exposes window.SH.ui.*
============================================================================= */
(function () {
  const { useState, useEffect, useRef } = React;
  const UI = window.SH.ui;
  const { cx, MDiv, M } = UI;
  const MButton = (M && M.motion && M.motion.button) || 'button';

  // ---------------------------------------------------------------------------------------------- suit pips
  const PIP = {
    S: 'M12 1.4C12 1.4 3 8.4 3 14c0 3.2 2.4 5 5 5 1.6 0 2.9-.7 3.6-1.8-.2 2.4-1.2 4.2-3 5.3h7.2c-1.8-1.1-2.8-2.9-3-5.3.7 1.1 2 1.8 3.6 1.8 2.6 0 5-1.8 5-5C21 8.4 12 1.4 12 1.4z',
    H: 'M12 22.6S2.4 15.4 2.4 8.7C2.4 5.3 4.9 3 7.8 3c1.8 0 3.4.9 4.2 2.5C12.8 3.9 14.4 3 16.2 3c2.9 0 5.4 2.3 5.4 5.7 0 6.700-9.600 13.900-9.600 13.900z',
    D: 'M12 1.2 20 12l-8 10.800L4 12z',
    C: 'M12 1.9a4.2 4.2 0 1 0 0 8.4 4.2 4.2 0 1 0 0-8.4zM6 9a4.2 4.2 0 1 0 0 8.4A4.2 4.2 0 1 0 6 9zM18 9a4.2 4.2 0 1 0 0 8.4A4.2 4.2 0 1 0 18 9zM9.4 9v6h5.2V9zM10.7 13c.3 4.500-.9 7.200-3 9.200h8.600c-2.100-2-3.300-4.700-3-9.200z'
  };
  const RED = { H: true, D: true };
  function Pip({ suit = 'S', size = 24, className, style }) {
    return <svg viewBox="0 0 24 24" width={size} height={size} className={cx('pip', RED[suit] ? 'is-red' : 'is-black', className)} style={style} aria-hidden="true" focusable="false"><path d={PIP[suit]} fill="currentColor" /></svg>;
  }

  // ---------------------------------------------------------------------------------------------- the mark
  // viewBox 64 x 80. `simple` drops the fine details so it survives 16-24 px (favicon / compact header).
  function Mark({ size = 48, simple = false, className, animated = false, title }) {
    const h = Math.round(size * 80 / 64);
    return (
      <svg viewBox="0 0 64 80" width={size} height={h} className={cx('mark', animated && 'mark-live', className)} role={title ? 'img' : undefined} aria-hidden={title ? undefined : 'true'} aria-label={title} focusable="false">
        {title ? <title>{title}</title> : null}
        <g className="mk-card">
          <rect x="11" y="24" width="42" height="54" rx="5.5" fill="#f3ead8" stroke="#150f10" strokeWidth={simple ? 3.2 : 2.6} />
          {!simple && <rect x="15" y="28" width="34" height="46" rx="3" fill="none" stroke="#b98a2e" strokeWidth="1" opacity=".75" />}
          <g transform="translate(32 55) scale(1.38) translate(-12 -12)"><path d={PIP.S} fill="#150f10" /></g>
          {!simple && <g fill="#150f10"><g transform="translate(17.500 33.500) scale(.5) translate(-12 -12)"><path d={PIP.S} /></g><g transform="translate(46.500 68.500) rotate(180) scale(.5) translate(-12 -12)"><path d={PIP.S} /></g></g>}
        </g>
        <g className="mk-cap">
          <path d="M19 24 C14 11 8 7 5 16" fill="none" stroke="#150f10" strokeWidth={simple ? 13 : 11.5} strokeLinecap="round" />
          <path d="M19 24 C14 11 8 7 5 16" fill="none" stroke="#b81e2d" strokeWidth={simple ? 8.4 : 7.2} strokeLinecap="round" />
          <path d="M32 24 C30 13 32 5 40 5" fill="none" stroke="#150f10" strokeWidth={simple ? 13 : 11.5} strokeLinecap="round" />
          <path d="M32 24 C30 13 32 5 40 5" fill="none" stroke="#b81e2d" strokeWidth={simple ? 8.4 : 7.2} strokeLinecap="round" />
          <path d="M45 24 C50 11 56 7 59 16" fill="none" stroke="#150f10" strokeWidth={simple ? 13 : 11.5} strokeLinecap="round" />
          <path d="M45 24 C50 11 56 7 59 16" fill="none" stroke="#b81e2d" strokeWidth={simple ? 8.4 : 7.2} strokeLinecap="round" />
          <path d="M10.5 27.5h43" stroke="#150f10" strokeWidth={simple ? 6.8 : 6.5} strokeLinecap="round" />
          <path d="M10.5 27.5h43" stroke="#e3b75a" strokeWidth={simple ? 3.6 : 3.4} strokeLinecap="round" />
          <circle className="bell b1" cx="5" cy="18.5" r={simple ? 4.8 : 4.2} fill="#e3b75a" stroke="#150f10" strokeWidth={simple ? 2.6 : 2.4} />
          <circle className="bell b2" cx="59" cy="18.5" r={simple ? 4.8 : 4.2} fill="#e3b75a" stroke="#150f10" strokeWidth={simple ? 2.6 : 2.4} />
          <circle className="bell b3" cx="41" cy="5" r={simple ? 4.8 : 4.2} fill="#e3b75a" stroke="#150f10" strokeWidth={simple ? 2.6 : 2.4} />
        </g>
      </svg>
    );
  }

  function Wordmark({ className, split = true }) {
    return <span className={cx('wordmark', className)}>{split ? <><span className="wm-a">Sheet</span><span className="wm-b">Head</span></> : 'SheetHead'}</span>;
  }

  // variant: 'stacked' (welcome / loading), 'lockup' (navigation, headers), 'mark' (mark alone), 'small' (tiny: game header)
  function Logo({ variant = 'lockup', size, className, animated, tagline = true }) {
    if (variant === 'mark') return <Mark size={size || 48} animated={animated} className={className} title="SheetHead" />;
    if (variant === 'small') return <span className={cx('logo logo-small', className)}><Mark size={size || 22} simple className="lg-mark" title="SheetHead" /></span>;
    if (variant === 'stacked') {
      return (
        <div className={cx('logo logo-stacked', className)} role="img" aria-label="SheetHead, the card-shedding game">
          <Mark size={size || 104} animated={animated} className="lg-mark" />
          <Wordmark className="lg-word" />
          {tagline && <div className="lg-tag"><i /><span>The card-shedding game</span><i /></div>}
        </div>
      );
    }
    return (
      <span className={cx('logo logo-lockup', className)} role="img" aria-label="SheetHead">
        <Mark size={size || 34} simple={(size || 34) < 30} className="lg-mark" />
        <Wordmark className="lg-word" />
      </span>
    );
  }

  // ---------------------------------------------------------------------------------------------- room (backdrop)
  // CSS layers always render (this is the whole backdrop when WebGL is off); the PixiJS layer adds drifting light, dust
  // and card silhouettes on top when available.
  function Room({ settings, paused }) {
    const host = useRef(null);
    useEffect(() => {
      const F = window.SH.fx;
      if (!F || !F.MenuBackdrop) return undefined;
      const cfg = F.resolve(); F.configure({ quality: settings.quality || 'auto', reducedMotion: !!settings.reducedMotion || settings.animations === false, enabled: settings.fx !== false });
      const c2 = F.resolve();
      if (paused || !c2.enabled || c2.reducedMotion || c2.quality === 'low' || !F.available()) return undefined;
      let bd = null, dead = false;
      F.MenuBackdrop.create(host.current).then(b => { if (dead) b.destroy(); else bd = b; }).catch(() => { /* CSS backdrop stays */ });
      return () => { dead = true; if (bd) bd.destroy(); };
    }, [!!paused, settings.quality, settings.reducedMotion, settings.animations, settings.fx]);
    return (
      <div className="room" aria-hidden="true">
        <div className="room-lamp" /><div className="room-felt" /><div className="room-lattice" />
        <div className="room-gl" ref={host} />
        <div className="room-vignette" /><div className="room-grain" />
      </div>
    );
  }

  // ---------------------------------------------------------------------------------------------- printed face card (menu tile)
  // A portrait playing card: corner indices, a big pip, a title in the display face, and a one-line promise.
  function FaceCard({ rank, suit, kicker, title, desc, cta = 'Play', onClick, tilt = 0, index = 0, disabled, className, badge }) {
    const inner = (
      <button type="button" className={cx('fcard', 's-' + suit, RED[suit] ? 'red' : 'black', className)} style={{ '--tilt': tilt + 'deg' }} onClick={onClick} disabled={disabled}>
        <span className="fc-idx tl"><b>{rank}</b><Pip suit={suit} size={16} /></span>
        <span className="fc-idx br"><b>{rank}</b><Pip suit={suit} size={16} /></span>
        <Pip suit={suit} size={200} className="fc-watermark" />
        <span className="fc-body">
          {kicker && <span className="fc-kicker">{kicker}</span>}
          <strong className="fc-title">{title}</strong>
          {desc && <span className="fc-desc">{desc}</span>}
        </span>
        <span className="fc-cta">{cta}<svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6" fill="none" stroke="currentColor" strokeWidth="2.600" strokeLinecap="round" strokeLinejoin="round" /></svg></span>
        {badge && <span className="fc-badge">{badge}</span>}
      </button>
    );
    if (!M) return <div className="fc-slot" style={{ '--i': index }}>{inner}</div>;
    return <MDiv className="fc-slot" style={{ '--i': index }} initial={{ opacity: 0, y: 70 }} animate={{ opacity: 1, y: 0 }} transition={{ type: 'spring', stiffness: 170, damping: 20, delay: 0.12 + index * 0.08 }}>{inner}</MDiv>;
  }

  // ---------------------------------------------------------------------------------------------- shared furniture
  function Rule({ label, className }) { return <div className={cx('rule', className)}><i /><span>{label}</span><i /></div>; }

  // Screen frame for every secondary screen: back control, page title in the display face, content.
  function Frame({ title, kicker, onBack, right, children, wide, className, bodyClass }) {
    return (
      <div className={cx('frame', wide && 'frame-wide', className)}>
        <header className="frame-head">
          {onBack ? <button type="button" className="back" onClick={onBack} aria-label="Back"><svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M19 12H5M11 6l-6 6 6 6" fill="none" stroke="currentColor" strokeWidth="2.400" strokeLinecap="round" strokeLinejoin="round" /></svg><span>Back</span></button> : <span />}
          <div className="frame-title">{kicker && <span className="kicker">{kicker}</span>}<h1>{title}</h1></div>
          <div className="frame-right">{right}</div>
        </header>
        <main className={cx('frame-body', bodyClass)}>{children}</main>
      </div>
    );
  }

  // Physical switch: a brass knob on a slot.
  function Switch({ label, hint, value, onChange, id }) {
    return (
      <label className="switch-row" htmlFor={id}>
        <span className="sw-text"><span className="sw-label">{label}</span>{hint && <span className="sw-hint">{hint}</span>}</span>
        <input id={id} type="checkbox" role="switch" className="sw-input" checked={!!value} onChange={e => onChange(e.target.checked)} />
        <span className="sw-track" aria-hidden="true"><span className="sw-knob" /></span>
      </label>
    );
  }
  // Index-tab segmented control
  function Tabs({ label, options, value, onChange, className }) {
    return (
      <div className={cx('tabs', className)} role="radiogroup" aria-label={label}>
        {options.map(([k, l]) => (
          <button key={k} type="button" role="radio" aria-checked={value === k} className={cx('tab', value === k && 'on')} onClick={() => onChange(k)}>{l}</button>
        ))}
      </div>
    );
  }

  // Shuffle loader: three cards riffle under the mark. Used for boot and for the hand-over from the menu into a match.
  function Shuffle({ label = 'Shuffling the deck' }) {
    return (
      <div className="shuffle" role="status" aria-live="polite">
        <Mark size={84} animated className="sh-mark" />
        <div className="sh-deck" aria-hidden="true"><i /><i /><i /><i /></div>
        <div className="sh-label">{label}</div>
      </div>
    );
  }

  Object.assign(UI, { Pip, Mark, Wordmark, Logo, Room, FaceCard, Rule, Frame, Switch, Tabs, Shuffle });
})();
