// === Main App ===
const { useState, useEffect, useMemo } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "density": "comfortable",
  "fieldStyle": "field",
  "showSchedule": true,
  "showDraft": true,
  "showStats": true,
  "showDepth": true
}/*EDITMODE-END*/;

function App({ data, refreshData }) {
  const [tab, setTab] = useState(() => {
    const hash = window.location.hash.slice(1);
    return hash || 'dashboard';
  });
  const [theme, setTheme] = useState('dark');
  const [side, setSide] = useState('offense');
  const [activePlayer, setActivePlayer] = useState(null);

  const tweaks = window.useTweaks ? window.useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => {}];
  const [t, setT] = tweaks;

  useEffect(() => {
    window.location.hash = tab;
  }, [tab]);

  useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    document.documentElement.setAttribute('data-density', t.density || 'comfortable');
  }, [theme, t.density]);

  // Keyboard: Esc to close modal
  useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') setActivePlayer(null); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  const currentSeason = data.seasons.find(s => s.year === 2026) || data.seasons[data.seasons.length - 1];
  const lastCompletedSeason = data.seasons.slice().reverse().find(s => s.stats.wins + s.stats.losses > 0);

  const totalPlayers = useMemo(() => {
    let n = 0;
    Object.values(data.depthChart.offense).forEach(arr => n += arr.length);
    Object.values(data.depthChart.defense).forEach(arr => n += arr.length);
    Object.values(data.depthChart.specialTeams).forEach(arr => n += arr.length);
    return n;
  }, [data]);

  const winsBySeason = data.seasons.filter(s => s.stats.wins + s.stats.losses > 0).map(s => s.stats.wins);
  const allTimePct = (data.allTime.wins / (data.allTime.wins + data.allTime.losses)).toFixed(3).replace(/^0/, '');

  const [swapMenu, setSwapMenu] = useState(null);

  const handleSwapPlayer = (personnelPackage, posKey, newPlayer) => {
    fetch("https://ravens-api.evagkotsakis.workers.dev/api/personnel-overrides", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        package: personnelPackage,
        position: posKey,
        playerName: newPlayer.name
      })
    })
    .then(res => res.json())
    .then(() => refreshData()) // Re-sync the app instantly
    .catch(err => console.error("Swap failed", err));
  };

  const handleRightClickPlayer = (e, pos, side, currentPackage) => {
    e.preventDefault();
    
    // Determine which roster group to pull from based on the side
    const rosterGroup = side === 'offense' ? data.depthChart.offense : data.depthChart.defense;
    
    let availablePlayers = [];
    
    // Aggregate players from all secondary 'allowedSwaps' positions, fallback to the primary key
    const searchKeys = pos.allowedSwaps || [pos.dataKey || pos.key];
    searchKeys.forEach(swapPosKey => {
      if (rosterGroup[swapPosKey]) {
        availablePlayers = [...availablePlayers, ...rosterGroup[swapPosKey]];
      }
    });

    setSwapMenu({
      x: e.clientX,
      y: e.clientY,
      pos,
      side,
      currentPackage,
      players: availablePlayers
    });
  };

  return (
    <>
      <div className="bg-ambience" />
      <div className="app" data-screen-label={`Tab: ${tab}`}>
        <header className="topbar">
          <div className="brand">
            <img src="assets/baltimore-ravens-logo.svg" alt="Baltimore Ravens" className="brand-mark"/>
            <div className="brand-text">
              <span className="city">Baltimore</span>
              <span className="label">Football Operations</span>
            </div>
          </div>
          <nav className="nav">
            {[
              ['dashboard', 'Overview'],
              ['depth', 'Depth Chart'],
              ['roster', 'Roster'],
              ['draft', 'Draft Room'],
              ['schedule', 'Schedule'],
              ['stats', 'History'],
            ].map(([k, l]) => (
              <button key={k} className={tab === k ? 'active' : ''} onClick={() => setTab(k)}>{l}</button>
            ))}
          </nav>
          <div className="topbar-actions">
            <span className="pill mono accent">2026 SEASON</span>
            <button
              className="icon-btn"
              onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
              aria-label="Toggle theme"
              title="Toggle theme"
            >
              {theme === 'dark' ? (
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><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 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>
              ) : (
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
              )}
            </button>
          </div>
        </header>

        {tab === 'dashboard' && <Dashboard {...{ data, currentSeason, lastCompletedSeason, totalPlayers, allTimePct, winsBySeason, setTab, setActivePlayer, side, setSide, t, handleRightClickPlayer }} />}
        {tab === 'depth' && <DepthChartView {...{ data, side, setSide, setActivePlayer, t, handleRightClickPlayer }} />}
        {tab === 'roster' && <RosterView {...{ data, setActivePlayer, refreshData }} />}
        {tab === 'schedule' && <ScheduleView {...{ data, currentSeason }} />}
        {tab === 'draft' && <DraftView {...{ data, refreshData }} />}
        {tab === 'stats' && <StatsView {...{ data }} />}
      </div>

      {activePlayer && <PlayerModal player={activePlayer} onClose={() => setActivePlayer(null)} seasons={data.seasons} />}
      {swapMenu && (
        <ContextMenu 
          x={swapMenu.x} 
          y={swapMenu.y} 
          onClose={() => setSwapMenu(null)}
          options={swapMenu.players.map((p, i) => ({
            label: `${p.number != null ? p.number : ''} ${p.name}`.trim(),
            action: () => handleSwapPlayer(swapMenu.currentPackage, swapMenu.pos.key, p)
          }))}
        />
      )}
    </>
  );
}

