const { Icon } = window.PryzeDesignSystem_b2bad9;
const { USER, LEADERBOARD_PEERS, FILLER_PEERS, LEADERBOARD_SCOPE_SIZES, LEADERBOARD_SCOPES, COMPANIES } = window.PryzeData;

function initials(name) { return name.split(' ').map(p => p[0]).join('').slice(0, 2).toUpperCase(); }
function shortName(name) { const parts = name.split(' '); return parts.length < 2 ? name : `${parts[0]} ${parts[parts.length - 1][0]}.`; }

function seededJitter(id, scope) { let h = 0; const s = id + scope + scope + 'v2'; for (let i = 0; i < s.length; i++) h = (h * 37 + s.charCodeAt(i) * 7) % 100000; return 0.3 + (h / 100000) * 1.8; }
function buildList(scope, mode) {
  const mult = scope === 'Universe' ? 5.4 : scope === 'Company' ? 2.1 : 1;
  const target = LEADERBOARD_SCOPE_SIZES[scope] - 1;
  const fillerNeeded = Math.max(0, target - LEADERBOARD_PEERS.length);
  const basePeers = [...LEADERBOARD_PEERS, ...FILLER_PEERS.slice(0, fillerNeeded)];
  const list = basePeers.map(p => { const j = seededJitter(p.id, scope); return { ...p, points: Math.round(p.points * mult * j), kudos: Math.round(p.kudos * mult * j) }; });
  const withSelf = [...list, { id: 'self', name: USER.name, points: Math.round(USER.points * mult), kudos: Math.round(USER.kudos * mult), role: USER.role, streak: USER.streak, goals: USER.goals, photo: USER.photo, company: USER.company, store: USER.store, rankChange: 2, isNewTop3: false, self: true }];
  withSelf.sort((a, b) => b[mode] - a[mode]);
  return withSelf.map((p, i) => ({ ...p, rank: i + 1, score: p[mode] }));
}

function CountUp({ value }) {
  const [n, setN] = React.useState(value);
  React.useEffect(() => {
    const start = performance.now(), dur = 700, from = 0;
    let raf, done = false;
    function tick(t) {
      const p = Math.min(1, (t - start) / dur);
      setN(Math.round(from + (value - from) * (1 - Math.pow(1 - p, 3))));
      if (p < 1) raf = requestAnimationFrame(tick); else done = true;
    }
    raf = requestAnimationFrame(tick);
    const fallback = setTimeout(() => { if (!done) setN(value); }, dur + 150);
    return () => { cancelAnimationFrame(raf); clearTimeout(fallback); };
  }, [value]);
  return <React.Fragment>{n.toLocaleString()}</React.Fragment>;
}

function RankArrow({ change }) {
  if (!change) return <span className="rank-arrow rank-arrow-flat"><Icon name="minus" size={11} /></span>;
  const up = change > 0;
  return <span className={`rank-arrow ${up ? 'rank-arrow-up' : 'rank-arrow-down'}`}><Icon name={up ? 'caret-up' : 'caret-down'} weight="fill" size={13} />{Math.abs(change)}</span>;
}

function PodiumGlow() {
  const colors = ['#FFE066', '#FFC85C', '#FFD9A0', '#F4E4C1', '#E9A23B', '#E4E7EC', '#C7CCD6'];
  const shapes = ['dot', 'star', 'confetti'];
  const sprinkles = React.useMemo(() => Array.from({ length: 40 }, (_, i) => ({
    left: 4 + Math.random() * 92, top: 6 + Math.random() * 88,
    delay: Math.random() * 3.2, dur: 2.4 + Math.random() * 2.4,
    color: colors[i % colors.length], size: 4 + Math.random() * 7,
    shape: shapes[i % shapes.length], rot: Math.random() * 360,
  })), []);
  const bokeh = React.useMemo(() => Array.from({ length: 18 }, (_, i) => ({
    left: 4 + Math.random() * 92, top: 4 + Math.random() * 86,
    size: 10 + Math.random() * 26, delay: Math.random() * 3, dur: 2.6 + Math.random() * 3,
    color: colors[i % colors.length],
  })), []);
  return (
    <div className="podium-glow-bg" aria-hidden="true">
      <div className="podium-spotlight-beam" />
      <div className="podium-shimmer-sweep" />
      <div className="podium-glow-blob podium-glow-blob-a" />
      <div className="podium-glow-blob podium-glow-blob-b" />
      <div className="podium-glow-blob podium-glow-blob-c" />
      {bokeh.map((b, i) => (
        <span key={i} className="podium-bokeh" style={{ left: b.left + '%', top: b.top + '%', width: b.size, height: b.size, '--bc': b.color, animationDelay: b.delay + 's', animationDuration: b.dur + 's' }} />
      ))}
      {sprinkles.map((p, i) => (
        <span key={i} className={`podium-sprinkle podium-sprinkle-${p.shape}`} style={{ left: p.left + '%', top: p.top + '%', '--c': p.color, width: p.size, height: p.shape === 'confetti' ? p.size * 1.8 : p.size, animationDelay: p.delay + 's', animationDuration: p.dur + 's', transform: `rotate(${p.rot}deg)` }}>{p.shape === 'star' ? '✦' : ''}</span>
      ))}
    </div>
  );
}

