/* global React */
// Primitives for the BoyleSports Stats Centre home — brand-true building blocks.
const PL = window.PL;

/* The signature lime parallelogram slash. */
function Slash({ h = 28, w, color = 'var(--bs-lime)', style }) {
  const width = w || h * 0.46;
  return (
    <span aria-hidden="true" style={{
      display: 'inline-block', width: width, height: h, background: color,
      transform: 'sk(-18deg)', // overwritten below
      ...style,
    }} />
  );
}
// fix skew (CSS transform key)
function SlashGlyph({ h = 28, w, color = 'var(--bs-lime)', style }) {
  const width = w || Math.round(h * 0.42);
  return (
    <span aria-hidden="true" style={{
      display: 'inline-block', width, height: h, background: color,
      transform: 'skewX(-18deg)', borderRadius: 1, flex: '0 0 auto', ...style,
    }} />
  );
}

/* Team colour disc — replaces crests/flags. Shows the 3-letter club code. */
function TeamDisc({ code, size = 34, ring = false, style }) {
  const t = PL.T[code] || { c: '#999', ink: '#fff', abbr: code };
  const fs = Math.round(size * 0.34);
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      width: size, height: size, borderRadius: '50%', flex: '0 0 auto',
      background: t.c, color: t.ink,
      boxShadow: ring ? `0 0 0 2px var(--bs-white), 0 0 0 3.5px ${t.c}` : 'inset 0 0 0 1px rgba(255,255,255,0.14)',
      fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: fs, letterSpacing: '0.01em',
      ...style,
    }}>{t.abbr}</span>
  );
}

/* Team name row: disc + name */
function TeamRow({ code, size = 30, bold = false, color = 'var(--text-primary)', name, abbrInstead = false, gap = 10, fs = 15 }) {
  const t = PL.T[code] || { name: code, abbr: code };
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap }}>
      <TeamDisc code={code} size={size} />
      <span style={{ fontFamily: 'var(--font-body)', fontWeight: bold ? 700 : 600, fontSize: fs, color, whiteSpace: 'nowrap' }}>
        {abbrInstead ? t.abbr : (name || t.name)}
      </span>
    </span>
  );
}

/* Numbered jersey — replaces player photos. Club-coloured shirt + squad number. */
function Jersey({ code, number, size = 64, style }) {
  const t = PL.T[code] || { c: '#888', c2: '#fff', ink: '#fff' };
  const w = size, h = size * 1.04;
  // pick a readable number colour against the shirt
  const numColor = t.ink === '#FFFFFF' ? '#FFFFFF' : t.ink;
  return (
    <span style={{ display: 'inline-block', width: w, height: h, position: 'relative', flex: '0 0 auto', ...style }}>
      <svg viewBox="0 0 100 104" width={w} height={h} style={{ display: 'block', filter: 'drop-shadow(0 2px 3px rgba(10,10,10,0.18))' }}>
        {/* body */}
        <path d="M30 14 L12 24 L4 46 L20 54 L22 100 L78 100 L80 54 L96 46 L88 24 L70 14 L60 22 Q50 30 40 22 Z"
          fill={t.c} stroke="rgba(0,0,0,0.12)" strokeWidth="1.5" />
        {/* collar */}
        <path d="M40 14 Q50 26 60 14 L60 12 Q50 22 40 12 Z" fill={t.c2} opacity="0.95" />
        {/* sleeve accents */}
        <path d="M12 24 L4 46 L20 54 L24 34 Z" fill={t.c2} opacity="0.28" />
        <path d="M88 24 L96 46 L80 54 L76 34 Z" fill={t.c2} opacity="0.28" />
      </svg>
      <span style={{
        position: 'absolute', inset: 0, top: '34%', display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: size * 0.42, color: numColor,
        textShadow: numColor === '#FFFFFF' ? '0 1px 2px rgba(0,0,0,0.35)' : 'none',
      }}>{number}</span>
    </span>
  );
}

