// pl.sportzone.is — Premier League TV guide v1
// Same visual language as worldcup.sportzone.is, but fixtures come live from
// /api/fixtures (api-football proxy) instead of a hardcoded schedule, and the
// tab structure is competition-based (PL / FA Cup / League Cup) with a
// date-strip navigator like the main sportzone.is site.

// ── Competitions ──────────────────────────────────────────────────────────────
// API-Football league ids: PL 39, FA Cup 45, League Cup (Carabao) 48.
// Cup tabs appear automatically once the API returns fixtures for them.
const COMPS = [
  { id:'pl',     name:'Premier League', short:'PL',  sub:'FIXTURES' },
  { id:'facup',  name:'FA Cup',         short:'FA',  sub:'FIXTURES' },
  { id:'eflcup', name:'League Cup',     short:'EFL', sub:'FIXTURES' },
];

// ── Countries & broadcasters ──────────────────────────────────────────────────
// channels: default broadcaster per competition. Set to null → badge shows TBD.
// CH_OVERRIDES lets you pin a specific channel for a single fixture id, e.g.
// the Prime Video match of the round in Sweden:
//   se: { 1234567: 'Prime Video' }
const COUNTRIES = [
  { code:'is', flag:'🇮🇸', name:'Iceland', tz:'Atlantic/Reykjavik',
    channels:{ pl:'Stöð 2 Sport', facup:null, eflcup:null },
    note:'Sýn (Stöð 2 Sport) holds exclusive Premier League rights in Iceland through the 2027/28 season.' },
  { code:'se', flag:'🇸🇪', name:'Sweden', tz:'Europe/Stockholm',
    channels:{ pl:'Viaplay / V Sport', facup:null, eflcup:null },
    note:'Viaplay (V Sport) holds Premier League rights in Sweden through 2027/28. One match per round is shown exclusively on Prime Video.' },
];

const CH_OVERRIDES = {
  is: {},   // fixtureId → channel name
  se: {},
};

function getChannel(fixtureId, comp, countryCode) {
  const o = CH_OVERRIDES[countryCode]?.[fixtureId];
  if (o) return o;
  const c = COUNTRIES.find(x => x.code === countryCode);
  return c?.channels?.[comp] || 'TBD';
}

// Browser timezone → country code (only supported countries)
const TZ_TO_COUNTRY = {
  'Atlantic/Reykjavik':'is',
  'Europe/Stockholm':'se',
};
function detectCountry() {
  try {
    const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
    return TZ_TO_COUNTRY[tz] || null;
  } catch(e) { return null; }
}

// ── Helpers ───────────────────────────────────────────────────────────────────
const TZ_IS = 'Atlantic/Reykjavik';
const fmt24    = (iso, tz) => new Date(iso).toLocaleTimeString('en-GB',{hour:'2-digit',minute:'2-digit',hour12:false,timeZone:tz||TZ_IS});
const fmtDay   = (iso, tz) => new Date(iso).toLocaleDateString('en-GB',{weekday:'long',day:'numeric',month:'long',timeZone:tz||TZ_IS});
const fmtChip  = (iso, tz) => {
  const d = new Date(iso);
  return {
    wd:  d.toLocaleDateString('en-GB',{weekday:'short',timeZone:tz||TZ_IS}).toUpperCase(),
    day: d.toLocaleDateString('en-GB',{day:'numeric',timeZone:tz||TZ_IS}),
    mon: d.toLocaleDateString('en-GB',{month:'short',timeZone:tz||TZ_IS}).toUpperCase(),
  };
};
const isoDay   = (iso, tz) => new Date(iso).toLocaleDateString('sv-SE',{timeZone:tz||TZ_IS});
const todayStr = (tz) => new Date().toLocaleDateString('sv-SE',{timeZone:tz||TZ_IS});

const LIVE_S = new Set(['1H','HT','2H','ET','BT','P','SUSP','INT','LIVE']);
const DONE_S = new Set(['FT','AET','PEN']);
const OFF_S  = new Set(['PST','CANC','ABD','AWD','WO']);

function endTime(iso) { return new Date(new Date(iso).getTime() + 115*60000); }

const LS_COUNTRY = 'pl_country';
const THEME_KEY  = 'if_v2_theme';

// Shorten API round labels: "Regular Season - 12" → "MATCHWEEK 12"
function roundLabel(round, comp) {
  if (!round) return null;
  const mw = round.match(/Regular Season\s*-\s*(\d+)/i);
  if (mw) return `MATCHWEEK ${mw[1]}`;
  return round.toUpperCase();
}