// === Dashboard ===
function Dashboard({ data, currentSeason, lastCompletedSeason, totalPlayers, allTimePct, winsBySeason, setTab, setActivePlayer, side, setSide, t, handleRightClickPlayer }) {
  const upcoming = currentSeason ? currentSeason.games.filter(g => !g.bye && g.future).slice(0, 5) : [];
  const recent = lastCompletedSeason
    ? lastCompletedSeason.games.filter(g => !g.bye && !g.future).slice(-5).reverse()
    : [];

  return (
    <div>
      <div className="page-head">
        <div>
          <div className="eyebrow">Season Brief · 2026</div>
          <h1>The roster, the record, the road ahead.</h1>
          <div className="sub">Live operational view across depth, draft, schedule, and 16 seasons of franchise history.</div>
        </div>
      </div>

      <div className="stat-grid">
        <Stat label="All-Time Record" value={`${data.allTime.wins}–${data.allTime.losses}`} sub={`${allTimePct} win rate · ${data.allTime.seasons} seasons`} />
        <Stat label="Active Roster" value={totalPlayers} sub="Players across 3 phases" />
        <Stat label="Points Scored" value={data.allTime.pointsFor.toLocaleString()} sub={`vs ${data.allTime.pointsAgainst.toLocaleString()} allowed`} />
        <Stat label="Last Season" value={lastCompletedSeason ? `${lastCompletedSeason.stats.wins}–${lastCompletedSeason.stats.losses}` : '—'} sub={lastCompletedSeason ? `${lastCompletedSeason.year} regular season` : ''} sparkline={winsBySeason} />
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1.6fr 1fr', gap: 20, marginTop: 28 }}>
        {/* Field preview */}
        <div className="card">
          <div className="card-head">
            <span className="title">Starting Lineup · {side === 'offense' ? 'Offense' : 'Defense'}</span>
            <div className="side-toggle" style={{ padding: 2 }}>
              <button className={side === 'offense' ? 'active' : ''} onClick={() => setSide('offense')}>OFF</button>
              <button className={side === 'defense' ? 'active' : ''} onClick={() => setSide('defense')}>DEF</button>
            </div>
          </div>
          <div style={{ padding: 14 }}>
            <FootballField side={side} depthChart={data.depthChart} onPlayerClick={setActivePlayer} onRightClickPlayer={handleRightClickPlayer} onContextMenu={(e, pos) => onRightClickPlayer && onRightClickPlayer(e, pos, side, currentPackage)}/>
            <div style={{ marginTop: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: 12, color: 'var(--fg-2)' }}>
              <span className="mono">Click any player chip for the full profile.</span>
              <button className="icon-btn" style={{ width: 'auto', padding: '0 12px', fontSize: 12 }} onClick={() => setTab('depth')}>
                Open full depth chart →
              </button>
            </div>
          </div>
        </div>

        {/* Upcoming + Recent */}
        <div style={{ display: 'grid', gap: 18 }}>
          <div className="card">
            <div className="card-head">
              <span className="title">Upcoming · 2026</span>
              <span className="count">{upcoming.length} games</span>
            </div>
            <div>
              {upcoming.length === 0 && <div style={{ padding: 24, color: 'var(--fg-2)', fontSize: 13 }}>Schedule complete.</div>}
              {upcoming.map((g, i) => {
                const isHome = g.home === 'Baltimore Ravens';
                const opp = isHome ? g.away : g.home;
                return (
                  <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 18px', borderBottom: '1px solid oklch(from var(--line) l c h / 0.5)' }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                      <span className="mono" style={{ color: 'var(--fg-2)', fontSize: 11, minWidth: 28 }}>WK {g.week}</span>
                      <span style={{ fontSize: 13, fontWeight: 500 }}>{isHome ? 'vs' : '@'} {opp}</span>
                    </div>
                    <span className="mono" style={{ fontSize: 11, color: 'var(--fg-2)' }}>{fmtDate(g.date)}</span>
                  </div>
                );
              })}
            </div>
          </div>
          <div className="card">
            <div className="card-head">
              <span className="title">Last 5 · {lastCompletedSeason ? lastCompletedSeason.year : '—'}</span>
              <span className="count">recent</span>
            </div>
            <div>
              {recent.map((g, i) => {
                const isHome = g.home === 'Baltimore Ravens';
                const opp = isHome ? g.away : g.home;
                return (
                  <div key={i} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 18px', borderBottom: '1px solid oklch(from var(--line) l c h / 0.5)' }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                      <span className={`pill ${g.result === 'W' ? 'win' : 'loss'}`} style={{ minWidth: 22, justifyContent: 'center' }}>{g.result}</span>
                      <span style={{ fontSize: 13, fontWeight: 500 }}>{isHome ? 'vs' : '@'} {opp}</span>
                    </div>
                    <span className="mono" style={{ fontSize: 12 }}>{isHome ? g.homeScore : g.awayScore}–{isHome ? g.awayScore : g.homeScore}</span>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>

      {t.showStats && (
        <div className="section">
          <div className="section-head">
            <h2>Season-by-season</h2>
            <span className="meta">Click a column to sort · {data.seasons.length} seasons on file</span>
          </div>
          <SeasonStats seasons={data.seasons.filter(s => s.stats.wins + s.stats.losses > 0)} />
        </div>
      )}
    </div>
  );
}

function Stat({ label, value, sub, sparkline }) {
  return (
    <div className="stat">
      <div className="label">{label}</div>
      <div className="value tnum">{value}</div>
      {sub && <div className="delta">{sub}</div>}
      {sparkline && (
        <div style={{ marginTop: 12 }}>
          <Sparkline data={sparkline} accent height={32} />
        </div>
      )}
    </div>
  );
}

// === Custom CustomSelect component ===
function CustomSelect({ options, value, onChange }) {
  const [isOpen, setIsOpen] = useState(false);
  const containerRef = React.useRef(null);

  useEffect(() => {
    function handleClickOutside(event) {
      if (containerRef.current && !containerRef.current.contains(event.target)) {
        setIsOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => {
      document.removeEventListener("mousedown", handleClickOutside);
    };
  }, []);

  return (
    <div className="personnel-select-wrap" ref={containerRef}>
      <button 
        type="button"
        className="personnel-select" 
        onClick={() => setIsOpen(!isOpen)}
      >
        {value}
      </button>
      <svg className="select-chevron" width="10" height="10" viewBox="0 0 10 10" fill="none">
        <path d="M2 3.5L5 6.5L8 3.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
      
      {isOpen && (
        <div className="custom-dropdown-menu">
          {options.map(opt => (
            <div 
              key={opt}
              className={`custom-dropdown-option ${opt === value ? 'selected' : ''}`}
              onClick={() => {
                onChange(opt);
                setIsOpen(false);
              }}
            >
              {opt}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// === Fixed defensive formation grid ===
// Row 1: ── OLB-L(3) DT(4) NT(5) DE(6) OLB-R(7) ──
// Row 2: ──────── LB1(5) LB2(6) ────────────────
// Row 3: CB1(1) CB Slot(2) ─ FS(4) ─ SS(6) ── CB2(9)
const DEFENSE_GRID = [
  { pos: 'OLB-L',   col: 3, row: 1 },
  { pos: 'DT',       col: 4, row: 1 },
  { pos: 'NT',       col: 5, row: 1 },
  { pos: 'DE',       col: 6, row: 1 },
  { pos: 'OLB-R',   col: 7, row: 1 },
  { pos: 'LB1',      col: 5, row: 2 },
  { pos: 'LB2',      col: 6, row: 2 },
  { pos: 'CB1',      col: 1, row: 3 },
  { pos: 'CB Slot',  col: 2, row: 3 },
  { pos: 'FS',       col: 4, row: 3 },
  { pos: 'SS',       col: 6, row: 3 },
  { pos: 'CB2',      col: 9, row: 3 },
];

function DefenseGrid({ depthChart, onPlayerClick }) {
  const group = depthChart.defense;
  return (
    <div className="depth-fixed-grid defense-grid">
      {DEFENSE_GRID.map(({ pos, col, row }) => {
        const players = group[pos] || [];
        if (!players.length) return null;
        return (
          <div
            key={pos}
            className="depth-pos-card"
            style={{ gridColumn: col, gridRow: row }}
          >
            <div className="ph"><strong>{pos}</strong><span>{players.length}</span></div>
            {players.map((p, i) => (
              <div
                key={i}
                className={`pl-row ${i === 0 ? 'starter' : ''}`}
                onClick={() => onPlayerClick({ ...p, position: pos, depth: p.depth || i + 1, group: 'defense' })}
                style={{ cursor: 'pointer' }}
              >
                <span className="num">{p.number != null ? p.number : '—'}</span>
                <span className="nm">{p.name}</span>
              </div>
            ))}
          </div>
        );
      })}
    </div>
  );
}

// === Fixed offensive formation grid ===
// Row 1 (9 cols): WR1 | WR Slot | LT | LG | C | RG | RT | TE | WR2
// Row 2:                                   QB(col5) | RB(col6)
const OFFENSE_GRID = [
  { pos: 'WR1',     col: 1, row: 1 },
  { pos: 'WR Slot', col: 2, row: 1 },
  { pos: 'LT',      col: 3, row: 1 },
  { pos: 'LG',      col: 4, row: 1 },
  { pos: 'C',       col: 5, row: 1 },
  { pos: 'RG',      col: 6, row: 1 },
  { pos: 'RT',      col: 7, row: 1 },
  { pos: 'TE',      col: 8, row: 1 },
  { pos: 'WR2',     col: 9, row: 1 },
  { pos: 'QB',      col: 5, row: 2 },
  { pos: 'RB',      col: 6, row: 2 },
];

function OffenseGrid({ depthChart, onPlayerClick }) {
  const group = depthChart.offense;
  return (
    <div className="depth-fixed-grid offense-grid">
      {OFFENSE_GRID.map(({ pos, col, row }) => {
        const players = group[pos] || [];
        if (!players.length) return null;
        return (
          <div
            key={pos}
            className="depth-pos-card"
            style={{ gridColumn: col, gridRow: row }}
          >
            <div className="ph"><strong>{pos}</strong><span>{players.length}</span></div>
            {players.map((p, i) => (
              <div
                key={i}
                className={`pl-row ${i === 0 ? 'starter' : ''}`}
                onClick={() => onPlayerClick({ ...p, position: pos, depth: p.depth || i + 1, group: 'offense' })}
                style={{ cursor: 'pointer' }}
              >
                <span className="num">{p.number != null ? p.number : '—'}</span>
                <span className="nm">{p.name}</span>
              </div>
            ))}
          </div>
        );
      })}
    </div>
  );
}

// === Depth section divider ===
function SectionDivider({ label }) {
  return (
    <div className="depth-section-divider">
      <div className="depth-section-line" />
      <span className="depth-section-label">{label}</span>
      <div className="depth-section-line" />
    </div>
  );
}

// === Depth Chart View ===
function DepthChartView({ data, side, setSide, setActivePlayer, t, handleRightClickPlayer }) {
  const offKeys = Object.keys(window.OFFENSE_PERSONNEL);
  const defKeys = Object.keys(window.DEFENSE_PERSONNEL);
  const [offPersonnel, setOffPersonnel] = useState(offKeys[0]);
  const [defPersonnel, setDefPersonnel] = useState(defKeys[0]);

  return (
    <div>
      <div className="page-head">
        <div>
          <div className="eyebrow">Roster · 2026</div>
          <h1>Depth chart.</h1>
          <div className="sub">Starters at every position, with full depth tiers. Click any chip for a player profile.</div>
        </div>
      </div>
      <div className="personnel-bar">
        <div className="personnel-group">
          <span className="personnel-label">OFFENSE</span>
          <CustomSelect 
            options={offKeys}
            value={offPersonnel}
            onChange={setOffPersonnel}
          />
        </div>
        <div className="personnel-group right">
          <span className="personnel-label">DEFENSE</span>
          <CustomSelect 
            options={defKeys}
            value={defPersonnel}
            onChange={setDefPersonnel}
          />
        </div>
      </div>
      <div className={t.fieldStyle === 'abstract' ? 'abstract-mode' : ''}>
        <FootballFieldVertical
          depthChart={data.depthChart}
          onPlayerClick={setActivePlayer}
          offPersonnel={offPersonnel}
          defPersonnel={defPersonnel}
          onContextMenu={(e, pos) => onRightClickPlayer && onRightClickPlayer(e, pos, side, currentPackage)}
          onRightClickPlayer={handleRightClickPlayer}
        />
      </div>
      <div className="depth-sections">
        <SectionDivider label="Offense" />
        <OffenseGrid depthChart={data.depthChart} onPlayerClick={setActivePlayer} />
        <SectionDivider label="Defense" />
        <DefenseGrid depthChart={data.depthChart} onPlayerClick={setActivePlayer} />
        <SectionDivider label="Special" />
        <SpecialTeamsCard data={data.depthChart.specialTeams} onPlayerClick={setActivePlayer} />
      </div>
    </div>
  );
}

// === Roster View ===
// Normalize the depth-chart position keys (WR1, OLB-L, …) to standard
// NFL labels (WR, OLB, …) and define a logical sort order.
const POSITION_DISPLAY = {
  QB: 'QB', RB: 'RB', 'WR1': 'WR', 'WR2': 'WR', 'WR Slot': 'WR',
  TE: 'TE', LT: 'LT', LG: 'LG', C: 'C', RG: 'RG', RT: 'RT',
  DE: 'DE', DT: 'DT', NT: 'NT', 'OLB-L': 'OLB', 'OLB-R': 'OLB',
  LB1: 'ILB', LB2: 'ILB', CB1: 'CB', CB2: 'CB', 'CB Slot': 'CB',
  SS: 'SS', FS: 'FS', K: 'K', P: 'P', LS: 'LS',
};
const POSITION_ORDER = ['QB','RB','WR','TE','LT','LG','C','RG','RT','DE','DT','NT','OLB','ILB','CB','SS','FS','K','P','LS'];
const POSITION_RANK = Object.fromEntries(POSITION_ORDER.map((p, i) => [p, i]));

function fmtHeight(inches) {
  if (inches == null) return '—';
  const ft = Math.floor(inches / 12);
  const inch = inches % 12;
  return `${ft}'${inch}"`;
}

// === Context Menu ===
function ContextMenu({ x, y, options, onClose }) {
  useEffect(() => {
    const handleClick = () => onClose();
    window.addEventListener('click', handleClick);
    return () => window.removeEventListener('click', handleClick);
  }, [onClose]);

  return (
    <div style={{
      position: 'fixed', top: Math.min(y, window.innerHeight - 100), left: Math.min(x, window.innerWidth - 180), zIndex: 10000,
      background: 'var(--bg-1)', border: '1px solid var(--line)', borderRadius: 8,
      boxShadow: '0 8px 24px rgba(0,0,0,0.4)', padding: '4px 0', minWidth: 180,
      fontFamily: 'var(--font-sans)', fontSize: 13
    }} onClick={e => e.stopPropagation()} onContextMenu={e => e.preventDefault()}>
      {options.map((opt, i) => (
        <div 
          key={i} 
          onClick={() => { opt.action(); onClose(); }} 
          onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-2)'}
          onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
          style={{
            padding: '8px 16px', cursor: 'pointer', 
            color: opt.danger ? '#ff5050' : 'var(--fg-0)',
            display: 'flex', alignItems: 'center', gap: 8
          }}
        >
          {opt.label}
        </div>
      ))}
    </div>
  );
}

// === Confirm Delete Modal ===
function ConfirmModal({ player, onClose, onConfirm }) {
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{ padding: 24, width: '100%', maxWidth: 400 }}>
        <h2 style={{ margin: '0 0 12px 0', fontFamily: 'var(--font-display)' }}>Remove Player</h2>
        <p style={{ margin: '0 0 24px 0', color: 'var(--fg-2)', fontSize: 13 }}>
          Are you sure you want to remove <strong>{player.name}</strong> from the roster? This action cannot be undone.
        </p>
        <div style={{ display: 'flex', gap: 12, justifyContent: 'flex-end' }}>
          <button onClick={onClose} style={{ padding: '8px 16px', background: 'transparent', border: '1px solid var(--line)', color: 'var(--fg-0)', borderRadius: 6, cursor: 'pointer' }}>Cancel</button>
          <button onClick={() => { onConfirm(); onClose(); }} style={{ padding: '8px 16px', background: '#e53935', color: 'white', border: 'none', borderRadius: 6, cursor: 'pointer', fontWeight: 600 }}>Remove</button>
        </div>
      </div>
    </div>
  );
}

function AddPlayerModal({ onClose, onSave, playerToEdit }) {
  const [formData, setFormData] = useState(() => {
    if (playerToEdit) {
      let h = playerToEdit.height;
      if (typeof h === 'number') {
        const ft = Math.floor(h / 12);
        const inch = h % 12;
        h = `${ft}' ${inch}`;
      }
      return { 
        ...playerToEdit, 
        height: h || '',
        phase: playerToEdit.group === 'special' ? 'specialTeams' : (playerToEdit.group || 'offense'),
        position: playerToEdit.posKey || 'QB'
      };
    }
    return {
      name: '', number: '', age: '', height: '', weight: '', 
      college: '', avg: '', cap: '', 
      position: 'QB', depth: 1, phase: 'offense'
    };
  });

  const handleChange = (e) => {
    setFormData({ ...formData, [e.target.name]: e.target.value });
  };

  const handleChangeHeight = (e) => {
    let val = e.target.value;
    // If the user types a space right after a number, convert it to feet symbol + space
    if (val.length > formData.height.length && val.endsWith(' ')) {
      const numMatch = val.match(/^(\d+) $/);
      if (numMatch) {
        val = `${numMatch[1]}' `;
      }
    }
    setFormData({ ...formData, height: val });
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const dataToSave = { ...formData };
    
    if (typeof dataToSave.height === 'string' && dataToSave.height.includes("'")) {
      const parts = dataToSave.height.split("'");
      const ft = parseInt(parts[0], 10) || 0;
      const inch = parseInt(parts[1], 10) || 0;
      dataToSave.height = ft * 12 + inch;
    } else if (dataToSave.height) {
      dataToSave.height = parseInt(dataToSave.height, 10);
    }

    console.log("Saving player:", dataToSave);
    onSave(dataToSave);
    onClose();
  };

  const inputStyle = {
    background: 'var(--bg-1)',
    border: '1px solid var(--line)',
    borderRadius: 8,
    padding: '9px 12px',
    color: 'var(--fg-0)',
    fontSize: 13,
    fontFamily: 'inherit',
    outline: 'none',
    width: '100%',
    boxSizing: 'border-box'
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{ padding: 24, width: '100%', maxWidth: 480 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 20 }}>
          <h2 style={{ margin: 0, fontFamily: 'var(--font-display)' }}>{playerToEdit ? 'Edit Player' : 'Add New Player'}</h2>
          <button className="icon-btn" onClick={onClose}>✕</button>
        </div>
        
        <form onSubmit={handleSubmit} style={{ display: 'grid', gap: 12 }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10 }}>
             <select name="phase" value={formData.phase} onChange={handleChange} style={inputStyle}>
                <option value="offense">Offense</option>
                <option value="defense">Defense</option>
                <option value="specialTeams">Special Teams</option>
             </select>
             <select name="position" value={formData.position} onChange={handleChange} style={inputStyle} required>
                {Object.keys(POSITION_DISPLAY).map(pos => (
                  <option key={pos} value={pos}>{pos}</option>
                ))}
             </select>
             <input type="number" name="depth" placeholder="Depth (1, 2...)" value={formData.depth} onChange={handleChange} style={inputStyle} required min="1" max="4" />
          </div>

          <input name="name" placeholder="Player Name" value={formData.name} onChange={handleChange} style={inputStyle} required />
          
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <input type="number" name="number" placeholder="Jersey #" value={formData.number} onChange={handleChange} style={inputStyle} />
            <input type="number" name="age" placeholder="Age" value={formData.age} onChange={handleChange} style={inputStyle} />
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <input type="text" name="height" placeholder="Height (e.g. 6' 2&quot;)" value={formData.height} onChange={handleChangeHeight} style={inputStyle} />
            <input type="number" name="weight" placeholder="Weight (lbs)" value={formData.weight} onChange={handleChange} style={inputStyle} />
          </div>

          <input name="college" placeholder="College" value={formData.college} onChange={handleChange} style={inputStyle} />
          
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <input type="number" name="avg" placeholder="AVG Salary" value={formData.avg} onChange={handleChange} style={inputStyle} />
            <input type="number" name="cap" placeholder="CAP Hit" value={formData.cap} onChange={handleChange} style={inputStyle} />
          </div>

          <button type="submit" style={{ marginTop: 10, padding: 12, background: 'var(--accent)', color: 'white', border: 'none', borderRadius: 8, fontWeight: 'bold', cursor: 'pointer' }}>
            {playerToEdit ? 'Update Player' : 'Save Player to Roster'}
          </button>
        </form>
      </div>
    </div>
  );
}

function RosterView({ data, setActivePlayer, refreshData }) {
  const [showAddModal, setShowAddModal] = useState(false);
  const [contextMenu, setContextMenu] = useState(null);
  const [playerToEdit, setPlayerToEdit] = useState(null);
  const [playerToRemove, setPlayerToRemove] = useState(null);

  const API_URL = "https://ravens-api.evagkotsakis.workers.dev/api/roster";

  // This fires when you click "Save" in the modal
  const handleSaveNewPlayer = (newPlayer) => {
    fetch(API_URL, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(newPlayer)
    })
    .then(res => res.json())
    .then(response => {
      console.log("Database says:", response);
      refreshData(); // This tells the Root component to fetch the updated list!
    })
    .catch(err => console.error("Error saving player:", err));
  };

  const handleUpdatePlayer = (updatedPlayer) => {
    fetch(API_URL, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ ...updatedPlayer, originalName: playerToEdit.name, originalPosition: playerToEdit.posKey })
    })
    .then(res => res.json())
    .then(response => {
      console.log("Database updated:", response);
      refreshData();
    })
    .catch(err => console.error("Error updating player:", err));
  };

  const handleDeletePlayer = (player) => {
    fetch(API_URL, {
      method: "DELETE",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: player.name, position: player.posKey, phase: player.group === 'special' ? 'specialTeams' : player.group })
    })
    .then(res => res.json())
    .then(response => {
      console.log("Database deleted:", response);
      refreshData();
    })
    .catch(err => console.error("Error deleting player:", err));
  };

  const handleRightClick = (e, r) => {
    e.preventDefault();
    setContextMenu({ x: e.clientX, y: e.clientY, player: r });
  };

  const [sortKey, setSortKey] = useState('position');
  const [sortDir, setSortDir] = useState('asc');
  const [search, setSearch] = useState('');
  const [groupFilter, setGroupFilter] = useState('All');

  const rows = useMemo(() => {
    const all = [];
    const groups = [
      ['offense', data.depthChart.offense],
      ['defense', data.depthChart.defense],
      ['special', data.depthChart.specialTeams],
    ];
    groups.forEach(([group, dict]) => {
      Object.entries(dict).forEach(([posKey, players]) => {
        players.forEach((p, depth) => {
          all.push({
            ...p,
            posKey,
            position: POSITION_DISPLAY[posKey] || posKey,
            group,
            depth: p.depth || index + 1,
          });
        });
      });
    });
    return all;
  }, [data]);

  // Predicate per row — used to mark rows in/out without unmounting them
  // so CSS transitions can run smoothly when toggling filters.
  const isVisible = (r) => {
    if (groupFilter !== 'All' && r.group !== groupFilter) return false;
    if (search && !`${r.name} ${r.college} ${r.position}`.toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  };

  // Sort the FULL row set so hidden rows keep stable keys/positions
  // (otherwise the table reorders mid-animation).
  const sorted = useMemo(() => {
    const arr = [...rows];
    arr.sort((a, b) => {
      let av, bv;
      if (sortKey === 'position') {
        av = POSITION_RANK[a.position] ?? 999;
        bv = POSITION_RANK[b.position] ?? 999;
        // tiebreak: depth
        if (av === bv) { av = a.depth ?? 999; bv = b.depth ?? 999; }
      } else {
        av = a[sortKey];
        bv = b[sortKey];
        if (av == null) av = sortDir === 'asc' ? Infinity : -Infinity;
        if (bv == null) bv = sortDir === 'asc' ? Infinity : -Infinity;
        if (typeof av === 'string') av = av.toLowerCase();
        if (typeof bv === 'string') bv = bv.toLowerCase();
      }
      if (av < bv) return sortDir === 'asc' ? -1 : 1;
      if (av > bv) return sortDir === 'asc' ? 1 : -1;
      return 0;
    });
    return arr;
  }, [rows, sortKey, sortDir]);

  const visibleCount = sorted.filter(isVisible).length;

  const toggleSort = (k) => {
    if (sortKey === k) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortKey(k); setSortDir('asc'); }
  };

  const Th = ({ k, children, mono, align }) => (
    <th
      className={`sortable ${mono ? 'mono' : ''} ${sortKey === k ? 'active' : ''}`}
      onClick={() => toggleSort(k)}
      style={align ? { textAlign: align } : undefined}
    >
      {children}
      {sortKey === k && <span style={{ marginLeft: 4 }}>{sortDir === 'asc' ? '↑' : '↓'}</span>}
    </th>
  );

  const groupChips = [
    ['All', 'All'],
    ['offense', 'Offense'],
    ['defense', 'Defense'],
    ['special', 'Special'],
  ];

  return (
    <div>
      <div className="page-head" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div className="eyebrow">Active roster · 2026</div>
          <h1>Full roster.</h1>
          <div className="sub">{rows.length} players across all phases. Sort by any column. Click a row for the full profile.</div>
        </div>
        <button 
          onClick={() => setShowAddModal(true)}
          style={{ padding: '10px 16px', background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 8, color: 'var(--fg-0)', fontWeight: 600, cursor: 'pointer' }}
        >
          + Add Player
        </button>
      </div>
      <div className="filter-bar">
        <input
          className="search-input"
          placeholder="Search players, college, position..."
          value={search}
          onChange={e => setSearch(e.target.value)}
        />
        <div className="chip-group">
          {groupChips.map(([k, l]) => (
            <button
              key={k}
              className={groupFilter === k ? 'active' : ''}
              onClick={() => setGroupFilter(k)}
            >{l}</button>
          ))}
        </div>
      </div>
      <div className="card" style={{ overflowX: 'auto' }}>
        <table>
          <thead>
            <tr>
              <Th k="position" mono>Pos</Th>
              <Th k="name">Player</Th>
              <Th k="number" mono align="right">No</Th>
              <Th k="age" mono align="right">Age</Th>
              <Th k="height" mono align="right">Ht</Th>
              <Th k="weight" mono align="right">Wt</Th>
              <Th k="college">College</Th>
              <Th k="draftYear" mono align="right">Drafted</Th>
              <Th k="avg" mono align="right">AVG</Th>
              <Th k="cap" mono align="right">CAP</Th>
            </tr>
          </thead>
          <tbody>
            {sorted.map((r) => {
              const visible = isVisible(r);
              return (
                <tr
                  key={`${r.group}-${r.posKey}-${r.depth}-${r.name}`}
                  className={`roster-row${visible ? '' : ' is-out'}`}
                  onClick={() => visible && setActivePlayer({ ...r, position: r.posKey })}
                  onContextMenu={(e) => visible && handleRightClick(e, r)}
                  aria-hidden={!visible}
                >
                  <td className="mono"><span className="pill" style={{ minWidth: 36, justifyContent: 'center' }}>{r.position}</span></td>
                  <td style={{ fontWeight: 500 }}>{r.name}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{r.number ?? '—'}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{r.age ?? '—'}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{fmtHeight(r.height)}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{r.weight ?? '—'}</td>
                  <td className="muted">{r.college || '—'}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{r.draftYear ?? <span style={{ color: 'var(--fg-3)' }}>UDFA</span>}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{r.avg ? `$${r.avg.toLocaleString()}` : '—'}</td>
                  <td className="mono" style={{ textAlign: 'right' }}>{r.cap ? `$${r.cap.toLocaleString()}` : '—'}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
        {visibleCount === 0 && (
          <div style={{ padding: '40px 20px', textAlign: 'center', color: 'var(--fg-2)' }}>No players match the current filters.</div>
        )}
      </div>

      {showAddModal && (
        <AddPlayerModal 
          onClose={() => setShowAddModal(false)} 
          onSave={handleSaveNewPlayer} 
        />
      )}
      {playerToEdit && (
        <AddPlayerModal 
          playerToEdit={playerToEdit}
          onClose={() => setPlayerToEdit(null)} 
          onSave={handleUpdatePlayer} 
        />
      )}
      {playerToRemove && (
        <ConfirmModal 
          player={playerToRemove}
          onClose={() => setPlayerToRemove(null)}
          onConfirm={() => handleDeletePlayer(playerToRemove)}
        />
      )}
      {contextMenu && (
        <ContextMenu 
          x={contextMenu.x} y={contextMenu.y} 
          onClose={() => setContextMenu(null)}
          options={[
            { label: 'Edit Player', action: () => setPlayerToEdit(contextMenu.player) },
            { label: 'Remove from Roster', action: () => setPlayerToRemove(contextMenu.player), danger: true }
          ]}
        />
      )}
    </div>
  );
}

function SpecialTeamsCard({ data, onPlayerClick }) {
  const groups = [['K', 'Kicker'], ['P', 'Punter'], ['LS', 'Long Snapper']];
  return (
    <div className="depth-list">
      {groups.map(([key, label]) => {
        const players = data[key] || [];
        return (
          <div className="depth-pos-card" key={key}>
            <div className="ph"><strong>{key}</strong> · {label}</div>
            {players.map((p, i) => (
              <div
                key={i}
                className="pl-row starter"
                onClick={() => onPlayerClick({ ...p, position: key, depth: i+1, group: 'special' })}
                style={{ cursor: 'pointer' }}
              >
                <span className="num">{p.number != null ? p.number : '—'}</span>
                <span className="nm">{p.name}</span>
              </div>
            ))}
          </div>
        );
      })}
      <div className="depth-pos-card" style={{ opacity: 0.55 }}>
        <div className="ph"><strong>IR</strong> · Injured Reserve</div>
        <div style={{ fontSize: 11.5, color: 'var(--fg-2)', padding: '4px 0' }}>No active IR designations.</div>
      </div>
    </div>
  );
}

// === Schedule View ===
function ScheduleView({ data, currentSeason }) {
  const [year, setYear] = useState(currentSeason ? currentSeason.year : data.seasons[data.seasons.length-1].year);
  const season = data.seasons.find(s => s.year === year);
  return (
    <div>
      <div className="page-head">
        <div>
          <div className="eyebrow">Game log</div>
          <h1>Schedule & results.</h1>
          <div className="sub">Every game across {data.seasons.length} seasons. {currentSeason && `${currentSeason.year} season is in progress.`}</div>
        </div>
      </div>
      <div className="filter-bar">
        <div className="chip-group" style={{ flexWrap: 'wrap' }}>
          {data.seasons.map(s => (
            <button key={s.year} className={year === s.year ? 'active' : ''} onClick={() => setYear(s.year)}>{s.year}</button>
          ))}
        </div>
      </div>
      <Schedule season={season} />
    </div>
  );
}

// === Draft View ===
function AddDraftModal({ onClose, onSave, pickToEdit }) {
  const [formData, setFormData] = useState(() => {
    if (pickToEdit) {
      return {
        ...pickToEdit,
        phase: pickToEdit.group === 'special' ? 'specialTeams' : (pickToEdit.group || 'offense'),
        position: pickToEdit.posKey || pickToEdit.position || 'QB',
        depth: pickToEdit.depth || 4
      };
    }
    return {
      year: 2026, round: 1, overall: '', name: '', 
      position: 'QB', college: '', phase: 'offense', depth: 4
    };
  });

  const handleChange = (e) => setFormData({ ...formData, [e.target.name]: e.target.value });

  const handleSubmit = (e) => {
    e.preventDefault();
    onSave({
      ...formData,
      year: parseInt(formData.year),
      round: parseInt(formData.round),
      overall: parseInt(formData.overall),
      depth: parseInt(formData.depth)
    });
    onClose();
  };

  const inputStyle = {
    background: 'var(--bg-1)', border: '1px solid var(--line)', borderRadius: 8,
    padding: '9px 12px', color: 'var(--fg-0)', fontSize: 13, fontFamily: 'inherit',
    outline: 'none', width: '100%', boxSizing: 'border-box'
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{ padding: 24, width: '100%', maxWidth: 480 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 20 }}>
          <h2 style={{ margin: 0, fontFamily: 'var(--font-display)' }}>{pickToEdit ? 'Edit Draft Pick' : 'Add Draft Pick'}</h2>
          <button className="icon-btn" onClick={onClose}>✕</button>
        </div>
        
        <form onSubmit={handleSubmit} style={{ display: 'grid', gap: 12 }}>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 10 }}>
             <input type="number" name="year" placeholder="Year" value={formData.year} onChange={handleChange} style={inputStyle} required />
             <input type="number" name="round" placeholder="Round" value={formData.round} onChange={handleChange} style={inputStyle} required />
             <input type="number" name="overall" placeholder="Pick #" value={formData.overall} onChange={handleChange} style={inputStyle} required />
          </div>

          <input name="name" placeholder="Player Name" value={formData.name} onChange={handleChange} style={inputStyle} required />
          
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <select name="position" value={formData.position} onChange={handleChange} style={inputStyle} required>
              {Object.keys(POSITION_DISPLAY).map(pos => <option key={pos} value={pos}>{pos}</option>)}
            </select>
            <input name="college" placeholder="College" value={formData.college} onChange={handleChange} style={inputStyle} />
          </div>

          <div style={{ marginTop: 8, paddingTop: 16, borderTop: '1px solid var(--line)' }}>
            <div className="eyebrow" style={{ marginBottom: 8 }}>Active Roster Placement</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
              <select name="phase" value={formData.phase} onChange={handleChange} style={inputStyle}>
                  <option value="offense">Offense</option>
                  <option value="defense">Defense</option>
                  <option value="specialTeams">Special Teams</option>
              </select>
              <input type="number" name="depth" placeholder="Depth (e.g. 4)" value={formData.depth} onChange={handleChange} style={inputStyle} required />
            </div>
          </div>

          <button type="submit" style={{ marginTop: 10, padding: 12, background: 'var(--accent)', color: 'white', border: 'none', borderRadius: 8, fontWeight: 'bold', cursor: 'pointer' }}>
            {pickToEdit ? 'Update Draft Pick' : 'Draft Player'}
          </button>
        </form>
      </div>
    </div>
  );
}

function DraftView({ data, refreshData }) {
  const [showAddModal, setShowAddModal] = useState(false);
  const [contextMenu, setContextMenu] = useState(null);
  const [pickToEdit, setPickToEdit] = useState(null);
  const [pickToRemove, setPickToRemove] = useState(null);

  const handleSavePick = (pick) => {
    fetch("https://ravens-api.evagkotsakis.workers.dev/api/draft", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(pick)
    })
    .then(res => res.json())
    .then(() => refreshData())
    .catch(err => console.error("Error saving draft pick:", err));
  };

  const handleUpdatePick = (pick) => {
    fetch("https://ravens-api.evagkotsakis.workers.dev/api/draft", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ ...pick, originalName: pickToEdit.name, originalYear: pickToEdit.year })
    })
    .then(res => res.json())
    .then(() => refreshData())
    .catch(err => console.error("Error updating draft pick:", err));
  };

  const handleDeletePick = (pick) => {
    fetch("https://ravens-api.evagkotsakis.workers.dev/api/draft", {
      method: "DELETE",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: pick.name, year: pick.year, round: pick.round })
    })
    .then(res => res.json())
    .then(() => refreshData())
    .catch(err => console.error("Error deleting draft pick:", err));
  };

  const handleRightClick = (e, r) => {
    setContextMenu({ x: e.clientX, y: e.clientY, pick: r });
  };

  return (
    <div>
      <div className="page-head" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
        <div>
          <div className="eyebrow">Draft history</div>
          <h1>Draft room.</h1>
          <div className="sub">{data.seasons.reduce((n, s) => n + s.draft.length, 0)} picks across {data.seasons.length} drafts. Filter, search, sort.</div>
        </div>
        <button 
          onClick={() => setShowAddModal(true)}
          style={{ padding: '10px 16px', background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 8, color: 'var(--fg-0)', fontWeight: 600, cursor: 'pointer' }}
        >
          + Add Pick
        </button>
      </div>
      <DraftTable seasons={data.seasons} onRightClick={handleRightClick} />
      
      {showAddModal && (
        <AddDraftModal 
          onClose={() => setShowAddModal(false)} 
          onSave={handleSavePick} 
        />
      )}

      {pickToEdit && (
        <AddDraftModal 
          onClose={() => setPickToEdit(null)} 
          onSave={handleUpdatePick} 
          pickToEdit={pickToEdit}
        />
      )}

      {pickToRemove && (
        <ConfirmModal 
          player={pickToRemove}
          onClose={() => setPickToRemove(null)}
          onConfirm={() => handleDeletePick(pickToRemove)}
        />
      )}

      {contextMenu && (
        <ContextMenu 
          x={contextMenu.x} y={contextMenu.y} 
          onClose={() => setContextMenu(null)}
          options={[
            { label: 'Edit Draft Pick', action: () => setPickToEdit(contextMenu.pick) },
            { label: 'Remove Draft Pick', action: () => setPickToRemove(contextMenu.pick), danger: true }
          ]}
        />
      )}
    </div>
  );
}

