
// ScoutingReport.jsx — Collaborative pre-game scouting notebook.
//
// A shared cozy "detective's notebook" the whole crew can co-edit before a Clash
// night. Stores multiple reports (one per upcoming opponent), each report holds
// per-lane enemy intel, target bans, game plan, and "don't forget" reminders.
//
// Persisted under localStorage key 'cozydraft-scouting-v1'.

const { useState, useEffect, useRef, useCallback, useMemo } = React;

// ── one-off CSS for the micro-interactions described in the brief ────────────
(() => {
  if (document.getElementById('scouting-report-css')) return;
  const s = document.createElement('style');
  s.id = 'scouting-report-css';
  s.textContent = `
    @keyframes sr-shake {
      0%   { transform: translateX(0)    rotate(0); }
      20%  { transform: translateX(-3px) rotate(-2deg); }
      40%  { transform: translateX( 3px) rotate( 2deg); }
      60%  { transform: translateX(-2px) rotate(-1deg); }
      80%  { transform: translateX( 2px) rotate( 1deg); }
      100% { transform: translateX(0)    rotate(0); }
    }
    @keyframes sr-shimmer {
      0%   { box-shadow: 0 0 0 0   #C5B4E300, 0 0 0 0 #F7DFA000; }
      50%  { box-shadow: 0 0 0 6px #C5B4E370, 0 0 14px 4px #F7DFA0a0; }
      100% { box-shadow: 0 0 0 12px #C5B4E300, 0 0 0 0 #F7DFA000; }
    }
    @keyframes sr-bob {
      0%, 100% { transform: translateY(0); }
      50%      { transform: translateY(-3px); }
    }
    @keyframes sr-pulse-sage {
      0%, 100% { box-shadow: 0 0 0 0 #7CBF8E80; }
      50%      { box-shadow: 0 0 0 8px #7CBF8E00; }
    }
    @keyframes sr-spin-slow { to { transform: rotate(360deg); } }

    .sr-tab        { transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1); }
    .sr-tab:hover  { animation: sr-bob 1.4s ease-in-out infinite; }
    .sr-shake      { animation: sr-shake 0.42s cubic-bezier(0.36, 0.07, 0.19, 0.97); }
    .sr-shimmer    { animation: sr-shimmer 0.7s ease-out; border-radius: 8px; }
    .sr-pulse-sage { animation: sr-pulse-sage 1.6s ease-out 2; }
    .sr-champ-chip-btn:focus-visible {
      outline: 2.5px solid var(--accent-orange) !important;
      outline-offset: 2px !important;
    }

    .sr-champ-scroll {
      scrollbar-width: thin;
      scrollbar-color: var(--accent-orange) var(--surface-nested);
    }
    .sr-champ-scroll::-webkit-scrollbar {
      width: 6px;
    }
    .sr-champ-scroll::-webkit-scrollbar-track {
      background: var(--surface-nested);
      border-radius: 4px;
    }
    .sr-champ-scroll::-webkit-scrollbar-thumb {
      background: var(--accent-orange);
      border-radius: 4px;
    }
    .sr-champ-scroll::-webkit-scrollbar-thumb:hover {
      background: #a25c30;
    }

    .sr-textarea {
      width: 100%; min-height: 78px; resize: vertical;
      border: 2px solid var(--border-default); border-radius: 14px;
      padding: 10px 12px; background: var(--surface-card); color: var(--text-primary);
      font-family: 'Nunito', sans-serif; font-weight: 700; font-size: 13.5px;
      line-height: 1.45; outline: none; transition: all 0.18s;
    }
    .sr-textarea:focus {
      border-color: var(--border-emphasis);
      box-shadow: 0 0 0 3px var(--border-default), 0 0 18px var(--border-default);
      background: var(--surface-card);
    }

    .sr-input {
      border: 2px solid var(--border-default); background: var(--surface-nested); color: var(--text-primary);
      font-family: 'Nunito'; font-weight: 800; font-size: 13px;
      padding: 6px 10px; outline: none; transition: all 0.18s;
    }
    .sr-input:focus { border-color: var(--border-emphasis); box-shadow: 0 0 0 2px var(--border-default); }

    .sr-hex-input {
      background: var(--surface-nested);
      padding: 10px 18px;
      border: 2px solid var(--border-emphasis);
      border-radius: 999px;
      font-family: 'Nunito'; font-weight: 800; font-size: 13px;
      color: var(--text-primary); outline: none; width: 100%;
      box-sizing: border-box;
      transition: box-shadow 0.18s, border-color 0.18s;
    }
    .sr-hex-input:focus { box-shadow: 0 0 0 3px var(--border-default); }
    .sr-hex-wrap {
      position: relative; flex: 1; min-width: 0;
    }
    .sr-hex-wrap:focus-within { box-shadow: none; }

    .sr-region-pill {
      background: #F7DFA0;
      border: 2px solid var(--border-emphasis);
      border-radius: 999px;
      padding: 6px 18px;
      font-family: 'Nunito'; font-weight: 800; font-size: 11px;
      color: var(--text-on-light); outline: none; cursor: pointer;
      appearance: none; -webkit-appearance: none;
      text-align: center;
    }
    .sr-region-pill option {
      background: #F7DFA0;
      color: var(--text-on-light);
    }
  `;
  document.head.appendChild(s);
})();

// ── persistence ──────────────────────────────────────────────────────────────
const STORAGE_KEY = 'cozydraft-scouting-v1';
const POSITIONS = ['TOP', 'JUNGLE', 'MID', 'ADC', 'SUPPORT'];
const REGIONS   = ['NA', 'EUW', 'EUNE', 'KR', 'BR', 'LAN', 'LAS', 'OCE', 'JP', 'TR', 'RU'];
const REGION_TO_PLATFORM = {
  NA: 'na1',
  EUW: 'euw1',
  EUNE: 'eun1',
  KR: 'kr',
  BR: 'br1',
  LAN: 'la1',
  LAS: 'la2',
  OCE: 'oc1',
  JP: 'jp1',
  TR: 'tr1',
  RU: 'ru',
};

function emptyLane() {
  return { riotId: '', region: 'NA', champPool: [], notes: '' };
}
function emptyReport(name = 'New scouting report') {
  return {
    id: Date.now() + Math.floor(Math.random() * 1000),
    name,
    subtitle: 'Saturday 7pm',
    createdAt: new Date().toLocaleDateString(),
    lanes: { TOP: emptyLane(), JUNGLE: emptyLane(), MID: emptyLane(), ADC: emptyLane(), SUPPORT: emptyLane() },
    bans: [null, null, null, null, null],     // each: { championId, reason } or null
    possibleBans: [],                          // up to 10 'maybe' bans: { championId, reason }
    gamePlan: '',
    priorities: [],                            // up to 5 short strings
  };
}

function loadReports() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (raw) {
      const parsed = JSON.parse(raw);
      if (parsed && Array.isArray(parsed.reports)) return parsed;
    }
  } catch {}
  return { reports: [], activeId: null };
}
function saveReports(state) {
  try { localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); } catch {}
}

// ── Small reusable bits ──────────────────────────────────────────────────────
function SavedChip({ visible }) {
  if (!visible) return null;
  return (
    <div className="sr-pulse-sage" style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      background: '#B8E0C0', border: '1.5px solid #7CBF8E',
      borderRadius: 20, padding: '3px 10px',
      fontFamily: 'Nunito', fontWeight: 800, fontSize: 11,
      color: '#2d6b47',
    }}>
      ✓ Saved
    </div>
  );
}

function ChampionPicker({ champions, onPick, onClose, anchorStyle = {} }) {
  const [q, setQ] = useState('');
  const ref = useRef(null);
  useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, [onClose]);

  const list = useMemo(() => {
    const arr = Object.values(champions || {});
    const f = q.trim().toLowerCase();
    return arr
      .filter(c => (window.matchesChampionSearch ? window.matchesChampionSearch(c, q) : (!f || c.name.toLowerCase().includes(f) || c.id.toLowerCase().includes(f))))
      .sort((a, b) => a.name.localeCompare(b.name))
      .slice(0, 60);
  }, [q, champions]);

  return (
    <div ref={ref} className="pop-in" style={{
      position: 'absolute', zIndex: 50,
      background: 'var(--surface-modal)', border: '2.5px solid var(--border-emphasis)',
      borderRadius: 18, padding: 10, width: 280,
      boxShadow: '0 12px 32px rgba(74, 55, 40, 0.3)',
      ...anchorStyle,
    }}>
      <input
        autoFocus
        placeholder="Search champ…"
        value={q}
        onChange={e => setQ(e.target.value)}
        className="sr-input"
        style={{ width: '100%', borderRadius: 12, marginBottom: 8 }}
      />
      <div style={{
        display: 'grid', gridTemplateColumns: 'repeat(6, 1fr)',
        gap: 4, maxHeight: 220, overflowY: 'auto',
      }}>
        {list.map(c => (
          <button key={c.id} onClick={() => { onPick(c.id); onClose(); }} className="cozy-btn" style={{
            border: 'none', background: 'transparent', padding: 2, cursor: 'pointer',
            borderRadius: 8,
          }} title={c.name}>
            <window.ChampionIcon championId={c.id} size={36} noAnim />
          </button>
        ))}
        {list.length === 0 && (
          <div style={{ gridColumn: '1 / -1', textAlign: 'center', color: 'var(--text-muted)', fontWeight: 700, fontSize: 12, padding: 16 }}>
            No matches 🌱
          </div>
        )}
      </div>
    </div>
  );
}

// ── Report tab (the cozy cards in the horizontal scroller) ───────────────────
function ReportTab({ report, active, onClick }) {
  return (
    <div
      onClick={onClick}
      className={`cozy-card sr-tab ${active ? 'active-card' : ''}`}
      style={{
        flexShrink: 0, width: 200, padding: '14px 14px 12px',
        cursor: 'pointer', position: 'relative',
        borderStyle: active ? 'dashed' : 'solid',
        borderWidth: active ? 3 : 2.5,
      }}
    >
      <div className="corner-dot corner-dot-bl"></div>
      <div className="corner-dot corner-dot-br"></div>
      <div style={{ paddingTop: 6, paddingLeft: 14, paddingRight: 14 }}>
        <div className="fredoka" style={{
          color: 'var(--text-primary)', fontSize: 14, lineHeight: 1.15,
          marginBottom: 4, overflow: 'hidden', textOverflow: 'ellipsis',
          whiteSpace: 'nowrap',
        }}>
          {report.name}
        </div>
        <div style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 800 }}>
          {report.subtitle}
        </div>
        {active && (
          <div style={{
            position: 'absolute', top: -10, right: 10,
            background: 'var(--accent-orange)', color: 'var(--surface-nested)',
            padding: '2px 10px', borderRadius: 12,
            fontFamily: 'Nunito', fontWeight: 800, fontSize: 10,
            display: 'inline-flex', alignItems: 'center', gap: 4,
            boxShadow: '0 2px 0 rgba(0,0,0,0.2)',
          }}>
            <span>spying</span> <window.CrystalSparkle size={10} color="var(--surface-nested)" />
          </div>
        )}
      </div>
    </div>
  );
}