/* Form pill string — W lime / L black / D grey. Pass `team` to enable per-match hover. */
function genFormDetails(code, results) {
  const CODES = Object.keys(window.PL.T);
  let seed = 7; for (const ch of code) seed = (seed * 31 + ch.charCodeAt(0)) >>> 0;
  const rnd = () => { seed = (seed * 1103515245 + 12345) & 0x7fffffff; return seed / 0x7fffffff; };
  const pick = (a) => a[Math.floor(rnd() * a.length)];
  const n = results.length;
  return results.map((res, i) => {
    let opp; do { opp = CODES[Math.floor(rnd() * CODES.length)]; } while (opp === code);
    const home = rnd() > 0.5;
    let s;
    if (res === 'W') s = pick([[2, 1], [3, 1], [1, 0], [2, 0], [3, 2]]);
    else if (res === 'D') s = pick([[1, 1], [0, 0], [2, 2]]);
    else s = pick([[0, 1], [1, 2], [0, 2], [1, 3]]);
    return { mw: 32 - (n - i), opp, home, tg: s[0], og: s[1], res };
  });
}
function Form({ results, size = 22, gap = 4, team }) {
  const [tip, setTip] = React.useState(null);
  const details = team ? genFormDetails(team, results) : null;
  const map = {
    W: { bg: 'var(--bs-lime)', fg: 'var(--bs-blue-navy)' },
    L: { bg: 'var(--bs-black)', fg: 'var(--bs-white)' },
    D: { bg: 'var(--bs-neutral-300)', fg: 'var(--bs-blue-navy)' },
  };
  return (
    <span style={{ display: 'inline-flex', gap }}>
      {results.map((r, i) => {
        const c = map[r] || map.D;
        const d = details && details[i];
        return <span key={i}
          onMouseEnter={d ? (e) => setTip({ r: e.currentTarget.getBoundingClientRect(), d }) : undefined}
          onMouseLeave={d ? () => setTip(null) : undefined}
          style={{
            width: size, height: size, borderRadius: 3, display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            background: c.bg, color: c.fg, fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: size * 0.5, cursor: d ? 'help' : 'default',
          }}>{r}</span>;
      })}
      {tip && (() => {
        const T = window.PL.T, d = tip.d;
        const hT = d.home ? team : d.opp, aT = d.home ? d.opp : team;
        const hS = d.home ? d.tg : d.og, aS = d.home ? d.og : d.tg;
        return (
          <div style={{ position: 'fixed', left: tip.r.left + tip.r.width / 2, top: tip.r.top - 8, transform: 'translate(-50%,-100%)', background: 'var(--bs-blue-navy)', padding: '8px 12px', borderRadius: 6, zIndex: 9999, pointerEvents: 'none', boxShadow: 'var(--shadow-lg)', whiteSpace: 'nowrap' }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 10, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--bs-lime)', marginBottom: 5 }}>Matchweek {d.mw} · {d.home ? 'Home' : 'Away'}</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
              <TeamDisc code={hT} size={18} />
              <span style={{ fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 13, color: '#fff' }}>{T[hT].abbr}</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontWeight: 700, fontSize: 14, color: 'var(--bs-lime)' }}>{hS}–{aS}</span>
              <span style={{ fontFamily: 'var(--font-body)', fontWeight: 700, fontSize: 13, color: '#fff' }}>{T[aT].abbr}</span>
              <TeamDisc code={aT} size={18} />
            </div>
          </div>
        );
      })()}
    </span>
  );
}

/* Custom dropdown chevron — brand icon, used on every <select> across the app. */
function Chevron({ size = 24, color = '#191919' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" style={{ display: 'block', flex: '0 0 auto' }} aria-hidden="true">
      <path d="M7.05 8.25L11.775 12.975L16.5 8.25L17.55 9.375L11.775 15.15L6 9.375L7.05 8.25Z" fill={color} />
    </svg>
  );
}

/* Exact Figma slash — lime parallelogram, identical for every heading (31×40, fixed).
   Same on desktop and mobile per brand spec. */
function FixedSlash({ color = '#D1F206', className = '' }) {
  return (
    <svg className={'bs-fixedslash ' + className} width="31" height="40" viewBox="0 0 31 40" fill="none" style={{ display: 'block', flex: '0 0 auto' }} aria-hidden="true">
      <path d="M19.4857 0H31L11.5143 40H0L19.4857 0Z" fill={color} />
    </svg>
  );
}

/* Section heading — Figma "/HEADING": lime slash with the title's first letter overlapping it.
   `right` renders a control (dropdown / export button) on the right and stays top-aligned so a
   wrapped two-line title keeps the slash next to its FIRST letter.
   `action` renders a text link that sits BELOW the heading, so the title always keeps one line. */
function SlashHeading({ title, action, right, onLight = true }) {
  const titleEl = (
    <div className="bs-heading-title" style={{ position: 'relative', display: 'flex', alignItems: 'center', minWidth: 0, flex: '1 1 auto', gap: 0 }}>
      <span style={{ flex: '0 0 auto' }}><FixedSlash /></span>
      <h2 style={{ position: 'relative', zIndex: 1, margin: 0, marginLeft: -12, fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 28, lineHeight: '32px', letterSpacing: '-0.01em', textTransform: 'uppercase', color: onLight ? 'var(--text-brand)' : 'var(--bs-white)', minWidth: 0, overflowWrap: 'normal' }}>{title}</h2>
    </div>
  );

  // Heading with a right-side control (export button / select): single top-aligned row,
  // title is free to wrap to two lines; the slash hugs the first letter of the top line.
  if (right) {
    return (
      <div className="bs-heading-row bs-heading-haswidget" style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, marginBottom: 18 }}>
        {titleEl}
        <span style={{ flex: '0 0 auto' }}>{right}</span>
      </div>
    );
  }

  // Heading with an action link: DESKTOP shows the link beside the title (row);
  // MOBILE drops the link below (handled by .bs-heading-hasaction in CSS).
  return (
    <div className="bs-heading-row bs-heading-hasaction" style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 18 }}>
      {titleEl}
      {action && (
        <a href="#" onClick={(e) => e.preventDefault()} className="bs-action-link" style={{
          flex: '0 0 auto', fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 13, letterSpacing: '0.06em', textTransform: 'uppercase',
          color: onLight ? 'var(--text-brand)' : 'var(--bs-lime)', textDecoration: 'none', whiteSpace: 'nowrap', display: 'inline-flex', alignItems: 'center', gap: 6,
        }}>{action} <span style={{ fontSize: 15 }}>→</span></a>
      )}
    </div>
  );
}