function IntroConfetti({ onDone }) {
  const colors = ['#FFE066', '#FFC85C', 'var(--color-primary)', '#FF5A2E', '#9C8FFF', '#E2FF17'];
  const shapes = ['line', 'circle', 'star'];
  const pieces = React.useMemo(() => Array.from({ length: 70 }, (_, i) => ({
    left: Math.random() * 100, delay: Math.random() * 0.5, dur: 2.4 + Math.random() * 1.3,
    color: colors[i % colors.length], rot: Math.random() * 360, size: 6 + Math.random() * 5,
    shape: shapes[i % shapes.length], drift: (Math.random() - 0.5) * 70,
  })), []);
  React.useEffect(() => { const t = setTimeout(onDone, 3600); return () => clearTimeout(t); }, [onDone]);
  return (
    <div className="lb-intro-confetti" aria-hidden="true">
      {pieces.map((p, i) => (
        <span key={i} className={`lb-confetti-piece lb-confetti-${p.shape}`} style={{ left: p.left + '%', '--drift': p.drift + 'px', color: p.color, background: p.shape !== 'star' ? p.color : undefined, width: p.shape === 'line' ? p.size * 0.5 : p.size, height: p.shape === 'line' ? p.size * 2.2 : p.size, animationDelay: p.delay + 's', animationDuration: p.dur + 's', transform: `rotate(${p.rot}deg)` }}>{p.shape === 'star' ? '✦' : ''}</span>
      ))}
    </div>
  );
}

function ScopeTabs({ scope, onChange }) {
  return (
    <div className="scope-tabs">
      {LEADERBOARD_SCOPES.map(s => (
        <button key={s} className={`scope-tab ${scope === s ? 'scope-tab-active' : ''}`} onClick={() => onChange(s)}>{s}</button>
      ))}
    </div>
  );
}

function ModeToggle({ mode, onChange }) {
  return (
    <div className="mode-toggle" onClick={() => onChange(mode === 'points' ? 'kudos' : 'points')} role="button" aria-label="Toggle points or kudos">
      <div className={`mode-knob ${mode === 'kudos' ? 'mode-knob-right' : ''}`} />
      <span className={`mode-opt ${mode === 'points' ? 'mode-opt-active' : ''}`}><Icon name="sparkle" weight="fill" size={14} /></span>
      <span className={`mode-opt ${mode === 'kudos' ? 'mode-opt-active' : ''}`}><Icon name="heart" weight="fill" size={14} /></span>
    </div>
  );
}

function PodiumCard({ entry, place, mode, scope }) {
  const order = place === 1 ? 2 : place === 2 ? 1 : 3;
  const company = entry.company && COMPANIES[entry.company];
  let location = null;
  if (scope === 'Company') location = entry.store;
  else if (scope === 'Universe') location = company && company.name;
  return (
    <div className={`podium-star podium-star-p${place}`} style={{ order, animationDelay: `${(3 - place) * 150}ms` }}>
      <div className="podium-star-avatar">
        {entry.photo ? <img src={entry.photo} alt={entry.name} /> : <span className="podium-star-initials">{initials(entry.name)}</span>}
        <span className="podium-star-numeral">{place}</span>
      </div>
      <p className="podium-star-name">{entry.self ? 'You' : shortName(entry.name)}</p>
      {location && <span className="podium-star-location">{location}</span>}
      <span className="podium-star-score"><CountUp value={entry.score} /> {mode === 'points' ? 'pts' : 'kudos'}</span>
    </div>
  );
}

function LbRow({ entry, scope, isSelf, rowRef, mode }) {
  const company = entry.company && COMPANIES[entry.company];
  return (
    <div className={`lb-row ${isSelf ? 'lb-row-self' : ''}`} ref={rowRef}>
      <span className="lb-row-rank">{entry.rank}</span>
      <span className="lb-row-avatar">{entry.photo ? <img src={entry.photo} alt={entry.name} /> : initials(entry.name)}</span>
      <div className="lb-row-namecol">
        <span className="lb-row-name">{entry.self ? 'You' : shortName(entry.name)}{mode === 'points' && <React.Fragment><Icon name="target" weight="bold" size={11} color="currentColor" />{entry.goals}</React.Fragment>}</span>
        {scope === 'Universe' && company && <span className="lb-row-company-name">{company.name}</span>}
        {scope === 'Company' && entry.store && <span className="lb-row-company-name">{entry.store}</span>}
      </div>
      <span className="lb-row-perf"><span className="lb-row-score">{entry.score.toLocaleString()}</span><RankArrow change={entry.rankChange} /></span>
    </div>
  );
}