// === Stats View ===
function StatsView({ data }) {
  const seasons = data.seasons.filter(s => s.stats.wins + s.stats.losses > 0);
  return (
    <div>
      <div className="page-head">
        <div>
          <div className="eyebrow">Franchise stats</div>
          <h1>{seasons.length} seasons of football.</h1>
          <div className="sub">Aggregate record, scoring trends, and season-over-season trajectories.</div>
        </div>
      </div>
      <div className="stat-grid" style={{ gridTemplateColumns: 'repeat(4, 1fr)' }}>
        <Stat label="Total Wins" value={data.allTime.wins} />
        <Stat label="Total Losses" value={data.allTime.losses} />
        <Stat label="Avg PF / Game" value={(data.allTime.pointsFor / seasons.reduce((n, s) => n + s.stats.wins + s.stats.losses, 0)).toFixed(1)} />
        <Stat label="Avg PA / Game" value={(data.allTime.pointsAgainst / seasons.reduce((n, s) => n + s.stats.wins + s.stats.losses, 0)).toFixed(1)} />
      </div>
      <div className="section">
        <div className="section-head"><h2>Season-by-season</h2></div>
        <SeasonStats seasons={seasons} />
      </div>
    </div>
  );
}

// === Tweaks Panel ===
function TweaksUI() {
  if (!window.TweaksPanel) return null;
  const { TweaksPanel, TweakSection, TweakRadio, TweakToggle } = window;
  const [t, setT] = window.useTweaks(TWEAK_DEFAULTS);
  return (
    <TweaksPanel>
      <TweakSection title="Layout">
        <TweakRadio
          label="Density"
          value={t.density}
          options={[
            { value: 'compact', label: 'Compact' },
            { value: 'comfortable', label: 'Default' },
            { value: 'spacious', label: 'Spacious' },
          ]}
          onChange={v => setT('density', v)}
        />
        <TweakRadio
          label="Depth chart"
          value={t.fieldStyle}
          options={[
            { value: 'field', label: 'Field' },
            { value: 'abstract', label: 'Abstract' },
          ]}
          onChange={v => setT('fieldStyle', v)}
        />
      </TweakSection>
      <TweakSection title="Modules">
        <TweakToggle label="Schedule strip" value={t.showSchedule} onChange={v => setT('showSchedule', v)} />
        <TweakToggle label="Draft section" value={t.showDraft} onChange={v => setT('showDraft', v)} />
        <TweakToggle label="Stats table" value={t.showStats} onChange={v => setT('showStats', v)} />
        <TweakToggle label="Depth list" value={t.showDepth} onChange={v => setT('showDepth', v)} />
      </TweakSection>
    </TweaksPanel>
  );
}