// ── Main component ────────────────────────────────────────────────────────────
function PLApp({ mobile, dark, onThemeChange }) {
  const isDark = dark;

  const [tab, setTab] = React.useState('pl');            // today | pl | facup | eflcup | stats
  const [fx, setFx]   = React.useState({ pl:null, facup:null, eflcup:null }); // null = loading
  const [selDate, setSelDate] = React.useState({});      // per-comp selected date, {} = auto
  const [search, setSearch]   = React.useState('');
  const [statsData, setStatsData] = React.useState(null);
  const [, tick] = React.useState(0);
  const [country, setCountry] = React.useState(() => {
    try {
      const saved = localStorage.getItem(LS_COUNTRY);
      if (saved && COUNTRIES.find(c => c.code === saved)) return saved;
    } catch(e) {}
    return detectCountry() || 'is';
  });
  const handleCountry = c => {
    setCountry(c);
    try { localStorage.setItem(LS_COUNTRY, c); } catch(e) {}
  };
  const tz = COUNTRIES.find(c => c.code === country)?.tz || TZ_IS;

  React.useEffect(() => {
    const t = setInterval(() => tick(n => n+1), 30000);
    return () => clearInterval(t);
  }, []);

  // Fetch fixtures for all competitions. PL polls every 2 min (live scores),
  // cups every 10 min. Server caches on the Vercel CDN so this is cheap.
  React.useEffect(() => {
    let alive = true;
    const load = (comp) => fetch(`/api/fixtures?comp=${comp}`)
      .then(r => r.json())
      .then(data => { if (alive && Array.isArray(data.fixtures)) setFx(prev => ({...prev, [comp]:data.fixtures})); })
      .catch(() => { if (alive) setFx(prev => ({...prev, [comp]: prev[comp] || []})); });
    ['pl','facup','eflcup'].forEach(load);
    const t1 = setInterval(() => load('pl'), 120000);
    const t2 = setInterval(() => { load('facup'); load('eflcup'); }, 600000);
    return () => { alive = false; clearInterval(t1); clearInterval(t2); };
  }, []);

  // Player stats (PL top scorers / assists) — cached 30 min server-side
  React.useEffect(() => {
    fetch('/api/stats')
      .then(r => r.json())
      .then(data => { if (data.scorers) setStatsData(data); })
      .catch(() => {});
  }, []);

  // ── Palette — identical to worldcup app ──────────────────────────────────────
  const pal = isDark ? {
    bg:'#222222', fg:'#F4F4F5', card:'#2A2A2A', card2:'#2E2E2E',
    hair:'#333333', hair2:'#3C3C3C', muted:'#7B7B82',
    accent:'#C8FF3D', accentFg:'#0A0A0B', accentSoft:'rgba(200,255,61,0.13)',
    panelBg:'#171717',
    badgeColor:'#C8FF3D', badgeBg:'rgba(200,255,61,0.14)',
  } : {
    bg:'#F4F3F0', fg:'#0A0A0B', card:'#ECEAE6', card2:'#F4F3F0',
    hair:'#D8D6D2', hair2:'#CBC9C4', muted:'#76736C',
    accent:'#F26419', accentFg:'#FFFFFF', accentSoft:'rgba(242,100,25,0.12)',
    panelBg:'#E5E3DF',
    badgeColor:'#F26419', badgeBg:'rgba(242,100,25,0.14)',
  };

  React.useEffect(() => { document.body.style.background = isDark ? '#222222' : '#F4F3F0'; }, [isDark]);

  // ── Derived ───────────────────────────────────────────────────────────────────
  const allFx   = ['pl','facup','eflcup'].flatMap(c => (fx[c]||[]).map(f => ({...f, comp:c})));
  const today   = todayStr(tz);
  const todayMs = allFx.filter(f => isoDay(f.iso,tz) === today).sort((a,b) => a.iso.localeCompare(b.iso));
  const liveMs  = allFx.filter(f => LIVE_S.has(f.status));
  const searchQ = search.trim().toLowerCase();
  const searchRes = searchQ ? allFx.filter(f =>
    f.home.toLowerCase().includes(searchQ) ||
    f.away.toLowerCase().includes(searchQ) ||
    (f.venue||'').toLowerCase().includes(searchQ)
  ).sort((a,b) => a.iso.localeCompare(b.iso)) : null;

  // Cup tabs only shown once the API has fixtures for them
  const visibleComps = COMPS.filter(c => c.id === 'pl' || (fx[c.id] && fx[c.id].length > 0));

  // ── Styles (copied from worldcup app for a consistent look) ──────────────────
  const S = {
    root:{ minHeight:'100vh', background:pal.bg, color:pal.fg,
      fontFamily:'"Inter",system-ui,sans-serif', letterSpacing:'-0.005em',
      display:'flex', flexDirection:'column' },
    topBar:{ display:'flex', flexDirection: mobile?'column':'row', alignItems: mobile?'stretch':'center',
      gap: mobile?8:20,
      padding:mobile?'10px 16px':'18px 32px',
      borderBottom:`1px solid ${pal.hair}`,
      position:'sticky', top:0, zIndex:50, background:pal.bg },
    topRow:{ display:'flex', alignItems:'center', gap:10 },
    bottomRow:{ display:'flex', alignItems:'center', gap:8 },
    iconBtn:{ width:38, height:38, borderRadius:10, cursor:'pointer',
      background:pal.card, border:`1px solid ${pal.hair}`,
      color:pal.fg, display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 },
    searchWrap:{ flex:1, maxWidth:380, display:'flex', alignItems:'center', gap:10,
      background:pal.card, border:`1px solid ${pal.hair}`,
      borderRadius:10, padding:'9px 14px', marginLeft:'auto' },
    searchInput:{ flex:1, border:'none', outline:'none', background:'transparent',
      color:pal.fg, fontSize:13, fontFamily:'inherit' },

    roundStrip:{ display:'flex', overflowX:'auto', scrollbarWidth:'none',
      borderBottom:`1px solid ${pal.hair}` },
    roundTab:(a) => ({ padding:mobile?'11px 16px 9px':'13px 22px 11px',
      cursor:'pointer', flexShrink:0, whiteSpace:'nowrap',
      borderRight:`1px solid ${pal.hair}`,
      background:a?pal.accent:'transparent', color:a?pal.accentFg:pal.fg,
      border:'none', textAlign:'left', fontFamily:'inherit',
      transition:'background .12s', display:'flex', flexDirection:'column', gap:2 }),
    rtWk:(a) => ({ fontSize:mobile?8.5:10, textTransform:'uppercase',
      letterSpacing:'0.14em', fontWeight:700, opacity:a?0.85:0.45 }),
    rtName:{ fontSize:mobile?17:20, fontWeight:700,
      fontFamily:'"JetBrains Mono",monospace', letterSpacing:'-0.02em', lineHeight:1, marginTop:2 },
    rtSub:(a) => ({ fontSize:9, marginTop:4, fontWeight:700, textTransform:'uppercase',
      letterSpacing:'0.10em', opacity:a?0.85:0.35 }),

    // Date strip — the sportzone.is-style day navigator
    dateBar:{ display:'flex', alignItems:'center',
      padding:mobile?'8px 12px':'10px 24px',
      borderBottom:`1px solid ${pal.hair}`, gap:6,
      overflowX:'auto', scrollbarWidth:'none' },
    dateChip:(a, isPast) => ({ minWidth:mobile?54:62, borderRadius:10,
      cursor:'pointer', flexShrink:0, padding:mobile?'7px 8px':'8px 10px',
      background:a?pal.accent:'transparent', color:a?pal.accentFg:(isPast?pal.muted:pal.fg),
      border:`1px solid ${a?pal.accent:pal.hair2}`, fontFamily:'inherit',
      display:'flex', flexDirection:'column', alignItems:'center', gap:1,
      transition:'background .12s' }),
    dcWd:{ fontSize:8.5, fontWeight:800, letterSpacing:'0.12em', opacity:0.7 },
    dcDay:{ fontSize:mobile?16:18, fontWeight:800, fontFamily:'"JetBrains Mono",monospace', lineHeight:1.1 },
    dcMon:{ fontSize:8.5, fontWeight:700, letterSpacing:'0.10em', opacity:0.7 },

    body:{ flex:1, display:mobile?'block':'flex' },
    livePane:{ width:280, flexShrink:0, borderRight:`1px solid ${pal.hair}`,
      padding:'24px 20px', background:pal.panelBg,
      position:'sticky', top:0, maxHeight:'calc(100vh - 57px)', overflowY:'auto' },
    timeline:{ flex:1, padding:'0 0 48px', overflowY:'auto', minWidth:0 },

    dateHdr:{ fontSize:mobile?15:17, fontWeight:800, letterSpacing:'-0.01em',
      color:pal.fg, textTransform:'capitalize',
      padding:mobile?'24px 16px 10px':'28px 32px 12px',
      borderBottom:`1px solid ${pal.hair}`, marginBottom:0 },

    evRow:{ borderBottom:`1px solid ${pal.hair}`, padding:mobile?'14px 16px':'16px 32px' },
    evGrid:{ display:'grid',
      gridTemplateColumns:mobile?'68px 1fr auto':'80px 52px 1fr auto',
      gap:mobile?'0 10px':'0 14px', alignItems:'center' },
    evTimeCol:{ display:'flex', flexDirection:'column', alignItems:'flex-start', gap:3 },
    evTime:{ fontSize:mobile?20:22, fontWeight:700,
      fontFamily:'"JetBrains Mono",monospace', letterSpacing:'-0.02em', lineHeight:1 },
    evTimeEnd:{ fontSize:10.5, color:pal.muted, fontWeight:500,
      fontFamily:'"JetBrains Mono",monospace' },
    evIcon:{ width:52, height:52, borderRadius:12,
      background:isDark?'#2A2A2A':'#ECEAE6',
      border:`1px solid ${pal.hair2}`,
      display:'flex', alignItems:'center', justifyContent:'center',
      color:pal.fg, flexShrink:0, overflow:'hidden' },
    evContent:{ minWidth:0 },
    evMeta:{ display:'flex', alignItems:'center', gap:6, marginBottom:4, flexWrap:'wrap' },
    evMetaText:{ fontSize:10, fontWeight:700, letterSpacing:'0.12em',
      color:pal.muted, textTransform:'uppercase' },
    evMetaDot:{ fontSize:10, color:pal.muted },
    roundBadge:{ padding:'2px 7px', borderRadius:3,
      fontSize:9.5, fontWeight:800, letterSpacing:'0.14em',
      color:pal.badgeColor, background:pal.badgeBg },
    liveBadge:{ display:'inline-flex', alignItems:'center', gap:4,
      padding:'2px 7px', borderRadius:3,
      background:'rgba(255,59,71,0.16)', color:'#FF3B47',
      fontSize:9.5, fontWeight:800, letterSpacing:'0.14em' },
    liveDotEl:{ width:6, height:6, borderRadius:'50%', background:'#FF3B47',
      animation:'ifPulse 1.4s ease-in-out infinite', flexShrink:0 },
    evTitle:{ fontWeight:700, fontSize:mobile?15:16,
      letterSpacing:'-0.01em', lineHeight:1.25, marginBottom:3,
      whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis' },
    evSub:{ fontSize:mobile?11:12, color:pal.muted, display:'flex', alignItems:'center', gap:4 },
    evStation:{ display:'flex', flexDirection:'column', alignItems:'center', gap:3, flexShrink:0 },

    countrySel:{ height:36, padding:'0 10px', borderRadius:10, cursor:'pointer',
      background:pal.card, border:`1px solid ${pal.hair}`, color:pal.fg,
      fontSize:13, fontFamily:'inherit', fontWeight:600, flexShrink:0, outline:'none' },

    liveHd:{ display:'flex', alignItems:'center', gap:8, marginBottom:16 },
    liveDotBig:{ width:8, height:8, borderRadius:'50%', background:'#FF3B47',
      animation:'ifPulse 1.4s ease-in-out infinite', flexShrink:0 },
    liveLabel:{ fontSize:11, fontWeight:800, letterSpacing:'0.12em',
      color:pal.muted, textTransform:'uppercase' },
    liveCount:{ marginLeft:'auto', minWidth:22, height:22, padding:'0 7px',
      background:'#FF3B47', color:'#fff', borderRadius:99, fontSize:11, fontWeight:800,
      display:'flex', alignItems:'center', justifyContent:'center',
      fontFamily:'"JetBrains Mono",monospace' },
    liveMiniCard:{ background:pal.card, border:`1px solid ${pal.hair}`,
      borderRadius:10, padding:'12px 14px', marginBottom:8 },
    emptyMsg:{ textAlign:'center', color:pal.muted, padding:'48px 16px', fontSize:14 },
    sectionHdr:{ fontSize:11, fontWeight:800, letterSpacing:'0.14em',
      color:pal.muted, textTransform:'uppercase',
      padding:mobile?'22px 16px 6px':'24px 32px 6px' },
  };

  // ── Channel badge ─────────────────────────────────────────────────────────────
  function ChannelBadge({ fixture }) {
    const ch = getChannel(fixture.id, fixture.comp, country);
    return (
      <div style={S.evStation}>
        <span style={{
          display:'inline-flex', alignItems:'center', justifyContent:'center',
          padding:'5px 10px', borderRadius:8,
          background:pal.accentSoft, border:`1px solid ${pal.badgeColor}`,
          fontSize:mobile?12:14, fontWeight:800, color:pal.badgeColor,
          letterSpacing:'0.03em', fontFamily:'"JetBrains Mono",monospace',
          textAlign:'center', lineHeight:1.3, whiteSpace:'nowrap',
        }}>
          {ch}
        </span>
      </div>
    );
  }

  // ── Match card ────────────────────────────────────────────────────────────────
  function MatchCard({ fixture }) {
    const f = fixture;
    const start  = fmt24(f.iso, tz);
    const end    = fmt24(endTime(f.iso).toISOString(), tz);
    const isLive = LIVE_S.has(f.status);
    const isFT   = DONE_S.has(f.status);
    const isOff  = OFF_S.has(f.status);
    const hasScore = f.hs != null && f.as != null && (isLive || isFT);
    const hasPens  = f.status === 'PEN' && f.phs != null && f.pas != null;

    const homeWon = isFT && hasScore && (hasPens ? f.phs > f.pas : f.hs > f.as);
    const awayWon = isFT && hasScore && (hasPens ? f.pas > f.phs : f.as > f.hs);
    const homeOp = isFT ? (homeWon ? 1 : awayWon ? 0.35 : 0.65) : 1;
    const awayOp = isFT ? (awayWon ? 1 : homeWon ? 0.35 : 0.65) : 1;

    const compName = COMPS.find(c => c.id === f.comp)?.name || 'Football';
    const rl = roundLabel(f.round, f.comp);

    return (
      <div style={S.evRow}>
        <div style={S.evGrid}>
          {/* TIME */}
          <div style={S.evTimeCol}>
            <span style={{
              ...S.evTime,
              color: isLive ? '#FF3B47' : isFT ? pal.muted : pal.fg
            }}>{start}</span>
            <span style={S.evTimeEnd}>{isLive && f.elapsed != null ? `${f.elapsed}′` : `to ${end}`}</span>
          </div>

          {/* ICON — home team crest, desktop only */}
          {!mobile && (
            <div style={S.evIcon}>
              {f.homeLogo
                ? <img src={f.homeLogo} alt="" style={{width:34,height:34,objectFit:'contain'}}
                    onError={e => { e.target.style.display='none'; }}/>
                : <span style={{fontSize:22}}>⚽</span>}
            </div>
          )}

          {/* CONTENT */}
          <div style={S.evContent}>
            <div style={S.evMeta}>
              <span style={S.evMetaText}>{compName}</span>
              {rl && <>
                <span style={S.evMetaDot}>·</span>
                <span style={S.roundBadge}>{rl}</span>
              </>}
              {isLive && (
                <div style={S.liveBadge}>
                  <span style={S.liveDotEl}/>
                  {f.status === 'HT' ? 'HT' : 'LIVE'}
                </div>
              )}
              {isFT && (
                <div style={{ padding:'2px 7px', borderRadius:3,
                  background:'rgba(128,128,128,0.12)', color:pal.muted,
                  fontSize:9.5, fontWeight:800, letterSpacing:'0.14em' }}>
                  {f.status}
                </div>
              )}
              {isOff && (
                <div style={{ padding:'2px 7px', borderRadius:3,
                  background:'rgba(255,59,71,0.10)', color:'#FF3B47',
                  fontSize:9.5, fontWeight:800, letterSpacing:'0.14em' }}>
                  {f.status === 'PST' ? 'POSTPONED' : f.status}
                </div>
              )}
            </div>
            <div style={{ ...S.evTitle, color: isFT ? pal.muted : pal.fg }}>
              {hasScore ? (
                <>
                  <span style={{opacity:homeOp, fontWeight:homeWon?700:undefined}}>{f.home}</span>
                  {homeWon && <span style={{color:pal.accent,fontSize:'0.7em',margin:'0 1px 0 3px',verticalAlign:'middle'}}>✓</span>}
                  <span style={{
                    fontFamily:'"JetBrains Mono",monospace', fontWeight:900,
                    color: isLive ? '#FF3B47' : pal.fg, padding:'0 4px',
                  }}> {f.hs}–{f.as} </span>
                  {awayWon && <span style={{color:pal.accent,fontSize:'0.7em',margin:'0 3px 0 1px',verticalAlign:'middle'}}>✓</span>}
                  <span style={{opacity:awayOp, fontWeight:awayWon?700:undefined}}>{f.away}</span>
                </>
              ) : (
                <>{f.home} – {f.away}</>
              )}
            </div>
            {hasPens && (
              <div style={{ fontFamily:'"JetBrains Mono",monospace',
                fontSize:mobile?11:12, fontWeight:700, color:pal.muted, marginBottom:3 }}>
                Penalties {f.phs}–{f.pas}
              </div>
            )}
            <div style={S.evSub}>
              <span style={{ color:'#FF3B47', fontSize:11 }}>📍</span>
              <span>{f.venue || '—'}</span>
            </div>
          </div>

          {/* STATION */}
          <ChannelBadge fixture={f} />
        </div>
      </div>
    );
  }

  // ── Group by date ─────────────────────────────────────────────────────────────
  function ByDate({ matches }) {
    if (!matches.length) return (
      <div style={S.emptyMsg}><div style={{fontWeight:700}}>No matches found.</div></div>
    );
    const byDate = {};
    matches.forEach(m => { const d=isoDay(m.iso,tz); if(!byDate[d])byDate[d]=[]; byDate[d].push(m); });
    return Object.entries(byDate).sort().map(([d,arr]) => {
      arr.sort((a,b) => a.iso.localeCompare(b.iso));
      return (
        <div key={d}>
          <div style={S.dateHdr}>{fmtDay(arr[0].iso,tz)}</div>
          {arr.map(m => <MatchCard key={m.id} fixture={m}/>)}
        </div>
      );
    });
  }

  // ── Date strip + competition view ─────────────────────────────────────────────
  function CompView({ comp }) {
    const list = fx[comp];
    if (list === null) return (
      <div style={S.emptyMsg}><div style={{fontWeight:700}}>Loading fixtures…</div></div>
    );
    const withComp = list.map(f => ({...f, comp}));
    if (!withComp.length) return (
      <div style={S.emptyMsg}><div style={{fontWeight:700}}>No fixtures announced yet.</div></div>
    );

    const dates = [...new Set(withComp.map(f => isoDay(f.iso,tz)))].sort();
    // Auto selection: today if it has matches, else the next matchday, else the last
    const auto = dates.includes(today) ? today : (dates.find(d => d > today) || dates[dates.length-1]);
    const sel  = selDate[comp] && dates.includes(selDate[comp]) ? selDate[comp] : auto;

    const dayMs = withComp.filter(f => isoDay(f.iso,tz) === sel);

    // Scroll the selected chip into view — once per comp+date (module-level
    // guard, because this component remounts on every parent re-render).
    const stripRef = React.useRef(null);
    React.useEffect(() => {
      const key = comp + '|' + sel;
      if (window.__plStripScrolled === key) return;
      const el = stripRef.current?.querySelector('[data-sel="1"]');
      if (el) { el.scrollIntoView({ inline:'center', block:'nearest' }); window.__plStripScrolled = key; }
    }, [sel, comp]);

    return (
      <>
        <div style={S.dateBar} data-sh ref={stripRef}>
          {dates.map(d => {
            const a = d === sel;
            const c = fmtChip(d + 'T12:00:00Z', 'UTC');
            const isPast = d < today;
            return (
              <button key={d} style={S.dateChip(a, isPast)} data-sel={a?'1':'0'}
                onClick={() => setSelDate(prev => ({...prev, [comp]: d}))}>
                <span style={S.dcWd}>{d === today ? 'TODAY' : c.wd}</span>
                <span style={S.dcDay}>{c.day}</span>
                <span style={S.dcMon}>{c.mon}</span>
              </button>
            );
          })}
        </div>
        <ByDate matches={dayMs}/>
      </>
    );
  }

  function TodayView() {
    const loading = fx.pl === null;
    if (loading) return (
      <div style={S.emptyMsg}><div style={{fontWeight:700}}>Loading fixtures…</div></div>
    );
    if (!todayMs.length) {
      const next = allFx.filter(f => new Date(f.iso) > new Date()).sort((a,b) => a.iso.localeCompare(b.iso))[0];
      return (
        <div style={S.emptyMsg}>
          <div style={{fontWeight:700}}>No match today</div>
          {next && <div style={{marginTop:8,fontSize:12}}>Next: {fmtDay(next.iso,tz)} {fmt24(next.iso,tz)} — {next.home} v {next.away}</div>}
        </div>
      );
    }
    return todayMs.map(m => <MatchCard key={m.comp+m.id} fixture={m}/>);
  }

  function SearchView() {
    if (!searchRes.length) return <div style={S.emptyMsg}>No results found.</div>;
    return <ByDate matches={searchRes}/>;
  }

  // ── Stats view — top scorers / assists / involvements ────────────────────────
  function StatsView() {
    if (!statsData) return (
      <div style={S.emptyMsg}>
        <div style={{fontWeight:700}}>Loading statistics…</div>
        <div style={{marginTop:8,fontSize:12,color:pal.muted}}>Stats appear once matches have been played.</div>
      </div>
    );
    if (!statsData.scorers?.length) return (
      <div style={S.emptyMsg}>
        <div style={{fontWeight:700}}>No stats available yet</div>
        <div style={{marginTop:8,fontSize:12,color:pal.muted}}>Check back after the first matchweek.</div>
      </div>
    );

    function PlayerRow({ player, statValue, statLabel, rank }) {
      return (
        <div style={{
          display:'grid', gridTemplateColumns:'28px 48px 1fr auto',
          gap:mobile?'0 10px':'0 14px', alignItems:'center',
          padding:mobile?'12px 16px':'14px 32px',
          borderBottom:`1px solid ${pal.hair}`,
        }}>
          <div style={{fontSize:13,fontWeight:800,color:rank<=3?pal.accent:pal.muted,
            fontFamily:'"JetBrains Mono",monospace',textAlign:'center'}}>
            {rank}
          </div>
          <div style={{width:44,height:44,borderRadius:'50%',overflow:'hidden',
            border:`1px solid ${pal.hair2}`,background:pal.card,flexShrink:0}}>
            {player.photo
              ? <img src={player.photo} alt={player.name}
                  style={{width:'100%',height:'100%',objectFit:'cover'}}
                  onError={e => { e.target.style.display='none'; }}/>
              : null}
          </div>
          <div style={{minWidth:0}}>
            <div style={{fontWeight:700,fontSize:mobile?14:15,
              whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>
              {player.name}
            </div>
            <div style={{display:'flex',alignItems:'center',gap:6,marginTop:3}}>
              {player.teamLogo && <img src={player.teamLogo} alt={player.team}
                style={{width:16,height:16,objectFit:'contain',flexShrink:0}}
                onError={e => { e.target.style.display='none'; }}/>}
              <span style={{fontSize:11,color:pal.muted,fontWeight:500}}>{player.team}</span>
            </div>
          </div>
          <div style={{textAlign:'right',flexShrink:0}}>
            <div style={{fontSize:mobile?22:26,fontWeight:800,
              fontFamily:'"JetBrains Mono",monospace', color:pal.accent,lineHeight:1}}>
              {statValue}
            </div>
            <div style={{fontSize:9,fontWeight:700,letterSpacing:'0.10em',
              color:pal.muted,textTransform:'uppercase',marginTop:2}}>
              {statLabel}
            </div>
          </div>
        </div>
      );
    }

    const involveMap = {};
    (statsData.scorers || []).forEach(p => {
      const k = `${p.name}|${p.team}`;
      involveMap[k] = { ...p, goals:p.goals||0, assists:p.assists||0 };
    });
    (statsData.assists || []).forEach(p => {
      const k = `${p.name}|${p.team}`;
      if (!involveMap[k]) involveMap[k] = { ...p, goals:p.goals||0 };
      involveMap[k].assists = p.assists || 0;
      if (!involveMap[k].photo) involveMap[k].photo = p.photo;
    });
    const involvements = Object.values(involveMap)
      .map(p => ({ ...p, involvements: (p.goals||0) + (p.assists||0) }))
      .sort((a,b) => b.involvements - a.involvements || b.goals - a.goals)
      .slice(0,10);

    const sections = [
      { title:'Top Scorers', icon:'⚽', list:statsData.scorers?.slice(0,10)||[], key:'goals', label:'GOALS' },
      { title:'Top Assists', icon:'🎯', list:statsData.assists?.slice(0,10)||[], key:'assists', label:'ASSISTS' },
      { title:'Goal Involvements', icon:'🔥', list:involvements, key:'involvements',
        label:p => `${p.goals||0}G · ${p.assists||0}A` },
    ];

    return (
      <>
        {sections.map(sec => (
          <div key={sec.title}>
            <div style={{...S.sectionHdr, display:'flex', alignItems:'center', gap:8}}>
              <span>{sec.icon}</span>
              <span>{sec.title}</span>
            </div>
            {sec.list.map((p, i) => (
              <PlayerRow key={p.name+i} player={p}
                statValue={p[sec.key]}
                statLabel={typeof sec.label === 'function' ? sec.label(p) : sec.label}
                rank={i+1}/>
            ))}
          </div>
        ))}
      </>
    );
  }

  // ── Live mini card (sidebar) ──────────────────────────────────────────────────
  function LiveMini({ match }) {
    return (
      <div style={S.liveMiniCard}>
        <div style={{display:'flex',alignItems:'center',gap:6,marginBottom:8}}>
          <span style={{fontSize:13,fontWeight:700,fontFamily:'"JetBrains Mono",monospace',color:'#FF3B47'}}>
            {match.elapsed != null ? `${match.elapsed}′` : fmt24(match.iso,tz)}
          </span>
          <div style={{...S.liveBadge,marginLeft:'auto',padding:'1px 6px'}}>
            <span style={S.liveDotEl}/>LIVE
          </div>
        </div>
        <div style={{fontWeight:700,fontSize:13,marginBottom:3}}>
          {match.home}{match.hs != null && <span style={{fontFamily:'"JetBrains Mono",monospace',marginLeft:6}}>{match.hs}</span>}
        </div>
        <div style={{fontWeight:700,fontSize:13,marginBottom:6}}>
          {match.away}{match.as != null && <span style={{fontFamily:'"JetBrains Mono",monospace',marginLeft:6}}>{match.as}</span>}
        </div>
        <div style={{fontSize:10,color:pal.muted}}>📍 {match.venue || '—'}</div>
      </div>
    );
  }

  // ── Render ────────────────────────────────────────────────────────────────────
  const todayCount = todayMs.length;
  const activeCountry = COUNTRIES.find(c => c.code === country);

  const tabs = [
    { id:'today', wk:'Today', name:String(todayCount||'0'), sub:'MATCHES TODAY' },
    ...visibleComps.map(c => ({
      id:c.id, wk:c.name,
      name:String((fx[c.id]||[]).length || '—'),
      sub:c.sub,
    })),
    { id:'stats', wk:'Statistics', name:'★', sub:'TOP PLAYERS' },
  ];

  return (
    <div style={S.root}>
      <style>{`
        @keyframes ifPulse{0%{box-shadow:0 0 0 0 rgba(255,59,71,.55)}70%{box-shadow:0 0 0 8px rgba(255,59,71,0)}100%{box-shadow:0 0 0 0 rgba(255,59,71,0)}}
        *{-webkit-tap-highlight-color:transparent}
        [data-sh]::-webkit-scrollbar{display:none}
      `}</style>

      {/* TOP BAR */}
      <div style={S.topBar}>
        {mobile ? (<>
          <div style={S.topRow}>
            <img src={`assets/logos/sportzone-${isDark?'dark':'light'}.svg`} alt="SportZone"
              style={{height:24,width:'auto',display:'block'}}/>
            <div style={{flex:1}}/>
            <select style={S.countrySel} value={country}
              onChange={e => handleCountry(e.target.value)} title="Select country">
              {COUNTRIES.map(c => (
                <option key={c.code} value={c.code}>{c.flag} {c.name}</option>
              ))}
            </select>
          </div>
          <div style={S.bottomRow}>
            <div style={{...S.searchWrap, maxWidth:'none', marginLeft:0, flex:1}}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={pal.muted} strokeWidth="2" strokeLinecap="round">
                <circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/>
              </svg>
              <input style={S.searchInput} placeholder="Search teams, venues…"
                value={search} onChange={e => setSearch(e.target.value)}/>
              {search && <button onClick={() => setSearch('')}
                style={{background:'none',border:'none',cursor:'pointer',color:pal.muted,fontSize:16,lineHeight:1,padding:'0 2px',display:'flex',alignItems:'center'}}>×</button>}
            </div>
            <button style={S.iconBtn} onClick={() => onThemeChange(!isDark)}>
              {isDark
                ? <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>
                : <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>}
            </button>
            <a href="https://ko-fi.com/torfason" target="_blank" rel="noopener noreferrer"
               title="Support SportZone on Ko-fi" style={{ ...S.iconBtn, textDecoration:'none' }}>
              <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
                <path d="M18 8h1a4 4 0 0 1 0 8h-1"/>
                <path d="M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z"/>
                <line x1="6" y1="1" x2="6" y2="4"/><line x1="10" y1="1" x2="10" y2="4"/><line x1="14" y1="1" x2="14" y2="4"/>
              </svg>
            </a>
          </div>
        </>) : (<>
          <div style={{display:'flex',alignItems:'center',gap:12,flexShrink:0}}>
            <img src={`assets/logos/sportzone-${isDark?'dark':'light'}.svg`} alt="SportZone"
              style={{height:26,width:'auto',display:'block'}}/>
          </div>
          <div>
            <div style={{fontWeight:800,fontSize:18,letterSpacing:'-0.02em',lineHeight:1}}>Premier League 2026/27</div>
            <div style={{fontSize:10,color:pal.muted,letterSpacing:'0.10em',marginTop:4}}>AUG – MAY · WHERE TO WATCH EVERY MATCH</div>
          </div>
          <div style={{...S.searchWrap}}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke={pal.muted} strokeWidth="2" strokeLinecap="round">
              <circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/>
            </svg>
            <input style={S.searchInput} placeholder="Search teams, venues…"
              value={search} onChange={e => setSearch(e.target.value)}/>
            {search && <button onClick={() => setSearch('')}
              style={{background:'none',border:'none',cursor:'pointer',color:pal.muted,fontSize:16,lineHeight:1,padding:'0 2px',display:'flex',alignItems:'center'}}>×</button>}
          </div>
          <button style={S.iconBtn} onClick={() => onThemeChange(!isDark)}>
            {isDark
              ? <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>
              : <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>}
          </button>
          <a href="https://ko-fi.com/torfason" target="_blank" rel="noopener noreferrer"
             title="Support SportZone on Ko-fi" style={{ ...S.iconBtn, textDecoration:'none' }}>
            <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <path d="M18 8h1a4 4 0 0 1 0 8h-1"/>
              <path d="M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z"/>
              <line x1="6" y1="1" x2="6" y2="4"/><line x1="10" y1="1" x2="10" y2="4"/><line x1="14" y1="1" x2="14" y2="4"/>
            </svg>
          </a>
          <select style={S.countrySel} value={country}
            onChange={e => handleCountry(e.target.value)} title="Select country">
            {COUNTRIES.map(c => (
              <option key={c.code} value={c.code}>{c.flag} {c.name}</option>
            ))}
          </select>
        </>)}
      </div>

      {/* LIVE BANNER */}
      {liveMs.length > 0 && (
        <div style={{background:'rgba(255,59,71,0.10)',borderBottom:'1px solid rgba(255,59,71,0.25)',
          padding:mobile?'8px 16px':'8px 32px',display:'flex',alignItems:'center',gap:10}}>
          <span style={{width:8,height:8,borderRadius:'50%',background:'#FF3B47',
            display:'inline-block',flexShrink:0,animation:'ifPulse 1.4s ease-in-out infinite'}}/>
          <span style={{fontSize:12,fontWeight:700,color:'#FF3B47'}}>
            LIVE: {liveMs.map(m => `${m.home} ${m.hs!=null?m.hs:''}–${m.as!=null?m.as:''} ${m.away}`).join('  ·  ')}
          </span>
        </div>
      )}

      {/* COMPETITION TABS */}
      <div style={S.roundStrip} data-sh>
        {tabs.map(rt => {
          const a = tab===rt.id && !searchRes;
          return (
            <button key={rt.id} style={S.roundTab(a)} onClick={() => {setTab(rt.id); setSearch('');}}>
              <div style={S.rtWk(a)}>{rt.wk}</div>
              <div style={S.rtName}>{rt.name}</div>
              <div style={S.rtSub(a)}>{rt.sub}</div>
            </button>
          );
        })}
        {!mobile && (
          <div style={{flex:1,display:'flex',alignItems:'center',justifyContent:'flex-end',
            padding:'0 32px',color:pal.muted,fontSize:11}}>
            <span style={{fontWeight:700,letterSpacing:'0.08em'}}>
              20 CLUBS · 380 MATCHES · {activeCountry?.channels?.pl || 'TBD'}
            </span>
          </div>
        )}
      </div>

      {/* BODY */}
      <div style={S.body}>
        {!mobile && (
          <div style={S.livePane}>
            <div style={S.liveHd}>
              <span style={S.liveDotBig}/>
              <span style={S.liveLabel}>Live now</span>
              {liveMs.length > 0 && <span style={S.liveCount}>{liveMs.length}</span>}
            </div>
            {liveMs.length === 0
              ? <div style={{color:pal.muted,fontSize:12,lineHeight:1.6}}>No match in progress.</div>
              : liveMs.map(m => <LiveMini key={m.comp+m.id} match={m}/>)}
            {(() => {
              const up = todayMs.filter(m => m.status === 'NS' || m.status === 'TBD');
              if (!up.length) return null;
              return <>
                <div style={{...S.liveLabel,display:'block',marginTop:20,marginBottom:10}}>Today</div>
                {up.slice(0,6).map(m => (
                  <div key={m.comp+m.id} style={{...S.liveMiniCard,marginBottom:6}}>
                    <div style={{fontWeight:700,fontSize:14,fontFamily:'"JetBrains Mono",monospace',marginBottom:4}}>{fmt24(m.iso,tz)}</div>
                    <div style={{fontWeight:700,fontSize:12,marginBottom:2}}>{m.home}</div>
                    <div style={{fontWeight:700,fontSize:12,marginBottom:4}}>{m.away}</div>
                    <div style={{fontSize:10,color:pal.muted}}>📍 {m.venue || '—'}</div>
                  </div>
                ))}
              </>;
            })()}
          </div>
        )}

        {/* Timeline */}
        <div style={S.timeline}>
          {searchRes      ? <SearchView/> :
           tab==='today'  ? <TodayView/> :
           tab==='stats'  ? <StatsView/> :
           <CompView comp={tab}/>}
          <div style={{textAlign:'center',marginTop:32,color:pal.muted,fontSize:11,padding:mobile?'0 16px 16px':'0 32px 16px'}}>
            {activeCountry?.note || ''}
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Root: mobile detection + shared theme (same pattern as sportzone.is) ───────
function isMobileDevice() {
  const byUA = /Mobi|Android|iPhone|iPad|iPod|Windows Phone/i.test(navigator.userAgent);
  const byWidth = window.innerWidth < 768;
  const byPointer = window.matchMedia('(pointer: coarse)').matches;
  return byUA || byWidth || byPointer;
}

function Root() {
  const mobile = React.useMemo(() => isMobileDevice(), []);
  const [dark, setDark] = React.useState(() => {
    try {
      const saved = localStorage.getItem(THEME_KEY);
      if (saved !== null) return saved === 'dark';
    } catch (e) {}
    return window.matchMedia('(prefers-color-scheme: dark)').matches;
  });
  const handleTheme = (isDark) => {
    setDark(isDark);
    try { localStorage.setItem(THEME_KEY, isDark ? 'dark' : 'light'); } catch (e) {}
  };
  return <PLApp mobile={mobile} dark={dark} onThemeChange={handleTheme} />;
}

ReactDOM.createRoot(document.getElementById('root')).render(<Root />);