/* White surface card */
function Panel({ children, pad = 0, style, hover = false, className = '' }) {
  return (
    <div className={'bs-panel ' + (hover ? 'bs-panel-hover ' : '') + className} style={{
      background: 'var(--bs-white)', border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-md)',
      boxShadow: 'none', padding: pad, overflow: 'hidden', ...style,
    }}>{children}</div>
  );
}

/* Horizontal comparison bar (home vs away split) */
function SplitBar({ home, away, hColor, aColor }) {
  const total = home + away || 1;
  const hPct = (home / total) * 100;
  return (
    <div style={{ display: 'flex', height: 8, borderRadius: 999, overflow: 'hidden', background: 'var(--bs-neutral-200)' }}>
      <div style={{ width: hPct + '%', background: hColor }} />
      <div style={{ width: (100 - hPct) + '%', background: aColor }} />
    </div>
  );
}

/* Early Payout badge — Figma "Badge / EPO": lime bar + EARLY//PAYOUT wordmark. */
function EPOBadge({ height = 18 }) {
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', background: 'var(--bs-lime)', padding: '0 8px', height, borderRadius: 2, flex: '0 0 auto' }}>
      <img src="assets/epo-badge.svg" alt="Early Payout" style={{ height: Math.round(height * 0.42), display: 'block' }} />
    </span>
  );
}

/* Underline tab row — shared by Matchweek, Player Leaders, Next Big Match.
   Figma "Style=Standard, Size=Small": grey pill container, active = white box w/ electric-blue border. */
function Tabs({ tabs, active, onChange, tone = 'light' }) {
  const items = tabs.map((t) => (typeof t === 'string' ? { id: t, label: t } : t));
  const dark = tone === 'dark';
  const railRef = React.useRef(null);
  const [fade, setFade] = React.useState(false);
  const update = React.useCallback(() => {
    const el = railRef.current; if (!el) return;
    setFade(el.scrollWidth - el.clientWidth - el.scrollLeft > 4);
  }, []);
  React.useEffect(() => {
    update();
    window.addEventListener('resize', update);
    return () => window.removeEventListener('resize', update);
  }, [update]);
  const fadeCol = dark ? 'rgba(255,255,255,0.1)' : 'rgb(239,241,245)';
  return (
    <div className="bs-tabs-wrap" style={{ position: 'relative', maxWidth: '100%' }}>
      <div ref={railRef} onScroll={update} className="bs-tabs" style={{
        display: 'flex', gap: 4, padding: 4, borderRadius: 2,
        background: dark ? 'rgba(255,255,255,0.1)' : 'rgb(239,241,245)', maxWidth: '100%',
        overflowX: 'auto', WebkitOverflowScrolling: 'touch',
      }}>
        {items.map((it) => {
          const on = active === it.id;
          return (
            <button key={it.id} onClick={() => onChange(it.id)} className="bs-tab" style={{
              display: 'inline-flex', flexDirection: 'column', alignItems: 'center', gap: 4, flex: '0 0 auto',
              background: on ? (dark ? 'var(--bs-white)' : 'rgb(255,255,255)') : 'transparent',
              border: 'none', borderRadius: 2, cursor: 'pointer', padding: '7px 14px 5px', whiteSpace: 'nowrap', transition: 'color .12s',
            }}>
              <span style={{
                display: 'inline-flex', alignItems: 'center', gap: 7,
                fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 14, lineHeight: '20px',
                color: on ? 'rgb(25,25,25)' : (dark ? 'rgba(255,255,255,0.65)' : 'rgb(117,117,117)'),
              }}>
                {it.dot && <span className="bs-live-dot" style={{ width: 7, height: 7, borderRadius: '50%', background: 'var(--bs-success)' }} />}
                {it.label}
                {it.count != null && <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, opacity: 0.8 }}>{it.count}</span>}
              </span>
              <span style={{ width: '100%', height: 3, borderRadius: 2, background: on ? 'rgb(36,0,246)' : 'transparent' }} />
            </button>
          );
        })}
      </div>
      {fade && <span aria-hidden="true" style={{ position: 'absolute', top: 4, bottom: 4, right: 4, width: 44, pointerEvents: 'none', borderRadius: '0 2px 2px 0', background: `linear-gradient(to right, transparent, ${fadeCol})` }} />}
    </div>
  );
}

Object.assign(window, { SlashGlyph, FixedSlash, Chevron, TeamDisc, TeamRow, Jersey, Form, SlashHeading, Panel, SplitBar, EPOBadge, Tabs });