function LeaderboardScreen() {
  const [scope, setScope] = React.useState('Store');
  const [mode, setMode] = React.useState('points');
  const [showIntro, setShowIntro] = React.useState(true);
  const [about, setAbout] = React.useState(false);
  const listRef = React.useRef(null);
  const selfRowRef = React.useRef(null);

  const list = React.useMemo(() => buildList(scope, mode), [scope, mode]);
  const top3 = list.slice(0, 3);
  const rest = list.slice(3);
  const self = list.find(p => p.self);
  const ahead = list[self.rank - 2];
  const gap = ahead ? ahead.score - self.score : 0;

  return (
    <div style={{ position: 'relative', flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0 }}>
      {showIntro && <IntroConfetti onDone={() => setShowIntro(false)} />}
      <div className="lb-controls">
        <div className="lb-title-row">
          <div>
            <p className="lb-title">Leaderboard</p>
            <p className="lb-subtitle">Look who's crushing it 🔥</p>
          </div>
          <button className="lb-info-btn" onClick={() => setAbout(true)} aria-label="How the leaderboard works"><Icon name="info" weight="fill" size={16} color="var(--color-primary)" /></button>
        </div>
        <div className="lb-controls-row">
          <ScopeTabs scope={scope} onChange={setScope} />
          <ModeToggle mode={mode} onChange={setMode} />
        </div>
      </div>

      <div className="lb-scroll" ref={listRef}>
        <div className="podium-stage">
          <PodiumGlow />
          <div className="podium-row" key={scope + mode}>
            {top3.map(entry => <PodiumCard key={entry.id} entry={entry} place={entry.rank} mode={mode} scope={scope} />)}
          </div>
        </div>


        <div className="lb-table-head">
          <span className="th-rank">#</span><span className="th-avatar-spacer" /><span className="th-name">Name</span>
          <span className="th-perf"><span className="th-score-label">{mode === 'points' ? 'Points' : 'Kudos'}</span><span className="th-arrow-spacer"><Icon name="caret-up" weight="fill" size={13} color="var(--fg-secondary)" /></span></span>
        </div>
        {rest.map(entry => (
          <LbRow key={entry.id} entry={entry} scope={scope} isSelf={entry.self} rowRef={entry.self ? selfRowRef : null} mode={mode} />
        ))}
      </div>

      {about && (
        <div className="lb-about-overlay" onClick={() => setAbout(false)} role="dialog" aria-modal="true" aria-label="How the leaderboard works">
          <div className="lb-about-card" onClick={e => e.stopPropagation()}>
            <button className="lb-about-close" onClick={() => setAbout(false)} aria-label="Close"><Icon name="x" weight="bold" size={14} color="currentColor" /></button>
            <p className="lb-about-title">Two ways to climb</p>
            <div className="lb-about-list">
              <div className="lb-about-row"><span className="lb-about-icon"><Icon name="coins" weight="fill" size={15} color="var(--color-primary)" /></span><span><b>Points</b> — earn on shift, spend on rewards</span></div>
              <div className="lb-about-row"><span className="lb-about-icon" data-tone="kudos"><Icon name="heart" weight="fill" size={15} color="var(--lime-500)" /></span><span><b>Kudos</b> — love from coworkers, can't be spent</span></div>
            </div>
            <p className="lb-about-note">Both are lifetime totals — points you've spent still count, and nothing resets.</p>
            <p className="lb-about-sub">Who you're up against</p>
            <div className="lb-about-list">
              <div className="lb-about-row"><span className="lb-about-icon" data-tone="store"><Icon name="storefront" weight="fill" size={15} color="var(--orange-500)" /></span><span><b>Store</b> — your team at {USER.store}</span></div>
              <div className="lb-about-row"><span className="lb-about-icon"><Icon name="buildings" weight="fill" size={15} color="var(--violet-300)" /></span><span><b>Company</b> — every store in your company</span></div>
              <div className="lb-about-row"><span className="lb-about-icon"><Icon name="globe-hemisphere-west" weight="fill" size={15} color="var(--color-primary)" /></span><span><b>Universe</b> — every Pryzer, every company</span></div>
            </div>
          </div>
        </div>
      )}

      <div className="lb-you-pill">
        <span className="lb-you-avatar">{self.photo ? <img src={self.photo} alt={self.name} /> : initials(self.name)}</span>
        <div className="lb-you-info">
          <span className="lb-you-label">You · #{self.rank} {mode === 'points' && <React.Fragment><Icon name="target" weight="bold" size={10} color="currentColor" />{self.goals}</React.Fragment>}</span>
          {gap > 0 && <span className="lb-you-gap">{gap.toLocaleString()} {mode === 'points' ? 'pts' : 'kudos'} behind #{self.rank - 1}</span>}
        </div>
        <span className="lb-you-score">{self.score.toLocaleString()}</span>
        <RankArrow change={self.rankChange} />
      </div>
    </div>
  );
}

window.PryzeScreens = Object.assign(window.PryzeScreens || {}, { LeaderboardScreen });