// Helper to resolve champion info by id or name
function lookupChampion(champId, champName, champions) {
  if (champions && typeof champions === 'object') {
    const list = Object.values(champions);
    if (champId != null) {
      const byKey = list.find(c =>
        String(c.key) === String(champId) ||
        String(c.id).toLowerCase() === String(champId).toLowerCase()
      );
      if (byKey) return byKey;
    }
    if (champName) {
      const clean = champName.toLowerCase().replace(/[^a-z0-9]/g, '');
      const byName = list.find(c =>
        c.id.toLowerCase().replace(/[^a-z0-9]/g, '') === clean ||
        c.name.toLowerCase().replace(/[^a-z0-9]/g, '') === clean
      );
      if (byName) return byName;
    }
  }
  return { id: champName || champId, name: champName || (typeof champId === 'string' && isNaN(Number(champId)) ? champId : `Champion ${champId}`) };
}

// ── Scout Import Preview Panel ──────────────────────────────────────────────
function ScoutImportPanel({ isOpen, onClose, riotId, parsedRiotId, region, pos, lane, onChange, reportId, enemyIndex, champions, triggerRef, mode = 'quick' }) {
  const panelRef = useRef(null);
  const { lobbyCode, showToast } = window.useApp ? window.useApp() : {};
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [data, setData] = useState(null);
  const [selectedChampIds, setSelectedChampIds] = useState(new Set());
  const [masteryExpanded, setMasteryExpanded] = useState(false);

  const hasFetchedRef = useRef(false);
  const dataRef = useRef(data);
  dataRef.current = data;

  const platform = REGION_TO_PLATFORM[region] || REGION_TO_PLATFORM[(region || '').toUpperCase()] || 'na1';
  const gameName = parsedRiotId?.gameName;
  const tagLine = parsedRiotId?.tagLine;

  const fetchData = useCallback(async (isRetry = false) => {
    if (!gameName || !tagLine) return;
    // Never re-fetch if results are already showing (unless explicitly retrying)
    if (!isRetry && dataRef.current) return;

    setLoading(true);
    setError(null);
    setData(null);
    try {
      const fetchFn = mode === 'deep' ? window.scoutDeepImport : window.scoutImport;
      const fnName = mode === 'deep' ? 'scoutDeepImport' : 'scoutImport';
      if (typeof fetchFn !== 'function') {
        throw new Error(`${fnName} client helper is not loaded.`);
      }
      const res = await fetchFn({
        gameName,
        tagLine,
        platform
      });
      if (!res || res.ok === false) {
        setError(res?.message || 'Failed to scout player. Please try again.');
      } else {
        setData(res);
        const top3 = (res.recent || []).slice(0, 3).map(r => r.championId);
        setSelectedChampIds(new Set(top3));
      }
    } catch (err) {
      setError(err?.message || 'An unexpected error occurred while scouting.');
    } finally {
      setLoading(false);
    }
  }, [gameName, tagLine, platform, mode]);

  useEffect(() => {
    if (isOpen) {
      if (!hasFetchedRef.current) {
        hasFetchedRef.current = true;
        fetchData();
      }
    } else {
      hasFetchedRef.current = false;
      setData(null);
      setError(null);
      setLoading(false);
      setSelectedChampIds(new Set());
      setMasteryExpanded(false);
    }
  }, [isOpen, fetchData]);

  // Focus trap & Escape listener
  useEffect(() => {
    if (!isOpen) return;

    const timer = setTimeout(() => {
      if (panelRef.current) {
        const focusable = panelRef.current.querySelectorAll(
          'button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])'
        );
        if (focusable.length > 0) {
          focusable[0].focus();
        }
      }
    }, 50);

    const handleKeyDown = (e) => {
      if (e.key === 'Escape') {
        e.preventDefault();
        e.stopPropagation();
        onClose();
        if (triggerRef?.current) triggerRef.current.focus();
        return;
      }

      if (e.key === 'Tab') {
        if (!panelRef.current) return;
        const focusable = panelRef.current.querySelectorAll(
          'button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])'
        );
        if (focusable.length === 0) return;
        const first = focusable[0];
        const last = focusable[focusable.length - 1];

        if (e.shiftKey) {
          if (document.activeElement === first) {
            e.preventDefault();
            last.focus();
          }
        } else {
          if (document.activeElement === last) {
            e.preventDefault();
            first.focus();
          }
        }
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    return () => {
      clearTimeout(timer);
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [isOpen, onClose, triggerRef]);

  if (!isOpen) return null;

  const handleClose = () => {
    onClose();
    if (triggerRef?.current) triggerRef.current.focus();
  };

  const getChampInfo = (champId, champName) => lookupChampion(champId, champName, champions);

  const handleAddSelected = async () => {
    if (selectedChampIds.size === 0) {
      handleClose();
      return;
    }

    const targetRiotId = (riotId || lane?.riotId || '').trim();
    const existingList = Array.isArray(lane?.champPool)
      ? lane.champPool
      : Object.values(lane?.champPool || {});

    // Collect all existing keys (both championId and name, lowercase)
    const existingKeys = new Set();
    for (const item of existingList) {
      if (!item) continue;
      if (typeof item === 'string') {
        existingKeys.add(item.toLowerCase());
      } else if (typeof item === 'object') {
        if (item.championId) existingKeys.add(String(item.championId).toLowerCase());
        if (item.id) existingKeys.add(String(item.id).toLowerCase());
        if (item.name) existingKeys.add(String(item.name).toLowerCase());
      }
    }

    const toAdd = [];
    for (const selectedId of selectedChampIds) {
      const champInfo = getChampInfo(selectedId);
      const isAlreadyPresent =
        existingKeys.has(String(selectedId).toLowerCase()) ||
        (champInfo.id && existingKeys.has(String(champInfo.id).toLowerCase())) ||
        (champInfo.name && existingKeys.has(String(champInfo.name).toLowerCase()));

      if (!isAlreadyPresent) {
        const now = Date.now();
        const entry = {
          championId: champInfo.id || selectedId,
          source: 'riot',
          importedAt: now,
        };

        const recentItem = (data?.recent || []).find(r =>
          String(r.championId) === String(selectedId) ||
          (champInfo.id && String(r.championId) === String(champInfo.id))
        );
        if (recentItem && typeof recentItem.games === 'number') {
          entry.recentGames = recentItem.games;
        }

        const masteryItem = (data?.mastery || []).find(m =>
          String(m.championId) === String(selectedId) ||
          (champInfo.id && String(m.championId) === String(champInfo.id))
        );
        if (masteryItem && masteryItem.championLevel != null) {
          entry.mastery = {
            level: masteryItem.championLevel,
            points: masteryItem.championPoints ?? 0,
          };
        }

        toAdd.push(entry);
        existingKeys.add(String(selectedId).toLowerCase());
        if (champInfo.id) existingKeys.add(String(champInfo.id).toLowerCase());
        if (champInfo.name) existingKeys.add(String(champInfo.name).toLowerCase());
      }
    }

    if (toAdd.length === 0) {
      if (showToast) showToast('Already on the list.');
      handleClose();
      return;
    }

    // Write each selected champion to its own leaf path in RTDB under the enemy's champPool
    if (window.db && lobbyCode && reportId != null) {
      try {
        const reportsRef = window.db.ref(`rooms/${lobbyCode}/state/scoutingReports`);
        const reportsSnap = await reportsRef.once('value');
        const reportsVal = reportsSnap.val();
        const reportsArr = window.firebaseToArray(reportsVal) || [];
        const rIndex = reportsArr.findIndex(r => r.id === reportId);

        if (rIndex !== -1) {
          const enemiesArr = window.firebaseToArray(reportsArr[rIndex].enemies) || [];
          const eIndex = enemiesArr.findIndex(e => e.position === pos);
          const targetEnemyIndex = eIndex !== -1 ? eIndex : (enemyIndex != null ? enemyIndex : 0);

          const poolRef = window.db.ref(
            `rooms/${lobbyCode}/state/scoutingReports/${rIndex}/enemies/${targetEnemyIndex}/champPool`
          );
          const poolSnap = await poolRef.once('value');
          const poolVal = poolSnap.val();

          let nextIndex = 0;
          if (Array.isArray(poolVal)) {
            nextIndex = poolVal.length;
          } else if (poolVal && typeof poolVal === 'object') {
            const numKeys = Object.keys(poolVal).map(k => parseInt(k, 10)).filter(k => !isNaN(k));
            nextIndex = numKeys.length > 0 ? Math.max(...numKeys) + 1 : Object.keys(poolVal).length;
          }

          for (const entry of toAdd) {
            const leafRef = window.db.ref(
              `rooms/${lobbyCode}/state/scoutingReports/${rIndex}/enemies/${targetEnemyIndex}/champPool/${nextIndex}`
            );
            await leafRef.set(entry);
            nextIndex++;
          }
        }
      } catch (err) {
        console.error('Failed to write imported champions to RTDB:', err);
      }
    }

    // Update local state so UI reflects immediately
    if (typeof onChange === 'function') {
      onChange({
        champPool: [...existingList, ...toAdd]
      });
    }

    const confirmMsg = `Added ${toAdd.length} champs to ${targetRiotId}.`;
    if (showToast) showToast(confirmMsg);
    handleClose();
  };

  const toggleChamp = (champId) => {
    setSelectedChampIds(prev => {
      const next = new Set(prev);
      if (next.has(champId)) next.delete(champId);
      else next.add(champId);
      return next;
    });
  };

  const formatRelativeTime = (timestamp) => {
    if (!timestamp) return 'just now';
    const diffSec = Math.floor((Date.now() - timestamp) / 1000);
    if (diffSec < 60) return 'just now';
    const diffMin = Math.floor(diffSec / 60);
    if (diffMin < 60) return `${diffMin}m ago`;
    const diffHr = Math.floor(diffMin / 60);
    if (diffHr < 24) return `${diffHr}h ago`;
    const diffDays = Math.floor(diffHr / 24);
    return `${diffDays}d ago`;
  };


  const masteryIds = new Set((data?.mastery || []).map(m => String(m.championId)));
  const recentChampIds = new Set((data?.recent || []).map(r => String(r.championId)));
  const remainingMastery = (data?.mastery || []).filter(m => !recentChampIds.has(String(m.championId)));
  const isDeep = (data?.depth === 'deep') || (mode === 'deep');

  const allLoadedChampIds = useMemo(() => {
    const ids = [];
    (data?.recent || []).forEach(r => {
      if (r?.championId && !ids.includes(r.championId)) ids.push(r.championId);
    });
    (remainingMastery || []).forEach(m => {
      if (m?.championId && !ids.includes(m.championId)) ids.push(m.championId);
    });
    return ids;
  }, [data, remainingMastery]);

  const isAllSelected = allLoadedChampIds.length > 0 && allLoadedChampIds.every(id => selectedChampIds.has(id));

  const toggleSelectAll = () => {
    if (isAllSelected) {
      setSelectedChampIds(new Set());
    } else {
      setSelectedChampIds(new Set(allLoadedChampIds));
    }
  };

  return (
    <div
      ref={panelRef}
      role="dialog"
      aria-modal="true"
      aria-label={isDeep ? `Deep Scout for ${riotId || 'player'}` : `Import recent champions for ${riotId || 'player'}`}
      className="pop-in"
      onClick={(e) => e.stopPropagation()}
      onInput={(e) => e.stopPropagation()}
      style={{
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        minHeight: '100%',
        maxHeight: '90vh',
        overflowY: 'auto',
        zIndex: 60,
        background: 'var(--surface-card)',
        border: '2.5px solid var(--border-emphasis)',
        borderRadius: 20,
        padding: '16px',
        boxShadow: '0 8px 32px rgba(74, 55, 40, 0.35)',
        display: 'flex',
        flexDirection: 'column',
        gap: 10,
        boxSizing: 'border-box',
      }}
    >
      {/* Panel Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', borderBottom: '1.5px solid var(--border-default)', paddingBottom: 8 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ fontSize: 16 }}>{isDeep ? '🔬' : '📥'}</span>
          <div>
            <div className="fredoka" style={{ fontSize: 14, color: isDeep ? '#6C5CE7' : 'var(--accent-orange)' }}>
              {isDeep ? 'Deep Scout (50 ranked games)' : 'Recent form (last 10 games)'}
            </div>
            <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)' }}>
              {riotId.trim()} • {region}
            </div>
          </div>
        </div>
        <button
          type="button"
          onClick={handleClose}
          aria-label="Close import panel"
          className="cozy-btn"
          style={{
            background: 'var(--surface-nested)',
            color: 'var(--text-primary)',
            border: 'none',
            borderRadius: '50%',
            width: 26,
            height: 26,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            cursor: 'pointer',
            fontSize: 14,
            fontWeight: 800,
            padding: 0,
          }}
        >
          ×
        </button>
      </div>

      {/* Loading State */}
      {loading && (
        <div style={{ padding: '24px 12px', textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 10 }}>
          <div style={{ fontSize: 26, animation: 'sr-bob 1.4s ease-in-out infinite' }}>
            {mode === 'deep' ? '🔬' : '🕵️'}
          </div>
          <div style={{ fontFamily: 'Nunito', fontWeight: 800, fontSize: 13, color: 'var(--text-primary)' }}>
            {mode === 'deep' ? `Deep Scouting ${riotId.trim()}...` : `Scouting ${riotId.trim()}...`}
          </div>
          <div style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 700, maxWidth: 280, lineHeight: 1.4 }}>
            {mode === 'deep'
              ? 'Checking up to 50 ranked games sequentially from Riot API...'
              : 'Fetching match history from Riot API'}
          </div>
          {mode === 'deep' && (
            <div style={{
              width: '100%',
              maxWidth: 220,
              height: 8,
              background: 'var(--surface-nested)',
              borderRadius: 4,
              overflow: 'hidden',
              border: '1.5px solid var(--border-default)',
              marginTop: 4,
            }}>
              <div style={{
                height: '100%',
                background: 'linear-gradient(90deg, #6C5CE7, #a25c30, #6C5CE7)',
                backgroundSize: '200% 100%',
                animation: 'sr-shimmer 2s infinite linear',
                borderRadius: 3,
                width: '100%',
              }} />
            </div>
          )}
          <button
            type="button"
            onClick={handleClose}
            className="cozy-btn"
            style={{
              marginTop: 6,
              background: 'var(--surface-nested)',
              color: 'var(--text-muted)',
              border: '1.5px solid var(--border-default)',
              borderRadius: 12,
              padding: '5px 12px',
              fontFamily: 'Nunito',
              fontWeight: 800,
              fontSize: 11,
              cursor: 'pointer',
            }}
          >
            Cancel
          </button>
        </div>
      )}

      {/* Error State */}
      {!loading && error && (
        <div style={{ padding: '16px 8px', textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}>
          <div style={{ fontSize: 24 }}>⚠️</div>
          <div style={{ fontFamily: 'Nunito', fontWeight: 800, fontSize: 12.5, color: '#D9534F', maxWidth: 300, lineHeight: 1.4 }}>
            {error}
          </div>
          <div style={{ display: 'flex', gap: 8, marginTop: 6 }}>
            <button
              type="button"
              onClick={handleClose}
              className="cozy-btn"
              style={{
                background: 'var(--surface-nested)',
                color: 'var(--text-primary)',
                border: '1.5px solid var(--border-default)',
                borderRadius: 12,
                padding: '5px 14px',
                fontFamily: 'Nunito',
                fontWeight: 800,
                fontSize: 11,
                cursor: 'pointer',
              }}
            >
              Cancel
            </button>
            <button
              type="button"
              onClick={() => fetchData(true)}
              className="cozy-btn"
              style={{
                background: 'var(--accent-orange)',
                color: 'white',
                border: 'none',
                borderRadius: 12,
                padding: '5px 14px',
                fontFamily: 'Nunito',
                fontWeight: 800,
                fontSize: 11,
                cursor: 'pointer',
                boxShadow: '0 2px 0 #a25c30',
              }}
            >
              🔄 Retry
            </button>
          </div>
        </div>
      )}

      {/* Empty State */}
      {!loading && !error && data && (!data.recent || data.recent.length === 0) && (
        <div style={{ padding: '20px 8px', textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}>
          <div style={{ fontSize: 24 }}>🌱</div>
          <div style={{ fontFamily: 'Nunito', fontWeight: 800, fontSize: 13, color: 'var(--text-muted)' }}>
            {isDeep ? 'No ranked games found. Add champs manually.' : 'No recent games found. Add champs manually.'}
          </div>
          <button
            type="button"
            onClick={handleClose}
            className="cozy-btn"
            style={{
              marginTop: 4,
              background: 'var(--surface-nested)',
              color: 'var(--text-primary)',
              border: '1.5px solid var(--border-default)',
              borderRadius: 12,
              padding: '5px 14px',
              fontFamily: 'Nunito',
              fontWeight: 800,
              fontSize: 11,
              cursor: 'pointer',
            }}
          >
            Cancel
          </button>
        </div>
      )}

      {/* Success State */}
      {!loading && !error && data && data.recent && data.recent.length > 0 && (
        <>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', fontSize: 11, fontWeight: 700, color: 'var(--text-muted)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <span>{isDeep ? 'Deep Scout (50 ranked games)' : 'Recent form (last 10 games)'}</span>
              <button
                type="button"
                onClick={toggleSelectAll}
                className="cozy-btn"
                style={{
                  background: isAllSelected ? 'var(--accent-orange)' : 'var(--surface-nested)',
                  color: isAllSelected ? '#fff' : 'var(--text-primary)',
                  border: isAllSelected ? 'none' : '1.5px solid var(--border-default)',
                  borderRadius: 8,
                  padding: '2px 8px',
                  fontFamily: 'Nunito',
                  fontWeight: 800,
                  fontSize: 10,
                  cursor: 'pointer',
                  display: 'inline-flex',
                  alignItems: 'center',
                  gap: 3,
                  boxShadow: isAllSelected ? '0 1px 0 #a25c30' : 'none',
                }}
                title={isAllSelected ? 'Deselect all champions' : 'Select all champions'}
              >
                <span>{isAllSelected ? '✓' : '＋'}</span>
                {isAllSelected ? 'Clear all' : 'Select all'}
              </button>
            </div>
            <span>
              {isDeep && typeof data.gamesCounted === 'number'
                ? `${data.gamesCounted} ranked ${data.gamesCounted === 1 ? 'game' : 'games'} analyzed • `
                : ''}
              {data.recent.length} {data.recent.length === 1 ? 'champ' : 'champs'}
            </span>
          </div>

          {/* Recent list */}
          <div
            className="sr-champ-scroll"
            style={{
              display: 'flex',
              flexDirection: 'column',
              gap: 6,
              maxHeight: isDeep ? 230 : 180,
              overflowY: 'auto',
              paddingRight: 6,
            }}
          >
            {data.recent.map(item => {
              const champInfo = getChampInfo(item.championId, item.championName);
              const isChecked = selectedChampIds.has(item.championId);
              const isMastery = masteryIds.has(String(item.championId));
              const checkId = `scout-champ-${pos}-${item.championId}`;

              return (
                <label
                  key={item.championId}
                  htmlFor={checkId}
                  onClick={(e) => e.stopPropagation()}
                  style={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: 8,
                    cursor: 'pointer',
                    padding: '5px 8px',
                    borderRadius: 10,
                    background: isChecked ? 'var(--surface-nested)' : 'transparent',
                    border: `1.5px solid ${isChecked ? 'var(--border-emphasis)' : 'var(--border-default)'}`,
                    transition: 'all 0.15s ease',
                  }}
                >
                  <input
                    type="checkbox"
                    id={checkId}
                    checked={isChecked}
                    onChange={(e) => {
                      e.stopPropagation();
                      toggleChamp(item.championId);
                    }}
                    onClick={(e) => e.stopPropagation()}
                    onInput={(e) => e.stopPropagation()}
                    style={{
                      width: 15,
                      height: 15,
                      accentColor: 'var(--accent-orange)',
                      cursor: 'pointer',
                    }}
                  />
                  <window.ChampionIcon championId={champInfo.id} size={28} noAnim />
                  <span style={{ fontWeight: 800, fontSize: 12.5, flex: 1, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {champInfo.name}
                  </span>
                  <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>
                    {item.games} {item.games === 1 ? 'game' : 'games'}
                  </span>
                  {isMastery && (
                    <span style={{
                      background: '#F7DFA0',
                      border: '1.5px solid var(--border-emphasis)',
                      borderRadius: 999,
                      padding: '1px 6px',
                      fontSize: 9.5,
                      fontWeight: 800,
                      color: 'var(--text-on-light)',
                      fontFamily: 'Nunito',
                      display: 'inline-flex',
                      alignItems: 'center',
                      gap: 2,
                      whiteSpace: 'nowrap',
                    }}>
                      ⭐ Career mastery
                    </span>
                  )}
                </label>
              );
            })}
          </div>

          {/* Collapsible Career Mastery for remaining mastery champions */}
          {remainingMastery.length > 0 && (
            <div style={{ marginTop: 2 }}>
              <button
                type="button"
                onClick={() => setMasteryExpanded(!masteryExpanded)}
                className="cozy-btn"
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'space-between',
                  background: 'var(--surface-nested)',
                  border: '1.5px solid var(--border-default)',
                  borderRadius: 10,
                  padding: '5px 10px',
                  fontSize: 11,
                  fontWeight: 800,
                  cursor: 'pointer',
                  color: 'var(--text-primary)',
                  width: '100%',
                }}
              >
                <span>🏆 Career mastery ({remainingMastery.length})</span>
                <span style={{ fontSize: 10 }}>{masteryExpanded ? '▴' : '▾'}</span>
              </button>

              {masteryExpanded && (
                <div
                  className="sr-champ-scroll"
                  style={{
                    display: 'flex',
                    flexDirection: 'column',
                    gap: 6,
                    maxHeight: 130,
                    overflowY: 'auto',
                    marginTop: 6,
                    paddingRight: 6,
                  }}
                >
                  {remainingMastery.map(item => {
                    const champInfo = getChampInfo(item.championId);
                    const isChecked = selectedChampIds.has(item.championId);
                    const checkId = `scout-mastery-${pos}-${item.championId}`;

                    return (
                      <label
                        key={item.championId}
                        htmlFor={checkId}
                        onClick={(e) => e.stopPropagation()}
                        style={{
                          display: 'flex',
                          alignItems: 'center',
                          gap: 8,
                          cursor: 'pointer',
                          padding: '5px 8px',
                          borderRadius: 10,
                          background: isChecked ? 'var(--surface-nested)' : 'transparent',
                          border: `1.5px solid ${isChecked ? 'var(--border-emphasis)' : 'var(--border-default)'}`,
                          transition: 'all 0.15s ease',
                        }}
                      >
                        <input
                          type="checkbox"
                          id={checkId}
                          checked={isChecked}
                          onChange={(e) => {
                            e.stopPropagation();
                            toggleChamp(item.championId);
                          }}
                          onClick={(e) => e.stopPropagation()}
                          onInput={(e) => e.stopPropagation()}
                          style={{
                            width: 15,
                            height: 15,
                            accentColor: 'var(--accent-orange)',
                            cursor: 'pointer',
                          }}
                        />
                        <window.ChampionIcon championId={champInfo.id} size={28} noAnim />
                        <span style={{ fontWeight: 800, fontSize: 12.5, flex: 1, color: 'var(--text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                          {champInfo.name}
                        </span>
                        <span style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>
                          Lvl {item.championLevel}
                        </span>
                      </label>
                    );
                  })}
                </div>
              )}
            </div>
          )}

          {/* If all career mastery champions were already in recent/ranked list */}
          {remainingMastery.length === 0 && (data?.mastery || []).length > 0 && (
            <div style={{
              marginTop: 2,
              padding: '6px 10px',
              background: 'var(--surface-nested)',
              borderRadius: 10,
              border: '1.5px dashed var(--border-default)',
              fontSize: 10.5,
              fontWeight: 700,
              color: 'var(--text-muted)',
              display: 'flex',
              alignItems: 'center',
              gap: 6,
            }}>
              <span>🏆</span>
              <span>All top career mastery champions are already in the list above</span>
            </div>
          )}

          {/* Footer buttons */}
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8, marginTop: 4 }}>
            <button
              type="button"
              onClick={toggleSelectAll}
              className="cozy-btn"
              style={{
                background: 'var(--surface-nested)',
                color: 'var(--text-primary)',
                border: '1.5px solid var(--border-default)',
                borderRadius: 12,
                padding: '6px 12px',
                fontFamily: 'Nunito',
                fontWeight: 800,
                fontSize: 11,
                cursor: 'pointer',
                display: 'inline-flex',
                alignItems: 'center',
                gap: 5,
              }}
            >
              <span style={{ fontSize: 12 }}>{isAllSelected ? '☑' : '☐'}</span>
              {isAllSelected ? 'Deselect all' : 'Select all'}
            </button>

            <div style={{ display: 'flex', gap: 8 }}>
              <button
                type="button"
                onClick={handleClose}
                className="cozy-btn"
                style={{
                  background: 'var(--surface-nested)',
                  color: 'var(--text-primary)',
                  border: '1.5px solid var(--border-default)',
                  borderRadius: 12,
                  padding: '6px 14px',
                  fontFamily: 'Nunito',
                  fontWeight: 800,
                  fontSize: 11,
                  cursor: 'pointer',
                }}
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={handleAddSelected}
                disabled={selectedChampIds.size === 0}
                className="cozy-btn"
                style={{
                  background: selectedChampIds.size === 0 ? 'var(--surface-nested)' : 'var(--accent-orange)',
                  color: selectedChampIds.size === 0 ? 'var(--text-muted)' : 'white',
                  border: 'none',
                  borderRadius: 12,
                  padding: '6px 14px',
                  fontFamily: 'Nunito',
                  fontWeight: 800,
                  fontSize: 11,
                  cursor: selectedChampIds.size === 0 ? 'not-allowed' : 'pointer',
                  boxShadow: selectedChampIds.size === 0 ? 'none' : '0 2px 0 #a25c30',
                }}
              >
                Add selected ({selectedChampIds.size})
              </button>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// ── Champion Pool Chip with Info Popover ─────────────────────────────────────
function ChampPoolChip({
  id,
  index,
  pos,
  isLast,
  shimmerKey,
  onRemove,
  champions,
  activePopoverChip,
  setActivePopoverChip,
}) {
  const chipKey = `${pos}-${index}`;
  const isOpen = activePopoverChip === chipKey;
  const buttonRef = useRef(null);
  const popoverRef = useRef(null);

  const rawChampId = typeof id === 'object' ? (id.championId || id.id) : id;
  const champInfo = lookupChampion(rawChampId, null, champions);
  const champName = champInfo?.name || (typeof id === 'string' ? id : (id?.championName || champInfo?.id || 'Champion'));

  const mastery = typeof id === 'object' ? (id.mastery || (id.championLevel != null ? { level: id.championLevel, points: id.championPoints } : null)) : null;
  const recentGames = typeof id === 'object' ? (typeof id.recentGames === 'number' ? id.recentGames : (typeof id.games === 'number' ? id.games : null)) : null;
  const hasMastery = mastery && mastery.level != null;
  const hasRecent = typeof recentGames === 'number';

  const togglePopover = (e) => {
    if (e) {
      e.preventDefault();
      e.stopPropagation();
    }
    setActivePopoverChip(prev => (prev === chipKey ? null : chipKey));
  };

  useEffect(() => {
    if (!isOpen) return;

    const handlePointerDown = (e) => {
      if (popoverRef.current && popoverRef.current.contains(e.target)) {
        return;
      }
      if (buttonRef.current && buttonRef.current.contains(e.target)) {
        return;
      }
      setActivePopoverChip(null);
      if (!e.target.closest('button, input, select, textarea, a')) {
        buttonRef.current?.focus();
      }
    };

    const handleKeyDown = (e) => {
      if (e.key === 'Escape') {
        e.preventDefault();
        e.stopPropagation();
        setActivePopoverChip(null);
        buttonRef.current?.focus();
      }
    };

    document.addEventListener('pointerdown', handlePointerDown);
    document.addEventListener('keydown', handleKeyDown);

    return () => {
      document.removeEventListener('pointerdown', handlePointerDown);
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [isOpen, setActivePopoverChip, chipKey]);

  return (
    <div
      className={isLast ? 'sr-shimmer' : ''}
      style={{ position: 'relative' }}
      data-shimmer={shimmerKey}
    >
      <button
        ref={buttonRef}
        type="button"
        className="sr-champ-chip-btn"
        onClick={togglePopover}
        onKeyDown={(e) => {
          if (e.key === ' ' || e.key === 'Spacebar') {
            e.preventDefault();
            togglePopover(e);
          }
        }}
        aria-label={`${champName} details`}
        aria-expanded={isOpen}
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          padding: 0,
          background: 'none',
          border: 'none',
          cursor: 'pointer',
          borderRadius: 7,
          outline: 'none',
          boxShadow: isOpen ? '0 0 0 2px var(--accent-orange)' : 'none',
          transition: 'transform 0.1s ease, box-shadow 0.15s ease',
        }}
      >
        <window.ChampionIcon championId={rawChampId} size={32} noAnim />
      </button>

      <button
        type="button"
        onClick={(e) => {
          e.stopPropagation();
          if (isOpen) setActivePopoverChip(null);
          onRemove();
        }}
        aria-label={`Remove ${champName}`}
        style={{
          position: 'absolute',
          top: -5,
          right: -5,
          width: 16,
          height: 16,
          borderRadius: '50%',
          background: 'var(--text-primary)',
          color: 'var(--surface-nested)',
          border: 'none',
          cursor: 'pointer',
          fontSize: 10,
          lineHeight: '14px',
          fontFamily: 'Nunito',
          fontWeight: 800,
          padding: 0,
          zIndex: 2,
        }}
      >
        ×
      </button>

      {isOpen && (
        <div
          ref={popoverRef}
          role="tooltip"
          className="pop-in"
          style={{
            position: 'absolute',
            bottom: 'calc(100% + 7px)',
            left: '50%',
            transform: 'translateX(-50%)',
            zIndex: 60,
            background: 'var(--surface-card)',
            border: '2px solid var(--border-emphasis)',
            borderRadius: 12,
            padding: '6px 10px',
            boxShadow: '0 4px 16px rgba(74, 55, 40, 0.28)',
            minWidth: 100,
            maxWidth: 180,
            display: 'flex',
            flexDirection: 'column',
            gap: 2,
            pointerEvents: 'auto',
            textAlign: 'center',
            whiteSpace: 'nowrap',
          }}
        >
          <div
            style={{
              position: 'absolute',
              bottom: -5,
              left: '50%',
              transform: 'translateX(-50%) rotate(45deg)',
              width: 8,
              height: 8,
              background: 'var(--surface-card)',
              borderRight: '2px solid var(--border-emphasis)',
              borderBottom: '2px solid var(--border-emphasis)',
            }}
          />

          <div
            style={{
              fontFamily: 'Fredoka One, Nunito',
              fontWeight: 800,
              fontSize: 12,
              color: 'var(--accent-orange)',
              lineHeight: 1.25,
            }}
          >
            {champName}
          </div>

          {hasMastery && (
            <div
              style={{
                fontFamily: 'Nunito',
                fontWeight: 800,
                fontSize: 11,
                color: 'var(--text-primary)',
                lineHeight: 1.25,
              }}
            >
              Lvl {mastery.level} career mastery
            </div>
          )}

          {hasRecent && (
            <div
              style={{
                fontFamily: 'Nunito',
                fontWeight: 700,
                fontSize: 10.5,
                color: 'var(--text-muted)',
                lineHeight: 1.25,
              }}
            >
              {recentGames} {recentGames === 1 ? 'game' : 'games'} (recent form)
            </div>
          )}

          {!hasMastery && !hasRecent && (
            <div
              style={{
                fontFamily: 'Nunito',
                fontWeight: 700,
                fontSize: 10.5,
                color: 'var(--text-muted)',
                lineHeight: 1.25,
              }}
            >
              Added manually
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ── Enemy lane card (left column) ────────────────────────────────────────────
function EnemyLaneCard({ pos, lane, onChange, champions, reportId, enemyIndex, activePopoverChip, setActivePopoverChip }) {
  const [pickerOpen, setPickerOpen] = useState(false);
  const [shimmerKey, setShimmerKey] = useState(0);
  const [importOpen, setImportOpen] = useState(false);
  const [importMode, setImportMode] = useState('quick');
  const [deepConfirmOpen, setDeepConfirmOpen] = useState(false);
  const importTriggerRef = useRef(null);
  const deepTriggerRef = useRef(null);

  const posColor = window.POSITION_COLORS[pos];
  const archetype = window.ARCHETYPE_BY_POSITION[pos];

  const debouncedRiotId = window.useDebounceFirebaseUpdate(
    lane.riotId,
    (val) => onChange({ riotId: val })
  );

  const debouncedNotes = window.useDebounceFirebaseUpdate(
    lane.notes,
    (val) => onChange({ notes: val })
  );

  const rawRiotId = (debouncedRiotId.value || '').trim();
  const parsedRiotId = useMemo(() => {
    return window.parseRiotId ? window.parseRiotId(rawRiotId) : null;
  }, [rawRiotId]);
  const isImportDisabled = !rawRiotId || !parsedRiotId;

  const importTooltip = !rawRiotId
    ? 'Enter a Riot ID (e.g. Name#TAG) to import champions'
    : !parsedRiotId
    ? 'Riot ID must include a tag (e.g. Name#TAG)'
    : 'Import recent champions played from Riot API';

  const deepScoutTooltip = !rawRiotId
    ? 'Enter a Riot ID (e.g. Name#TAG) to Deep Scout'
    : !parsedRiotId
    ? 'Riot ID must include a tag (e.g. Name#TAG)'
    : 'Deep Scout up to 50 ranked games from Riot API';

  const addChamp = (id) => {
    if (lane.champPool.includes(id)) return;
    onChange({ champPool: [...lane.champPool, id] });
    setShimmerKey(k => k + 1);
  };
  const removeChamp = (id) =>
    onChange({ champPool: lane.champPool.filter(x => x !== id) });

  // External-tool URLs (these are just hyperlinks to public community sites).
  const idForUrl = encodeURIComponent((debouncedRiotId.value || '').replace('#', '-'));
  const links = [
    { label: 'op.gg',       color: '#AED6F1', shadow: '#7fb4d6',
      href: debouncedRiotId.value ? `https://op.gg/summoners/${lane.region.toLowerCase()}/${idForUrl}` : null },
    { label: 'U.GG',        color: '#C5B4E3', shadow: '#9e87cc',
      href: debouncedRiotId.value ? `https://u.gg/lol/profile/${lane.region.toLowerCase()}1/${idForUrl}/overview` : null },
    { label: 'Porofessor',  color: '#B8E0C0', shadow: '#7CBF8E',
      href: debouncedRiotId.value ? `https://porofessor.gg/live/${lane.region.toLowerCase()}/${idForUrl}` : null },
  ];

  return (
    <div className="cozy-card" style={{ padding: '18px 16px 14px', position: 'relative' }}>
      <div className="corner-dot corner-dot-bl"></div>
      <div className="corner-dot corner-dot-br"></div>

      {/* Top row: hex role + Riot ID input + region pill */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 6 }}>
        <window.HexFrame size={44} color={posColor} borderColor="var(--border-emphasis)" borderWidth={2.5}>
          <window.RoleSilhouette archetype={archetype} size={26} color="var(--text-on-light)" />
        </window.HexFrame>

        <div className="sr-hex-wrap" style={{ flex: 1 }}>
          <input
            className="sr-hex-input"
            placeholder="EnemyName#NA1"
            value={debouncedRiotId.value}
            onChange={e => debouncedRiotId.onChange(e.target.value)}
            onBlur={debouncedRiotId.onBlur}
            onFocus={debouncedRiotId.onFocus}
          />
        </div>

        <div style={{ position: 'relative' }}>
          <select
            value={lane.region}
            onChange={e => onChange({ region: e.target.value })}
            className="sr-region-pill"
            style={{ paddingRight: 26 }}
          >
            {REGIONS.map(r => <option key={r} value={r}>{r}</option>)}
          </select>
          <span style={{
            position: 'absolute', right: 8, top: '50%', transform: 'translateY(-50%)',
            fontSize: 9, color: 'var(--text-on-light)', pointerEvents: 'none', fontWeight: 800,
          }}>▾</span>
        </div>
      </div>

      {/* Quick link sticker buttons + Import recent champs + Deep Scout */}
      <div style={{ display: 'flex', gap: 8, marginTop: 12, flexWrap: 'wrap', alignItems: 'center' }}>
        {links.map(l => (
          <a
            key={l.label}
            href={l.href || '#'}
            target="_blank"
            rel="noopener noreferrer"
            onClick={(e) => { if (!l.href) e.preventDefault(); }}
            className="cozy-btn"
            style={{
              textDecoration: 'none',
              background: l.color, color: 'var(--text-on-light-pastel)',
              border: 'none', borderRadius: 12,
              padding: '4px 12px', fontSize: 11, fontWeight: 800,
              fontFamily: 'Nunito',
              boxShadow: `0 3px 0 ${l.shadow}`,
              opacity: l.href ? 1 : 0.5,
              cursor: l.href ? 'pointer' : 'not-allowed',
              display: 'inline-flex', alignItems: 'center', gap: 4,
            }}
          >
            {l.label} <span style={{ fontSize: 10 }}>↗</span>
          </a>
        ))}

        <button
          ref={importTriggerRef}
          type="button"
          disabled={isImportDisabled}
          title={importTooltip}
          onClick={() => {
            if (!isImportDisabled) {
              setImportMode('quick');
              setImportOpen(true);
            }
          }}
          className="cozy-btn"
          style={{
            background: '#F7DFA0',
            color: 'var(--text-on-light)',
            border: 'none',
            borderRadius: 12,
            padding: '4px 12px',
            fontSize: 11,
            fontWeight: 800,
            fontFamily: 'Nunito',
            boxShadow: isImportDisabled ? 'none' : '0 3px 0 #c8ae65',
            opacity: isImportDisabled ? 0.5 : 1,
            cursor: isImportDisabled ? 'not-allowed' : 'pointer',
            display: 'inline-flex',
            alignItems: 'center',
            gap: 4,
          }}
        >
          📥 Import recent champs
        </button>

        <button
          ref={deepTriggerRef}
          type="button"
          disabled={isImportDisabled}
          title={deepScoutTooltip}
          onClick={() => {
            if (!isImportDisabled) {
              setDeepConfirmOpen(true);
            }
          }}
          className="cozy-btn"
          style={{
            background: '#C5B4E3',
            color: 'var(--text-on-light-pastel)',
            border: 'none',
            borderRadius: 12,
            padding: '4px 12px',
            fontSize: 11,
            fontWeight: 800,
            fontFamily: 'Nunito',
            boxShadow: isImportDisabled ? 'none' : '0 3px 0 #9e87cc',
            opacity: isImportDisabled ? 0.5 : 1,
            cursor: isImportDisabled ? 'not-allowed' : 'pointer',
            display: 'inline-flex',
            alignItems: 'center',
            gap: 4,
          }}
        >
          🔬 Deep Scout
        </button>
      </div>

      {/* Deep Scout confirmation modal */}
      {deepConfirmOpen && (
        <div
          role="dialog"
          aria-modal="true"
          aria-label="Confirm Deep Scout"
          className="pop-in"
          onClick={(e) => e.stopPropagation()}
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            zIndex: 65,
            background: 'rgba(0, 0, 0, 0.45)',
            backdropFilter: 'blur(2px)',
            borderRadius: 20,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            padding: 16,
            boxSizing: 'border-box',
          }}
        >
          <div
            style={{
              background: 'var(--surface-card)',
              border: '2.5px solid var(--border-emphasis)',
              borderRadius: 16,
              padding: '16px 18px',
              maxWidth: 340,
              width: '100%',
              boxShadow: '0 8px 32px rgba(0, 0, 0, 0.35)',
              display: 'flex',
              flexDirection: 'column',
              gap: 12,
              textAlign: 'center',
            }}
          >
            <div style={{ fontSize: 28 }}>🔬</div>
            <div className="fredoka" style={{ fontSize: 15, color: 'var(--text-primary)' }}>
              Run Deep Scout?
            </div>
            <div style={{
              fontFamily: 'Nunito',
              fontSize: 12,
              fontWeight: 700,
              color: 'var(--text-secondary, var(--text-primary))',
              lineHeight: 1.45,
            }}>
              This checks up to 50 ranked games. This is faster and lighter on rate limits than before (~52 API calls), but it still uses part of the team's shared Riot API rate limit, so avoid running it for multiple opponents back to back.
            </div>
            <div style={{ display: 'flex', gap: 8, justifyContent: 'center', marginTop: 4 }}>
              <button
                type="button"
                onClick={() => setDeepConfirmOpen(false)}
                className="cozy-btn"
                style={{
                  background: 'var(--surface-nested)',
                  color: 'var(--text-primary)',
                  border: '1.5px solid var(--border-default)',
                  borderRadius: 12,
                  padding: '6px 16px',
                  fontFamily: 'Nunito',
                  fontWeight: 800,
                  fontSize: 12,
                  cursor: 'pointer',
                }}
              >
                Cancel
              </button>
              <button
                type="button"
                onClick={() => {
                  setDeepConfirmOpen(false);
                  setImportMode('deep');
                  setImportOpen(true);
                }}
                className="cozy-btn"
                style={{
                  background: '#6C5CE7',
                  color: '#FFFFFF',
                  border: 'none',
                  borderRadius: 12,
                  padding: '6px 16px',
                  fontFamily: 'Nunito',
                  fontWeight: 800,
                  fontSize: 12,
                  cursor: 'pointer',
                  boxShadow: '0 3px 0 #4D3DB5',
                }}
              >
                Confirm Deep Scout
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Champion pool */}
      <div style={{ marginTop: 14 }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 6,
          fontSize: 11, fontWeight: 800, color: 'var(--accent-orange)',
          textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 6,
        }}>
          <window.PawPrint size={14} color="var(--accent-orange)" />
          What they play
        </div>

        <div style={{
          position: 'relative',
          display: 'flex', flexWrap: 'wrap', gap: 6,
          padding: 8, background: 'var(--surface-nested)',
          border: '1.5px dashed var(--border-default)', borderRadius: 12,
          minHeight: 52, alignItems: 'center',
        }}>
          {lane.champPool.map((id, i) => (
            <ChampPoolChip
              key={typeof id === 'object' ? (id.championId ? `${id.championId}-${i}` : i) : `${id}-${i}`}
              id={id}
              index={i}
              pos={pos}
              isLast={i === lane.champPool.length - 1}
              shimmerKey={shimmerKey}
              onRemove={() => removeChamp(id)}
              champions={champions}
              activePopoverChip={activePopoverChip}
              setActivePopoverChip={setActivePopoverChip}
            />
          ))}
          <button
            onClick={() => setPickerOpen(true)}
            className="cozy-btn"
            style={{
              width: 32, height: 32, borderRadius: 8,
              border: '2px dashed var(--border-emphasis)', background: 'transparent',
              color: 'var(--accent-orange)', fontFamily: 'Fredoka One', fontSize: 18,
              cursor: 'pointer', padding: 0,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            }}
            title="Add a champ they play"
          >＋</button>
          {lane.champPool.length === 0 && (
            <span style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 12, marginLeft: 4 }}>
              Add champs they play…
            </span>
          )}
          {pickerOpen && (
            <ChampionPicker
              champions={champions}
              onClose={() => setPickerOpen(false)}
              onPick={addChamp}
              anchorStyle={{ top: '100%', left: 0, marginTop: 4 }}
            />
          )}
        </div>
      </div>

      {/* Notes */}
      <div style={{ marginTop: 12 }}>
        <textarea
          className="sr-textarea"
          placeholder="What to expect, weaknesses, playstyle… 📝"
          value={debouncedNotes.value}
          onChange={e => debouncedNotes.onChange(e.target.value)}
          onBlur={debouncedNotes.onBlur}
          onFocus={debouncedNotes.onFocus}
        />
      </div>

      {/* Scout import preview panel */}
      {importOpen && (
        <ScoutImportPanel
          isOpen={importOpen}
          onClose={() => setImportOpen(false)}
          mode={importMode}
          riotId={debouncedRiotId.value || ''}
          parsedRiotId={parsedRiotId}
          region={lane.region || 'NA'}
          pos={pos}
          lane={lane}
          onChange={onChange}
          reportId={reportId}
          enemyIndex={enemyIndex}
          champions={champions}
          triggerRef={importMode === 'deep' ? deepTriggerRef : importTriggerRef}
        />
      )}
    </div>
  );
}

// ── Target Ban Slot (helper component) ───────────────────────────────────────
function TargetBanSlot({ b, i, setBan, champions, pickerSlot, setPickerSlot, shakeIdx, setShakeIdx }) {
  const debouncedReason = window.useDebounceFirebaseUpdate(
    b?.reason || '',
    (val) => setBan(i, { ...b, reason: val })
  );

  return (
    <div style={{ flex: 1, position: 'relative' }}>
      <button
        onClick={() => setPickerSlot(i)}
        className={`cozy-btn ${shakeIdx === i ? 'sr-shake' : ''}`}
        style={{
          width: '100%', aspectRatio: '1 / 1.1', position: 'relative',
          background: 'transparent', border: 'none', padding: 0, cursor: 'pointer',
        }}
      >
        <window.HexFrame
          size="100%"
          color={b ? '#3a1f1f' : 'var(--surface-nested)'}
          borderColor={b ? '#C97070' : 'var(--border-default)'}
          borderWidth={2.5}
          style={{ width: '100%', height: '100%' }}
        >
          {b ? (
            <div style={{ position: 'relative', width: '74%', height: '74%' }}>
              <window.ChampionIcon championId={b.championId} size="100%" noAnim
                style={{ width: '100%', height: '100%', opacity: 0.65 }}
              />
              {/* Ban X overlay */}
              <svg viewBox="0 0 40 40" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
                <path d="M6 6 L34 34 M34 6 L6 34" stroke="#E85555" strokeWidth="4.5" strokeLinecap="round" />
                <circle cx="20" cy="20" r="17" stroke="#E85555" strokeWidth="2.5" fill="none" opacity="0.7" />
              </svg>
            </div>
          ) : (
            <div style={{ textAlign: 'center', color: 'var(--text-muted)', fontWeight: 800, fontSize: 10, lineHeight: 1.2 }}>
              <div style={{ fontSize: 20, marginBottom: 2 }}>🚫</div>
              Tap to ban
            </div>
          )}
        </window.HexFrame>
      </button>

      {b && (
        <>
          <div style={{ marginTop: 4, textAlign: 'center', fontSize: 11, fontWeight: 800, color: 'var(--text-primary)' }}>
            {champions[b.championId]?.name || b.championId}
          </div>
          <input
            className="sr-input"
            placeholder="Why ban? 🌱"
            value={debouncedReason.value}
            onChange={e => debouncedReason.onChange(e.target.value)}
            onBlur={debouncedReason.onBlur}
            onFocus={debouncedReason.onFocus}
            style={{
              width: '100%', marginTop: 4, borderRadius: 8,
              fontSize: 10.5, padding: '4px 6px', textAlign: 'center',
            }}
          />
          <button
            onClick={(e) => { e.stopPropagation(); setBan(i, null); }}
            style={{
              position: 'absolute', top: -4, right: -4,
              width: 18, height: 18, borderRadius: '50%',
              background: 'var(--text-primary)', color: 'var(--surface-nested)',
              border: 'none', cursor: 'pointer',
              fontSize: 10, fontFamily: 'Nunito', fontWeight: 800,
              lineHeight: '16px', padding: 0,
            }}
            title="Remove ban"
          >×</button>
        </>
      )}

      {pickerSlot === i && (
        <ChampionPicker
          champions={champions}
          onClose={() => setPickerSlot(null)}
          onPick={(id) => setBan(i, { championId: id, reason: '' })}
          anchorStyle={{ top: 'calc(100% + 4px)', left: 0 }}
        />
      )}
    </div>
  );
}

// ── Watchlist Slot (helper component) ────────────────────────────────────────
function WatchlistSlot({ p, i, possibleShakeIdx, removePossible, updatePossible, possibleEditIdx, setPossibleEditIdx, champions }) {
  const debouncedReason = window.useDebounceFirebaseUpdate(
    p.reason || '',
    (val) => updatePossible(i, { reason: val })
  );

  return (
    <div
      className={possibleShakeIdx === i ? 'sr-shake' : ''}
      style={{
        position: 'relative',
        display: 'flex', flexDirection: 'column', alignItems: 'center',
        width: 64,
      }}
    >
      <div style={{ position: 'relative', width: 44, height: 50 }}>
        <window.HexFrame
          size={44}
          color="#3a1f1f"
          borderColor="#C97070"
          borderWidth={2}
          style={{ width: 44, height: 50 }}
        >
          <div style={{ position: 'relative', width: '74%', height: '74%' }}>
            <window.ChampionIcon
              championId={p.championId} size="100%" noAnim
              style={{ width: '100%', height: '100%', opacity: 0.65 }}
            />
            <svg viewBox="0 0 40 40" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%' }}>
              <path d="M8 8 L32 32 M32 8 L8 32" stroke="#E85555" strokeWidth="3.5" strokeLinecap="round" />
            </svg>
          </div>
        </window.HexFrame>
        <button
          onClick={() => removePossible(i)}
          style={{
            position: 'absolute', top: -3, right: -3,
            width: 16, height: 16, borderRadius: '50%',
            background: 'var(--text-primary)', color: 'var(--surface-nested)',
            border: 'none', cursor: 'pointer',
            fontSize: 10, lineHeight: '14px',
            fontFamily: 'Nunito', fontWeight: 800, padding: 0,
          }}
          title="Remove from watchlist"
        >×</button>
      </div>
      <div style={{
        marginTop: 2, fontSize: 10, fontWeight: 800, color: 'var(--text-primary)',
        maxWidth: 64, overflow: 'hidden', textOverflow: 'ellipsis',
        whiteSpace: 'nowrap', textAlign: 'center',
      }}>
        {champions[p.championId]?.name || p.championId}
      </div>
      <button
        onClick={() => setPossibleEditIdx(possibleEditIdx === i ? -1 : i)}
        className="cozy-btn"
        style={{
          marginTop: 2, padding: '1px 6px',
          fontSize: 9, fontFamily: 'Nunito', fontWeight: 800,
          color: p.reason ? 'var(--accent-green)' : 'var(--text-muted)',
          background: p.reason ? 'rgba(184, 224, 192, 0.25)' : 'transparent',
          border: `1px solid ${p.reason ? 'var(--accent-green)' : 'var(--border-default)'}`,
          borderRadius: 8, cursor: 'pointer', whiteSpace: 'nowrap',
        }}
        title={p.reason || 'Add a note'}
      >
        {p.reason ? '📝 note' : '+ note'}
      </button>
      {possibleEditIdx === i && (
        <input
          autoFocus
          className="sr-input"
          placeholder="Why bother? 🌱"
          value={debouncedReason.value}
          onChange={e => debouncedReason.onChange(e.target.value)}
          onBlur={() => {
            debouncedReason.onBlur();
            setPossibleEditIdx(-1);
          }}
          onKeyDown={e => {
            if (e.key === 'Enter' || e.key === 'Escape') {
              debouncedReason.onBlur();
              setPossibleEditIdx(-1);
            }
          }}
          style={{
            position: 'absolute', top: '100%', left: '50%', transform: 'translateX(-50%)',
            width: 160, marginTop: 4, borderRadius: 10, fontSize: 11,
            zIndex: 30, boxShadow: '0 6px 20px rgba(74, 55, 40, 0.3)',
          }}
        />
      )}
    </div>
  );
}

// ── Target Bans card ─────────────────────────────────────────────────────────
function TargetBansCard({ bans, onChange, possibleBans = [], onPossibleBansChange, champions }) {
  const [pickerSlot, setPickerSlot] = useState(null);
  const [shakeIdx, setShakeIdx] = useState(-1);
  const [possiblePickerOpen, setPossiblePickerOpen] = useState(false);
  const [possibleEditIdx, setPossibleEditIdx] = useState(-1);
  const [possibleShakeIdx, setPossibleShakeIdx] = useState(-1);

  const setBan = (idx, ban) => {
    const next = [...bans];
    next[idx] = ban;
    onChange(next);
    if (ban) { setShakeIdx(idx); setTimeout(() => setShakeIdx(-1), 500); }
  };

  const addPossible = (id) => {
    if (possibleBans.length >= 10) return;
    if (possibleBans.some(p => p.championId === id)) return;
    const next = [...possibleBans, { championId: id, reason: '' }];
    onPossibleBansChange(next);
    const newIdx = next.length - 1;
    setPossibleShakeIdx(newIdx);
    setTimeout(() => setPossibleShakeIdx(-1), 500);
  };
  const removePossible = (idx) =>
    onPossibleBansChange(possibleBans.filter((_, i) => i !== idx));
  const updatePossible = (idx, patch) =>
    onPossibleBansChange(possibleBans.map((p, i) => i === idx ? { ...p, ...patch } : p));

  return (
    <div className="cozy-card" style={{ padding: '18px 18px 14px', position: 'relative' }}>
      <div className="corner-dot corner-dot-bl"></div>
      <div className="corner-dot corner-dot-br"></div>

      <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginTop: 4, marginBottom: 12 }}>
        <h2 className="fredoka" style={{ color: '#C97070', fontSize: 22, margin: 0 }}>
          Target Bans
        </h2>
        <span style={{ fontSize: 18 }}>⚔️</span>
        <span style={{
          marginLeft: 'auto', fontSize: 11, fontWeight: 800, color: 'var(--text-muted)',
        }}>
          {bans.filter(Boolean).length}/5 locked in
        </span>
      </div>

      <div style={{ display: 'flex', gap: 10, justifyContent: 'space-between' }}>
        {bans.map((b, i) => (
          <TargetBanSlot
            key={i}
            b={b}
            i={i}
            setBan={setBan}
            champions={champions}
            pickerSlot={pickerSlot}
            setPickerSlot={setPickerSlot}
            shakeIdx={shakeIdx}
            setShakeIdx={setShakeIdx}
          />
        ))}
      </div>

      {/* ─── Possible bans subsection ─────────────────────────────────────── */}
      <div style={{
        marginTop: 18, paddingTop: 14,
        borderTop: '1.5px dashed var(--border-default)',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
          <window.RuneGlyph variant={2} size={14} color="var(--accent-orange)" />
          <div style={{
            fontFamily: 'Nunito', fontWeight: 800, fontSize: 12,
            color: 'var(--accent-orange)', textTransform: 'uppercase', letterSpacing: 0.5,
          }}>
            Possible bans — on the watchlist
          </div>
          <span style={{ marginLeft: 'auto', fontSize: 11, fontWeight: 800, color: 'var(--text-muted)' }}>
            {possibleBans.length}/10
          </span>
        </div>
        <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 12, margin: '0 0 10px' }}>
          Backup picks if a target is taken first, or scary champs we're still debating ✦
        </p>

        <div style={{
          position: 'relative',
          display: 'flex', flexWrap: 'wrap', gap: 8,
          padding: 10, background: 'var(--surface-nested)',
          border: '1.5px dashed var(--border-default)', borderRadius: 14,
          minHeight: 64, alignItems: 'flex-start',
        }}>
          {possibleBans.map((p, i) => (
            <WatchlistSlot
              key={`${p.championId}-${i}`}
              p={p}
              i={i}
              possibleShakeIdx={possibleShakeIdx}
              removePossible={removePossible}
              updatePossible={updatePossible}
              possibleEditIdx={possibleEditIdx}
              setPossibleEditIdx={setPossibleEditIdx}
              champions={champions}
            />
          ))}

          {possibleBans.length < 10 && (
            <button
              onClick={() => setPossiblePickerOpen(true)}
              className="cozy-btn"
              style={{
                width: 44, height: 50, marginTop: 0,
                clipPath: window.hexClip,
                background: 'transparent',
                border: 'none', padding: 0, cursor: 'pointer',
                position: 'relative',
              }}
              title="Add a possible ban"
            >
              <div style={{
                position: 'absolute', inset: 0,
                background: 'repeating-linear-gradient(45deg, var(--border-default) 0 4px, transparent 4px 8px)',
                clipPath: window.hexClip,
              }} />
              <div style={{
                position: 'absolute', inset: 2,
                background: 'var(--surface-nested)',
                clipPath: window.hexClip,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                color: 'var(--accent-orange)', fontFamily: 'Fredoka One', fontSize: 22,
              }}>＋</div>
            </button>
          )}

          {possibleBans.length === 0 && (
            <span style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 12, marginLeft: 6, alignSelf: 'center' }}>
              Stash backup bans here…
            </span>
          )}

          {possiblePickerOpen && (
            <ChampionPicker
              champions={champions}
              onClose={() => setPossiblePickerOpen(false)}
              onPick={addPossible}
              anchorStyle={{ top: '100%', left: 0, marginTop: 6 }}
            />
          )}
        </div>
      </div>
    </div>
  );
}

// ── Game Plan & Priority Focus ───────────────────────────────────────────────
function GamePlanCard({ plan, onChange }) {
  const debouncedPlan = window.useDebounceFirebaseUpdate(
    plan,
    onChange
  );

  return (
    <div className="cozy-card" style={{ padding: '18px 18px 14px', position: 'relative' }}>
      <div className="corner-dot corner-dot-bl"></div>
      <div className="corner-dot corner-dot-br"></div>
      <div style={{ marginTop: 4 }}>
        <h2 className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 22, margin: 0, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          Game Plan <span style={{ fontSize: 18 }}>🍲</span>
        </h2>
        <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 12.5, margin: '4px 0 10px' }}>
          What's the win condition vs this team?
        </p>
        <textarea
          className="sr-textarea"
          value={debouncedPlan.value}
          onChange={e => debouncedPlan.onChange(e.target.value)}
          onBlur={debouncedPlan.onBlur}
          onFocus={debouncedPlan.onFocus}
          placeholder="What lanes do we want to snowball? What's our biggest threat? When do we want to teamfight?"
          style={{ minHeight: 120, background: 'var(--surface-card)', borderColor: 'var(--border-default)' }}
        />
      </div>
    </div>
  );
}

function PriorityFocusCard({ priorities, onChange }) {
  const [draft, setDraft] = useState('');
  const add = () => {
    const v = draft.trim();
    if (!v || priorities.length >= 5) return;
    onChange([...priorities, v]);
    setDraft('');
  };
  const remove = (i) => onChange(priorities.filter((_, idx) => idx !== i));

  return (
    <div className="cozy-card" style={{ padding: '18px 18px 14px', position: 'relative' }}>
      <div className="corner-dot corner-dot-bl"></div>
      <div className="corner-dot corner-dot-br"></div>
      <div style={{ marginTop: 4 }}>
        <h2 className="fredoka" style={{ color: '#7CBF8E', fontSize: 22, margin: 0, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
          Don't forget! <window.CrystalSparkle size={16} color="#7CBF8E" />
        </h2>
        <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 12.5, margin: '4px 0 10px' }}>
          Top 3 things to remember during the game…
        </p>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {priorities.map((p, i) => (
            <div key={i} className="pop-in" style={{
              display: 'inline-flex', alignItems: 'center', gap: 8,
              background: '#B8E0C0', border: '1.5px solid #7CBF8E',
              borderRadius: 16, padding: '5px 12px 5px 8px',
              color: '#2d6b47', fontFamily: 'Nunito', fontWeight: 800, fontSize: 13,
            }}>
              <window.PawPrint size={14} color="#2d6b47" />
              <span style={{ flex: 1 }}>{p}</span>
              <button onClick={() => remove(i)} style={{
                width: 18, height: 18, borderRadius: '50%',
                background: '#2d6b47', color: '#B8E0C0', border: 'none',
                cursor: 'pointer', fontFamily: 'Nunito', fontWeight: 800, fontSize: 11,
                lineHeight: '16px', padding: 0,
              }}>×</button>
            </div>
          ))}

          {priorities.length < 5 && (
            <div style={{ display: 'flex', gap: 6, marginTop: 4 }}>
              <input
                className="sr-input"
                style={{ flex: 1, borderRadius: 14 }}
                placeholder={priorities.length === 0 ? 'e.g. ward Baron at 18min ✦' : 'Add another reminder…'}
                value={draft}
                onChange={e => setDraft(e.target.value)}
                onKeyDown={e => { if (e.key === 'Enter') add(); }}
              />
              <window.CozyButton color="sage" small onClick={add}>＋ Add</window.CozyButton>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Empty state ──────────────────────────────────────────────────────────────
function EmptyState({ onCreate }) {
  return (
    <div className="cozy-card" style={{
      maxWidth: 520, margin: '40px auto', padding: '40px 30px',
      textAlign: 'center', position: 'relative',
    }}>
      <div className="corner-dot corner-dot-bl"></div>
      <div className="corner-dot corner-dot-br"></div>

      {/* Floating "detective poro" — original cozy mascot holding a magnifier */}
      <div className="float" style={{ display: 'inline-block', marginBottom: 16 }}>
        <svg viewBox="0 0 120 110" width="140" height="128">
          {/* body */}
          <ellipse cx="56" cy="68" rx="36" ry="30" fill="var(--surface-card)" stroke="var(--border-emphasis)" strokeWidth="2.5" />
          {/* belly */}
          <ellipse cx="56" cy="76" rx="22" ry="16" fill="var(--surface-nested)" />
          {/* ears */}
          <path d="M28 46 Q24 32 36 30 L42 44 Z" fill="var(--surface-card)" stroke="var(--border-emphasis)" strokeWidth="2.5" strokeLinejoin="round" />
          <path d="M84 46 Q88 32 76 30 L70 44 Z" fill="var(--surface-card)" stroke="var(--border-emphasis)" strokeWidth="2.5" strokeLinejoin="round" />
          <path d="M30 42 Q28 36 34 35" fill="#F2A7C3" />
          <path d="M82 42 Q84 36 78 35" fill="#F2A7C3" />
          {/* face */}
          <circle cx="46" cy="60" r="2.5" fill="var(--text-primary)" />
          <circle cx="64" cy="60" r="2.5" fill="var(--text-primary)" />
          <circle cx="46.7" cy="59.3" r="0.8" fill="var(--surface-card)" />
          <circle cx="64.7" cy="59.3" r="0.8" fill="var(--surface-card)" />
          <ellipse cx="55" cy="67" rx="3" ry="2" fill="var(--text-primary)" />
          <path d="M52 70 Q55 73 58 70" stroke="var(--text-primary)" strokeWidth="1.6" fill="none" strokeLinecap="round" />
          {/* cheek blush */}
          <ellipse cx="39" cy="66" rx="3" ry="2" fill="#F2A7C3" opacity="0.6" />
          <ellipse cx="71" cy="66" rx="3" ry="2" fill="#F2A7C3" opacity="0.6" />
          {/* magnifying glass */}
          <circle cx="92" cy="44" r="14" fill="#AED6F140" stroke="var(--border-emphasis)" strokeWidth="2.5" />
          <circle cx="92" cy="44" r="14" fill="none" stroke="var(--surface-card)" strokeWidth="1" opacity="0.8" />
          <path d="M102 54 L114 66" stroke="var(--border-emphasis)" strokeWidth="4" strokeLinecap="round" />
          <path d="M85 38 Q92 32 98 38" stroke="var(--surface-card)" strokeWidth="1.5" fill="none" opacity="0.8" />
          {/* paw on handle */}
          <ellipse cx="78" cy="62" rx="6" ry="5" fill="var(--surface-card)" stroke="var(--border-emphasis)" strokeWidth="2" />
          {/* sparkle */}
          <g transform="translate(20, 22)">
            <path d="M0 -6 L1.2 -1.2 L6 0 L1.2 1.2 L0 6 L-1.2 1.2 L-6 0 L-1.2 -1.2 Z" fill="#F7DFA0" />
          </g>
          <g transform="translate(100, 18)">
            <path d="M0 -4 L0.8 -0.8 L4 0 L0.8 0.8 L0 4 L-0.8 0.8 L-4 0 L-0.8 -0.8 Z" fill="#C5B4E3" />
          </g>
        </svg>
      </div>

      <h2 className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 28, margin: '0 0 8px' }}>
        No scouting reports yet! 👁️
      </h2>
      <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 14, margin: '0 0 22px', maxWidth: 380, marginLeft: 'auto', marginRight: 'auto', lineHeight: 1.45 }}>
        Start a report to prep for your next match. The whole crew can write notes together!
      </p>
      <window.CozyButton color="sage" onClick={onCreate}>
        Create your first report 🌱
      </window.CozyButton>
    </div>
  );
}

// ── Live presence chip (uses claimed online players) ─────────────────────────
function ScoutingPresence() {
  const { players, POSITION_COLORS } = window.useApp();
  const online = players.filter(p => p.claimed && p.online).slice(0, 5);
  return (
    <div className="cozy-card" style={{ padding: '6px 14px 6px 8px', display: 'inline-flex', alignItems: 'center', gap: 10 }}>
      <div className="corner-dot corner-dot-bl"></div>
      <div className="corner-dot corner-dot-br"></div>
      <div style={{ display: 'inline-flex', marginLeft: 14 }}>
        {online.map((p, i) => (
          <div key={p.id} title={`${p.name} · ${p.position}`} style={{
            marginLeft: i === 0 ? 0 : -10,
            position: 'relative',
          }}>
            <window.HexFrame size={26} color={p.identityColor || POSITION_COLORS[p.position]} borderColor="var(--border-emphasis)" borderWidth={1.8}>
              <span style={{ fontFamily: 'Fredoka One', fontSize: 10, color: 'var(--text-on-light)' }}>{p.name[0]}</span>
            </window.HexFrame>
            <div style={{
              position: 'absolute', bottom: -1, right: -1,
              width: 7, height: 7, borderRadius: '50%',
              background: '#7CBF8E', border: '1.5px solid var(--surface-card)',
            }} />
          </div>
        ))}
      </div>
      <div style={{
        fontFamily: 'Nunito', fontWeight: 800, fontSize: 11.5, color: 'var(--text-primary)',
        display: 'inline-flex', alignItems: 'center', gap: 4, paddingRight: 4,
      }}>
        Scouting together <span>👁️</span> <window.CrystalSparkle size={11} color="#C5B4E3" />
      </div>
    </div>
  );
}

// ── Main screen ──────────────────────────────────────────────────────────────
function ScoutingReport() {
  const {
    scoutingReports: reports,
    activeScoutingReportId: activeId,
    createScoutingReport,
    updateScoutingReport,
    updateScoutingEnemy,
    deleteScoutingReport,
    setActiveScoutingReport,
    champions,
    showToast,
    lobbyCode,
    sessionUserId,
    players,
    myUserId
  } = window.useApp();

  const [renaming, setRenaming] = useState(false);
  const [renameDraft, setRenameDraft] = useState('');
  const [savedFlash, setSavedFlash] = useState(false);
  const [activePopoverChip, setActivePopoverChip] = useState(null);
  const [editors, setEditors] = useState({});
  const isFirstRun = useRef(true);
  const prevReportsRef = useRef(reports);
  const active = reports.find(r => r.id === activeId) || reports[0] || null;

  // Track local player details for presence
  const me = players.find(p => p.ownerId === sessionUserId) || players.find(p => p.id === myUserId) || players[0];
  const displayName = me ? me.name : 'Teammate';
  const displayColor = me ? me.identityColor : '#C4845A';

  // Listen to teammates' scouting presence entries in Firebase
  useEffect(() => {
    if (!window.db || !lobbyCode) return;
    const presenceRef = window.db.ref(`rooms/${lobbyCode}/presence`);
    const handleValue = (snapshot) => {
      setEditors(snapshot.val() || {});
    };
    presenceRef.on('value', handleValue);
    return () => {
      try {
        presenceRef.off('value', handleValue);
      } catch (e) {}
    };
  }, [lobbyCode]);

  // Publish presence when opening/switching reports, clear on report switch, unmount, or disconnect
  useEffect(() => {
    if (!window.db || !lobbyCode || !sessionUserId) return;
    const currentReportId = active?.id;
    const myPresenceRef = window.db.ref(`rooms/${lobbyCode}/presence/${sessionUserId}`);

    if (currentReportId) {
      myPresenceRef.set({
        userId: sessionUserId,
        userName: displayName,
        userColor: displayColor,
        reportId: currentReportId,
        timestamp: Date.now()
      });
      myPresenceRef.onDisconnect().remove();
    } else {
      myPresenceRef.remove();
    }

    return () => {
      try {
        myPresenceRef.remove();
      } catch (e) {}
    };
  }, [lobbyCode, sessionUserId, active?.id, displayName, displayColor]);

  // Flash saved chip briefly when reports update
  useEffect(() => {
    if (isFirstRun.current) {
      isFirstRun.current = false;
      prevReportsRef.current = reports;
      return;
    }
    if (JSON.stringify(prevReportsRef.current) !== JSON.stringify(reports)) {
      setSavedFlash(true);
      const t = setTimeout(() => setSavedFlash(false), 1400);
      prevReportsRef.current = reports;
      return () => clearTimeout(t);
    }
  }, [reports]);

  // Filter active editors of this report
  const activeEditors = useMemo(() => {
    const currentReportId = active?.id;
    if (!currentReportId) return [];
    return Object.entries(editors)
      .filter(([uId, data]) => uId !== sessionUserId && data && data.reportId === currentReportId)
      .map(([_, data]) => data);
  }, [editors, active?.id, sessionUserId]);

  const editorsText = useMemo(() => {
    if (activeEditors.length === 0) return '';
    const names = activeEditors.map(e => e.userName);
    if (names.length === 1) return `✏️ ${names[0]} is editing`;
    if (names.length === 2) return `✏️ ${names[0]} and ${names[1]} are editing`;
    return `✏️ ${names.slice(0, 2).join(', ')} and ${names.length - 2} others are editing`;
  }, [activeEditors]);

  const safeBans = useMemo(() => {
    const arr = [...(active?.targetBans || [])];
    while (arr.length < 5) arr.push(null);
    return arr.slice(0, 5);
  }, [active?.targetBans]);

  const createReport = async () => {
    const n = reports.length + 1;
    const newReport = await createScoutingReport(`vs Opponent #${n}`);
    if (newReport?.id) {
      setActiveScoutingReport(newReport.id);
    }
    showToast && showToast('New scouting report started 🌱');
  };

  const deleteReport = () => {
    if (!active) return;
    if (!window.confirm(`Delete "${active.name}"? This can't be undone.`)) return;
    const nextReports = reports.filter(r => r.id !== active.id);
    const nextActiveId = nextReports[0]?.id || null;
    deleteScoutingReport(active.id);
    setActiveScoutingReport(nextActiveId);
    showToast && showToast('Report deleted 🗑️');
  };

  const openAllOpgg = () => {
    if (!active) return;
    let opened = 0;
    POSITIONS.forEach(pos => {
      const enemy = (active.enemies || []).find(e => e.position === pos);
      if (enemy && enemy.riotId) {
        const id = encodeURIComponent(enemy.riotId.replace('#', '-'));
        window.open(`https://op.gg/summoners/${enemy.region.toLowerCase()}/${id}`, '_blank', 'noopener');
        opened += 1;
      }
    });
    showToast && showToast(opened ? `Opened ${opened} profiles 👁️` : 'Add some Riot IDs first 🌱');
  };

  const copyLink = () => {
    if (!active) return;
    const link = `${window.location.origin}${window.location.pathname}#scout/report/${active.id}`;
    navigator.clipboard?.writeText(link).then(
      () => showToast && showToast('Report link copied 📋'),
      () => showToast && showToast('Couldn\'t copy — try again 🌱'),
    );
  };

  const startRename = () => { setRenaming(true); setRenameDraft(active?.name || ''); };
  const commitRename = () => {
    const v = renameDraft.trim();
    if (v) updateScoutingReport(active.id, { name: v });
    setRenaming(false);
  };

  // ── empty state ────────────────────────────────────────────────────────────
  if (reports.length === 0 || !active) {
    return (
      <div style={{ padding: 20, position: 'relative' }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 8, gap: 12, flexWrap: 'wrap' }}>
          <div>
            <h1 className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 28, margin: 0, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
              Scouting Report <span>👁️</span>
            </h1>
            <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 14, margin: '4px 0 0' }}>
              A shared notebook for the crew — prep your next match together
            </p>
          </div>
          <ScoutingPresence />
        </div>
        <EmptyState onCreate={createReport} />
      </div>
    );
  }

  // ── main layout ────────────────────────────────────────────────────────────
  return (
    <div style={{ padding: '20px 20px 24px', position: 'relative' }}>
      {/* Header row */}
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', marginBottom: 12, gap: 12, flexWrap: 'wrap' }}>
        <div style={{ minWidth: 0 }}>
          <h1 className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 28, margin: 0, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
            Scouting Report <span>👁️</span>
            <SavedChip visible={savedFlash} />
          </h1>
          <p style={{ color: 'var(--text-muted)', fontWeight: 700, fontSize: 14, margin: '4px 0 0' }}>
            Recon the enemy team & lock in your game plan — the crew is taking notes ✦
          </p>
        </div>
        <ScoutingPresence />
      </div>

      {/* Report selector */}
      <div style={{ position: 'relative', marginBottom: 14 }}>
        <div className="hide-scroll" style={{
          display: 'flex', gap: 12, overflowX: 'auto',
          padding: '14px 4px 18px',
        }}>
          {reports.map(r => (
            <ReportTab
              key={r.id}
              report={r}
              active={r.id === active?.id}
              onClick={() => setActiveScoutingReport(r.id)}
            />
          ))}
          <button
            onClick={createReport}
            className="cozy-btn"
            style={{
              flexShrink: 0, alignSelf: 'center',
              background: '#7CBF8E', color: 'white',
              border: 'none', borderRadius: 18,
              padding: '14px 22px', fontFamily: 'Fredoka One',
              fontSize: 15, cursor: 'pointer',
              boxShadow: '0 4px 0 #559e6a',
              display: 'inline-flex', alignItems: 'center', gap: 8,
              whiteSpace: 'nowrap',
            }}
          >
            New report 🌱
          </button>
        </div>
      </div>

      {/* Utility bar */}
      <div className="cozy-card" style={{
        padding: '10px 16px 10px 16px', marginBottom: 16,
        display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap',
      }}>
        <div className="corner-dot corner-dot-bl"></div>
        <div className="corner-dot corner-dot-br"></div>
        <div style={{ paddingLeft: 14, display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', flex: 1 }}>
          {renaming ? (
            <input
              autoFocus
              className="sr-input"
              style={{ borderRadius: 12, minWidth: 240 }}
              value={renameDraft}
              onChange={e => setRenameDraft(e.target.value)}
              onBlur={commitRename}
              onKeyDown={e => { if (e.key === 'Enter') commitRename(); if (e.key === 'Escape') setRenaming(false); }}
            />
          ) : (
            <div className="fredoka" style={{ color: 'var(--text-primary)', fontSize: 15, marginRight: 6 }}>
              {active.name}
            </div>
          )}
          <window.CozyButton color="terracotta" small onClick={openAllOpgg}>
            👁️ Open all in op.gg
          </window.CozyButton>
          <window.CozyButton color="lavender" small onClick={copyLink}>
            📋 Copy report link
          </window.CozyButton>
          <window.CozyButton color="cream" small onClick={startRename}>
            ✏️ Rename
          </window.CozyButton>
        </div>
        <button
          onClick={deleteReport}
          className="cozy-btn"
          style={{
            background: 'var(--surface-nested)', color: 'var(--text-muted)',
            border: '1.5px solid var(--border-default)', borderRadius: 12,
            padding: '4px 12px', fontFamily: 'Nunito', fontWeight: 800,
            fontSize: 12, cursor: 'pointer',
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}
          title="Delete report"
        >
          🗑️ Delete
        </button>
      </div>

      {/* Live Editors Indicator */}
      {activeEditors.length > 0 && (
        <div className="pop-in" style={{
          display: 'flex', alignItems: 'center', gap: 8,
          marginBottom: 16, paddingLeft: 14,
          fontFamily: 'Nunito', fontWeight: 800, fontSize: 13, color: 'var(--accent-orange)'
        }}>
          <div style={{ display: 'inline-flex' }}>
            {activeEditors.map((e, i) => (
              <div key={i} title={e.userName} style={{ marginLeft: i === 0 ? 0 : -8 }}>
                <window.HexFrame size={22} color={e.userColor || 'var(--accent-orange)'} borderColor="var(--border-emphasis)" borderWidth={1.5}>
                  <span style={{ fontFamily: 'Fredoka One', fontSize: 10, color: 'var(--text-on-light)' }}>
                    {e.userName ? e.userName[0].toUpperCase() : '?'}
                  </span>
                </window.HexFrame>
              </div>
            ))}
          </div>
          <span style={{ animation: 'float 2s ease-in-out infinite' }}>{editorsText}</span>
        </div>
      )}

      {/* Two-column layout */}
      <div className="sr-grid" style={{
        display: 'grid', gap: 16,
        gridTemplateColumns: 'minmax(0, 1.1fr) minmax(0, 1fr)',
      }}>
        <style>{`
          @media (max-width: 900px) {
            .sr-grid { grid-template-columns: 1fr !important; }
          }
        `}</style>

        {/* LEFT — Enemy roster */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <div className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 18, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
            <window.LaurelCrest size={20} color="var(--accent-orange)" />
            Enemy Roster — study them
          </div>
          {POSITIONS.map((pos, enemyIndex) => {
            const enemy = (active.enemies || []).find(e => e.position === pos) || {
              position: pos,
              riotId: '',
              region: 'NA',
              champPool: [],
              notes: ''
            };
            return (
              <EnemyLaneCard
                key={pos}
                pos={pos}
                lane={enemy}
                onChange={(updatedEnemy) => updateScoutingEnemy(active.id, enemyIndex, updatedEnemy)}
                champions={champions}
                reportId={active.id}
                enemyIndex={enemyIndex}
                activePopoverChip={activePopoverChip}
                setActivePopoverChip={setActivePopoverChip}
              />
            );
          })}
        </div>

        {/* RIGHT — Team strategy */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <div className="fredoka" style={{ color: 'var(--accent-orange)', fontSize: 18, display: 'inline-flex', alignItems: 'center', gap: 8 }}>
            <window.RuneGlyph variant={2} size={20} color="var(--accent-orange)" />
            Crew Strategy — game plan
          </div>
          <TargetBansCard
            bans={safeBans}
            onChange={(targetBans) => updateScoutingReport(active.id, { targetBans })}
            possibleBans={active.possibleBans || []}
            onPossibleBansChange={(possibleBans) => updateScoutingReport(active.id, { possibleBans })}
            champions={champions}
          />
          <GamePlanCard
            plan={active.gamePlan || ''}
            onChange={(gamePlan) => updateScoutingReport(active.id, { gamePlan })}
          />
          <PriorityFocusCard
            priorities={active.priorityFocus || []}
            onChange={(priorityFocus) => updateScoutingReport(active.id, { priorityFocus })}
          />

          {/* Decorative rune row */}
          <div style={{ display: 'flex', justifyContent: 'center', gap: 18, padding: '6px 0 4px', opacity: 0.55 }}>
            <window.RuneGlyph variant={0} size={16} color="var(--accent-orange)" />
            <window.RuneGlyph variant={3} size={16} color="var(--accent-orange)" />
            <window.RuneGlyph variant={1} size={16} color="var(--accent-orange)" />
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ScoutingReport });