// === Mount ===
function Root() {
  const [data, setData] = useState(null);
  
  // Here is your live Cloudflare API!
  const API_URL = "https://ravens-api.evagkotsakis.workers.dev/api/roster";

  const loadData = () => {
    Promise.all([
      fetch('data/team-data.json').then(r => r.json()),
      fetch("https://ravens-api.evagkotsakis.workers.dev/api/roster").then(r => r.json()),
      fetch("https://ravens-api.evagkotsakis.workers.dev/api/draft").then(r => r.json()),
      fetch("https://ravens-api.evagkotsakis.workers.dev/api/personnel-overrides").then(r => r.ok ? r.json() : []).catch(() => [])
    ])
    .then(([staticData, liveDepthChart, liveDraft, overrides]) => {
      // 1. Apply live roster
      staticData.depthChart = liveDepthChart;

      // 2. Clear static draft picks so we only use the live DB
      staticData.seasons.forEach(s => {
        s.draft = [];
      });

      // 3. Insert live database draft picks into the historical static JSON
      liveDraft.forEach(d => {
        let season = staticData.seasons.find(s => s.year === d.year);
        // If it's a future draft year that doesn't exist in the JSON yet, create it
        if (!season) {
          season = { year: d.year, games: [], draft: [], stats: {wins:0, losses:0, ties:0, pointsFor:0, pointsAgainst:0} };
          staticData.seasons.push(season);
        }
        season.draft.push({
          round: d.round,
          overall: d.overall,
          name: d.name,
          position: d.position,
          college: d.college
        });
      });

      // 4. Apply Personnel Overrides
      const applyOverrides = (personnelMap, sideKey) => {
        Object.keys(personnelMap).forEach(pkg => {
          personnelMap[pkg].forEach(pos => {
            const override = overrides.find(o => o.package === pkg && o.position === pos.key);
            
            if (override) {
              // Search for the player in any of the allowed swap positions
              const searchKeys = pos.allowedSwaps || [pos.dataKey || pos.key];
              let overridePlayer = null;
              
              for (const key of searchKeys) {
                const chartPlayers = liveDepthChart[sideKey][key] || [];
                const found = chartPlayers.find(p => p.name === override.playerName);
                if (found) {
                  // Found them! Tag them with their true positional label
                  overridePlayer = { ...found, rosterPosition: POSITION_DISPLAY[key] || key };
                  break;
                }
              }
              pos.overridePlayer = overridePlayer;
            } else {
              pos.overridePlayer = null;
            }
          });
        });
      };

      if (window.OFFENSE_PERSONNEL) applyOverrides(window.OFFENSE_PERSONNEL, 'offense');
      if (window.DEFENSE_PERSONNEL) applyOverrides(window.DEFENSE_PERSONNEL, 'defense');

      setData({...staticData}); 
    })
    .catch(err => console.error("Database sync failed:", err));
  };

  useEffect(() => {
    loadData();
  }, []);

  if (!data) return (
    <div style={{ display: 'grid', placeItems: 'center', minHeight: '60vh', color: 'var(--fg-2)', fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '0.1em' }}>
      SYNCING WITH DATABASE…
    </div>
  );

  return (
    <>
      {/* Notice we are now passing refreshData down! */}
      <App data={data} refreshData={loadData} />
      <TweaksUI />
    </>
  );
}

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