// Bracket, stats, live scoreboard, settings views.

// ============================================================
// Bracket
// ============================================================

const BRACKET_STAGES = [
  { id: 'm16', label: 'Dieciseisavos',    matchCount: 16 },
  { id: 'r16', label: 'Octavos de Final', matchCount: 8  },
  { id: 'qf',  label: 'Cuartos de Final', matchCount: 4  },
  { id: 'sf',  label: 'Semifinales',      matchCount: 2  },
  { id: 'f',   label: 'Final',            matchCount: 1  },
];

function BracketTeamSlot({ teams, teamId, onSelect, onClear, size = 18 }) {
  const team = teams.find((tm) => tm.id === teamId);
  if (team) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', gap: 4, flex: 1, minWidth: 0 }}>
        <TeamBadge team={team} size={size}/>
        <span style={{ flex: 1, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{team.name}</span>
        <button
          onClick={onClear}
          style={{ background: 'none', border: 'none', color: 'var(--muted)', cursor: 'pointer', fontSize: 14, lineHeight: 1, padding: '0 2px', flexShrink: 0 }}
          title="Quitar equipo"
        >×</button>
      </div>
    );
  }
  return (
    <select
      value=""
      onChange={(e) => e.target.value && onSelect(e.target.value)}
      style={{ flex: 1, fontSize: 11, background: 'var(--surface-3)', border: '1px solid var(--border)', color: 'var(--muted)', borderRadius: 4, padding: '2px 4px', cursor: 'pointer' }}
    >
      <option value="">— Equipo —</option>
      {teams.map((tm) => (
        <option key={tm.id} value={tm.id}>{tm.name}</option>
      ))}
    </select>
  );
}

function BracketView({ state, dispatch, t }) {
  const [seedError, setSeedError] = React.useState("");
  const [addingRound, setAddingRound] = React.useState(false);
  const [selectedStage, setSelectedStage] = React.useState('f');

  function seedFromGroups() {
    const seeds = getGroupSeeds(0);
    if (seeds.length < 2) { setSeedError("Necesitas al menos 2 clasificados."); return; }
    setSeedError("");

    let target = 2;
    while (target * 2 <= seeds.length) target *= 2;
    const used = seeds.slice(0, target);

    // Standard seeding: 1 vs N, 2 vs N-1, ...
    const pairs = [];
    for (let i = 0; i < target / 2; i++) {
      pairs.push([used[i].teamId, used[target - 1 - i]?.teamId || null]);
    }

    const numRounds = Math.log2(target);
    const rounds = [];
    rounds.push({
      label: stageLabelFor(target, t),
      matches: pairs.map(([a, b]) => ({
        id: uid(), homeId: a, awayId: b,
        homeScore: null, awayScore: null, played: false,
      })),
    });
    let prev = rounds[0].matches.length;
    for (let r = 1; r < numRounds; r++) {
      const count = prev / 2;
      rounds.push({
        label: stageLabelFor(count * 2, t),
        matches: Array.from({ length: count }, () => ({
          id: uid(), homeId: null, awayId: null, homeScore: null, awayScore: null, played: false,
        })),
      });
      prev = count;
    }
    dispatch({ type: "SET_BRACKET", bracket: { rounds } });
  }

  function getGroupSeeds(needed) {
    const qualifyPer = state.meta.qualifyPerGroup || 2;
    const byPosition = {};

    state.groups.forEach((g) => {
      const teams = state.teams.filter((tm) => tm.groupId === g.id);
      const matches = state.matches.filter((m) => m.groupId === g.id);
      const rows = computeStandings(teams, matches, state.meta);
      // Take up to qualifyPer, but expand if the bracket needs more
      const take = needed
        ? Math.max(qualifyPer, Math.ceil(needed / Math.max(state.groups.length, 1)))
        : qualifyPer;
      rows.slice(0, Math.min(take, rows.length)).forEach((r, idx) => {
        const pos = idx + 1;
        if (!byPosition[pos]) byPosition[pos] = [];
        byPosition[pos].push({ teamId: r.team.id, group: g.name, pos, pts: r.pts, gd: r.gd, gf: r.gf });
      });
    });

    // Within each position group, sort by pts → gd → gf
    const seeds = [];
    Object.keys(byPosition).sort((a, b) => +a - +b).forEach((pos) => {
      byPosition[pos]
        .sort((a, b) => b.pts - a.pts || b.gd - a.gd || b.gf - a.gf)
        .forEach((s) => seeds.push(s));
    });

    // If still not enough (no groups yet), fall back to all teams ranked by wins/pts
    if (needed && seeds.length < needed) {
      const inGroup = new Set(seeds.map((s) => s.teamId));
      state.teams
        .filter((tm) => !inGroup.has(tm.id))
        .forEach((tm) => seeds.push({ teamId: tm.id, group: '', pos: 99, pts: 0, gd: 0, gf: 0 }));
    }

    return seeds;
  }

  function addRoundManually() {
    const stage = BRACKET_STAGES.find((s) => s.id === selectedStage) || BRACKET_STAGES[4];
    const needed = stage.matchCount * 2;
    const seeds = getGroupSeeds(needed);
    const used = seeds.slice(0, needed);

    // Standard elimination seeding: seed1 vs seedN, seed2 vs seed(N-1), ...
    // e.g. 8 teams → 1v8, 2v7, 3v6, 4v5
    const pairs = [];
    for (let i = 0; i < stage.matchCount; i++) {
      pairs.push([
        used[i]?.teamId || null,
        used[needed - 1 - i]?.teamId || null,
      ]);
    }

    // Build rounds with shared IDs — same ID used in bracket AND calendar
    const firstRound = {
      label: stage.label,
      matches: pairs.map(([a, b]) => ({
        id: uid(), homeId: a, awayId: b, homeScore: null, awayScore: null, played: false,
      })),
    };
    const stageIdx = BRACKET_STAGES.findIndex((s) => s.id === selectedStage);
    const followingRounds = BRACKET_STAGES.slice(stageIdx + 1).map((s) => ({
      label: s.label,
      matches: Array.from({ length: s.matchCount }, () => ({
        id: uid(), homeId: null, awayId: null, homeScore: null, awayScore: null, played: false,
      })),
    }));
    const allNewRounds = [firstRound, ...followingRounds];

    // Calendar entries use the SAME id as the bracket match
    const calendarMatches = allNewRounds.flatMap((r) =>
      r.matches.map((m) => ({
        id: m.id,           // ← same ID as bracket match
        stage: r.label,
        round: r.label,
        groupId: null,
        homeId: m.homeId,
        awayId: m.awayId,
        homeScore: null,
        awayScore: null,
        played: false,
        scorers: [],
        date: "",
        time: "",
        venueId: null,
        court: "",
      }))
    );

    dispatch({ type: "SET_BRACKET", bracket: { rounds: [...state.bracket.rounds, ...allNewRounds] } });
    dispatch({ type: "SET_MATCHES", matches: [...state.matches, ...calendarMatches] });
    setAddingRound(false);
  }

  function removeRound(ri) {
    const rounds = state.bracket.rounds.filter((_, i) => i !== ri);
    dispatch({ type: "SET_BRACKET", bracket: { rounds } });
  }

  function addMatchToRound(ri) {
    const newRounds = state.bracket.rounds.map((r, i) =>
      i === ri
        ? { ...r, matches: [...r.matches, { id: uid(), homeId: null, awayId: null, homeScore: null, awayScore: null, played: false }] }
        : r
    );
    dispatch({ type: "SET_BRACKET", bracket: { rounds: newRounds } });
  }

  function removeMatch(ri, mi) {
    const newRounds = state.bracket.rounds.map((r, i) =>
      i === ri ? { ...r, matches: r.matches.filter((_, j) => j !== mi) } : r
    );
    dispatch({ type: "SET_BRACKET", bracket: { rounds: newRounds } });
  }

  function getBracketWinner(m) {
    if (!m.homeId || !m.awayId) return null;
    if (m.homeScore === null || m.homeScore === undefined || m.homeScore === "") return null;
    if (m.awayScore === null || m.awayScore === undefined || m.awayScore === "") return null;
    const hs = +m.homeScore, as = +m.awayScore;
    if (isNaN(hs) || isNaN(as)) return null;
    if (hs > as) return m.homeId;
    if (as > hs) return m.awayId;
    return m.penaltyWinnerId || null;
  }

  // Helper: find a match in state.matches by its bracket match id
  function calendarMatchExists(id) {
    return state.matches.some((m) => m.id === id);
  }

  function updateBracketMatch(roundIdx, matchIdx, patch) {
    const rounds = JSON.parse(JSON.stringify(state.bracket.rounds));
    const m = rounds[roundIdx].matches[matchIdx];
    const matchId = m.id;
    Object.assign(m, patch);
    dispatch({ type: "SET_BRACKET", bracket: { rounds } });
    // Sync to calendar if shared ID exists
    if (calendarMatchExists(matchId)) {
      dispatch({ type: "UPDATE_MATCH", id: matchId, patch });
    }
  }

  function advanceWinner(roundIdx, matchIdx, winnerId) {
    const rounds = JSON.parse(JSON.stringify(state.bracket.rounds));
    const m = rounds[roundIdx].matches[matchIdx];

    // Mark penalty winner if draw
    if (m.homeScore !== null && m.awayScore !== null && +m.homeScore === +m.awayScore) {
      m.penaltyWinnerId = winnerId;
      if (calendarMatchExists(m.id)) {
        dispatch({ type: "UPDATE_MATCH", id: m.id, patch: { penaltyWinnerId: winnerId } });
      }
    }

    // Place winner in next round bracket + calendar
    const nextRi = roundIdx + 1;
    if (nextRi < rounds.length) {
      const nextMi = Math.floor(matchIdx / 2);
      const slot = matchIdx % 2 === 0 ? "homeId" : "awayId";
      const nextM = rounds[nextRi].matches[nextMi];
      if (nextM) {
        nextM[slot] = winnerId;
        // Sync to calendar
        if (calendarMatchExists(nextM.id)) {
          dispatch({ type: "UPDATE_MATCH", id: nextM.id, patch: { [slot]: winnerId } });
        }
      }
    }

    dispatch({ type: "SET_BRACKET", bracket: { rounds } });
  }

  // Detect champion from bracket Final
  const bracketChampion = React.useMemo(() => {
    const finalRound = state.bracket.rounds.find(r => r.label === 'Final') || (state.bracket.rounds.length ? state.bracket.rounds[state.bracket.rounds.length - 1] : null);
    if (!finalRound?.matches.length) return null;
    const m = finalRound.matches[0];
    const wId = getBracketWinner(m);
    return wId ? state.teams.find(tm => tm.id === wId) || null : null;
  }, [state.bracket.rounds, state.teams]);

  return (
    <div data-screen-label="06 Bracket">
      {bracketChampion && (
        <div style={{
          background: 'linear-gradient(135deg, #7a4f00 0%, #c98b00 25%, #ffd700 50%, #c98b00 75%, #7a4f00 100%)',
          borderRadius: 'var(--r)', padding: '22px 30px', marginBottom: 24,
          display: 'flex', alignItems: 'center', gap: 24,
          boxShadow: '0 0 50px rgba(255,200,0,0.25), 0 4px 20px rgba(0,0,0,0.5)',
        }}>
          <div style={{ fontSize: 52, lineHeight: 1, filter: 'drop-shadow(0 4px 8px rgba(0,0,0,0.5))' }}>🏆</div>
          <div>
            <div style={{ fontSize: 10, fontWeight: 800, letterSpacing: '.28em', textTransform: 'uppercase', color: 'rgba(0,0,0,0.55)', marginBottom: 6 }}>Campeón del Torneo</div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
              <ShieldSvg shieldId={bracketChampion.shield || 'classic'} color={bracketChampion.color || '#3A86FF'} size={52} text={bracketChampion.short || abbrev(bracketChampion.name)}/>
              <span style={{ fontFamily: 'var(--display)', fontSize: 32, letterSpacing: '.04em', color: '#1a0e00' }}>{bracketChampion.name.toUpperCase()}</span>
            </div>
          </div>
        </div>
      )}

      <div className="page-head">
        <div>
          <h1 className="page-title">{t("bracket_title")}</h1>
          <div className="page-sub">{t("bracket_sub")}</div>
        </div>
        <div className="page-actions">
          {seedError && <span className="tag hot">{seedError}</span>}
          <ConfirmBtn
            label={t("clear_bracket")}
            confirmLabel="Limpiar"
            className="btn"
            disabled={state.bracket.rounds.length === 0}
            onConfirm={() => {
              dispatch({ type: "SET_BRACKET", bracket: { rounds: [] } });
              dispatch({ type: "SET_MATCHES", matches: state.matches.filter(m => m.stage === "groups") });
            }}
          />
          <button className="btn" onClick={() => setAddingRound((v) => !v)}>
            + Agregar fase
          </button>
          <ConfirmBtn
            label={"🌱 " + t("seed_bracket")}
            confirmLabel="Confirmar"
            className="btn btn-primary"
            onConfirm={seedFromGroups}
          />
        </div>
      </div>

      {addingRound && (
        <div className="card" style={{ marginBottom: 16, display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap', padding: '14px 16px' }}>
          <span style={{ fontFamily: 'var(--ui-cond)', fontSize: 11, fontWeight: 800, letterSpacing: '.15em', textTransform: 'uppercase', color: 'var(--muted)' }}>Nueva fase:</span>
          {BRACKET_STAGES.map((s) => (
            <button key={s.id} onClick={() => setSelectedStage(s.id)}
              className={"btn btn-sm" + (selectedStage === s.id ? " btn-primary" : "")}>
              {s.label}
              <span style={{ marginLeft: 5, fontSize: 10, opacity: 0.65, fontFamily: 'var(--ui-cond)' }}>{s.matchCount}p</span>
            </button>
          ))}
          <div style={{ flex: 1 }}/>
          <button className="btn btn-ghost btn-sm" onClick={() => setAddingRound(false)}>Cancelar</button>
          <button className="btn btn-primary btn-sm" onClick={addRoundManually}>Crear bracket</button>
        </div>
      )}

      {state.bracket.rounds.length === 0 ? (
        <div className="empty" style={{ paddingTop: 60 }}>
          <div style={{ fontSize: 48, marginBottom: 16 }}>🏆</div>
          <h3 style={{ marginBottom: 8 }}>Sin bracket todavía</h3>
          <p className="muted" style={{ maxWidth: 360, margin: '0 auto 20px' }}>
            Genera el bracket automáticamente desde la tabla de grupos, o crea fases manualmente.
          </p>
          <div style={{ display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap' }}>
            <button className="btn btn-primary" onClick={() => setAddingRound(true)}>+ Agregar fase</button>
            <ConfirmBtn label={"🌱 " + t("seed_bracket")} confirmLabel="Confirmar" className="btn" onConfirm={seedFromGroups}/>
          </div>
        </div>
      ) : (
        <div className="bracket scroll-x" style={{ gap: 24, padding: '16px 4px 24px' }}>
          {state.bracket.rounds.map((round, ri) => {
            const isFinalRound = round.label === 'Final' || ri === state.bracket.rounds.length - 1;
            const played = round.matches.filter(m => m.played).length;
            const total = round.matches.length;
            const isComplete = played === total && total > 0;
            return (
              <div key={ri} className="bracket-round" style={{ minWidth: 230 }}>
                <div className={"bracket-round-label" + (isFinalRound && bracketChampion ? " has-champion" : "")}
                  style={{ display:'flex', flexDirection:'column', gap:4 }}>
                  <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
                    <span style={{ display:'flex', alignItems:'center', gap:6 }}>
                      {isFinalRound && <span style={{ fontSize:12 }}>🏆</span>}
                      {round.label}
                    </span>
                    <div style={{ display:'flex', gap:4, alignItems:'center' }}>
                      <span style={{ fontSize:10, color: isComplete ? 'var(--green)' : 'var(--muted)', fontFamily:'var(--ui-cond)', letterSpacing:'.04em' }}>
                        {played}/{total}
                      </span>
                      <button onClick={() => addMatchToRound(ri)} title="Agregar partido"
                        style={{ background:'none', border:'1px solid var(--border)', color:'var(--muted)', borderRadius:4, cursor:'pointer', fontSize:11, padding:'1px 6px', lineHeight:1.6 }}>+</button>
                      <button onClick={() => removeRound(ri)} title="Eliminar fase"
                        style={{ background:'none', border:'1px solid var(--border)', color:'var(--muted)', borderRadius:4, cursor:'pointer', fontSize:11, padding:'1px 6px', lineHeight:1.6 }}>×</button>
                    </div>
                  </div>
                  {total > 0 && (
                    <div className="phase-bar">
                      <div className={"phase-bar-fill" + (isComplete ? " bar-done" : isFinalRound ? " bar-final" : " bar-ko")}
                        style={{ width: Math.round(played / total * 100) + "%" }}/>
                    </div>
                  )}
                </div>
                {round.matches.map((m, mi) => (
                  <BracketMatchCard key={m.id}
                    m={m}
                    teams={state.teams}
                    getBracketWinner={getBracketWinner}
                    isFinal={isFinalRound && round.matches.length === 1}
                    onUpdate={(patch) => updateBracketMatch(ri, mi, patch)}
                    onAdvance={(winnerId) => advanceWinner(ri, mi, winnerId)}
                    onRemove={() => removeMatch(ri, mi)}
                  />
                ))}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

function BracketMatchCard({ m, teams, getBracketWinner, onUpdate, onAdvance, onRemove, isFinal }) {
  const [hs, setHs] = React.useState(m.homeScore != null ? String(m.homeScore) : "");
  const [as, setAs] = React.useState(m.awayScore != null ? String(m.awayScore) : "");
  const [editing, setEditing] = React.useState(false);

  React.useEffect(() => {
    if (!editing) {
      setHs(m.homeScore != null ? String(m.homeScore) : "");
      setAs(m.awayScore != null ? String(m.awayScore) : "");
    }
  }, [m.homeScore, m.awayScore, editing]);

  const home = teams.find(tm => tm.id === m.homeId);
  const away = teams.find(tm => tm.id === m.awayId);
  const winnerId = getBracketWinner(m);
  const homeWin = m.played && winnerId === m.homeId;
  const awayWin = m.played && winnerId === m.awayId;
  const isDraw = m.played && m.homeScore != null && m.awayScore != null && +m.homeScore === +m.awayScore;

  const hsNum = hs !== "" ? +hs : null;
  const asNum = as !== "" ? +as : null;
  const bothEntered = hsNum !== null && asNum !== null && !isNaN(hsNum) && !isNaN(asNum);
  const localWinner = bothEntered ? (hsNum > asNum ? m.homeId : asNum > hsNum ? m.awayId : null) : null;
  const showConfirm = bothEntered && m.homeId && m.awayId && (!m.played || editing);
  const locked = m.played && !editing;

  const scoreStyle = {
    width: 34, textAlign: 'center', fontFamily: 'var(--display)', fontSize: 18,
    outline: 'none', padding: '2px 3px',
    background: locked ? 'transparent' : 'var(--surface-4)',
    border: locked ? 'none' : '1px solid var(--border-2)',
    borderRadius: 4, color: 'inherit',
  };

  function confirm() {
    if (!bothEntered) return;
    onUpdate({ homeScore: hsNum, awayScore: asNum, played: true, penaltyWinnerId: null });
    if (localWinner) onAdvance(localWinner);
    setEditing(false);
  }

  const cardClass = "bracket-match" + (isFinal ? " is-final" : "");

  return (
    <div className={cardClass} style={{ position:'relative' }}>
      <button onClick={onRemove} title="Quitar"
        style={{ position:'absolute', top:3, right:3, background:'none', border:'none', color:'var(--faint)', cursor:'pointer', fontSize:12, lineHeight:1, padding:'1px 3px', zIndex:2, borderRadius:2, transition:'color .1s' }}
        onMouseEnter={e => e.target.style.color = 'var(--hot)'}
        onMouseLeave={e => e.target.style.color = 'var(--faint)'}
      >×</button>

      {/* Home row */}
      <div className={"bracket-team " + (homeWin ? "win" : awayWin ? "lost" : "")}
        style={homeWin && home ? { borderLeftColor: home.color || 'var(--green)' } : {}}>
        <div className="bracket-team-name" style={{ flex:1, minWidth:0 }}>
          {locked ? (
            <div style={{ display:'flex', alignItems:'center', gap:5, flex:1, minWidth:0 }}>
              <TeamBadge team={home || { shield:'classic', color:'var(--muted)', short:'?' }} size={18}/>
              <span style={{ flex:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', fontSize:12.5 }}>
                {home?.name || <span style={{ color:'var(--muted)', fontStyle:'italic' }}>Por definir</span>}
              </span>
              {homeWin && <span style={{ color:'var(--green)', fontSize:10, fontWeight:800, flexShrink:0 }}>✓</span>}
            </div>
          ) : (
            <BracketTeamSlot teams={teams} teamId={m.homeId}
              onSelect={(id) => onUpdate({ homeId: id })}
              onClear={() => { onUpdate({ homeId: null, homeScore: null, played: false, penaltyWinnerId: null }); setHs(""); }}/>
          )}
        </div>
        <input value={locked ? (m.homeScore ?? "") : hs} readOnly={locked} type="number" min="0"
          onChange={(e) => setHs(e.target.value)}
          style={{ ...scoreStyle, color: homeWin ? 'var(--green)' : awayWin ? 'var(--faint)' : 'var(--text)' }}/>
      </div>

      {/* Away row */}
      <div className={"bracket-team " + (awayWin ? "win" : homeWin ? "lost" : "")}
        style={awayWin && away ? { borderLeftColor: away.color || 'var(--green)' } : {}}>
        <div className="bracket-team-name" style={{ flex:1, minWidth:0 }}>
          {locked ? (
            <div style={{ display:'flex', alignItems:'center', gap:5, flex:1, minWidth:0 }}>
              <TeamBadge team={away || { shield:'classic', color:'var(--muted)', short:'?' }} size={18}/>
              <span style={{ flex:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', fontSize:12.5 }}>
                {away?.name || <span style={{ color:'var(--muted)', fontStyle:'italic' }}>Por definir</span>}
              </span>
              {awayWin && <span style={{ color:'var(--green)', fontSize:10, fontWeight:800, flexShrink:0 }}>✓</span>}
            </div>
          ) : (
            <BracketTeamSlot teams={teams} teamId={m.awayId}
              onSelect={(id) => onUpdate({ awayId: id })}
              onClear={() => { onUpdate({ awayId: null, awayScore: null, played: false, penaltyWinnerId: null }); setAs(""); }}/>
          )}
        </div>
        <input value={locked ? (m.awayScore ?? "") : as} readOnly={locked} type="number" min="0"
          onChange={(e) => setAs(e.target.value)}
          style={{ ...scoreStyle, color: awayWin ? 'var(--green)' : homeWin ? 'var(--faint)' : 'var(--text)' }}/>
      </div>

      {/* Champion row for Final */}
      {isFinal && winnerId && (() => { const w = teams.find(t => t.id === winnerId); return w ? (
        <div className="bracket-champion-row">
          <span className="champ-label">Campeón</span>
          <TeamBadge team={w} size={18}/>
          <span className="champ-name">{w.name}</span>
        </div>
      ) : null; })()}

      {/* Actions bar */}
      {(!locked || isDraw) && (
        <div style={{ padding:'4px 8px 5px', borderTop:'1px solid var(--border)', display:'flex', alignItems:'center', gap:5 }}>
          {showConfirm && !isDraw && (
            <button className="btn btn-sm btn-primary" style={{ flex:1, fontSize:11 }} onClick={confirm}>
              ✓ {localWinner ? "Confirmar →" : "Empate"}
            </button>
          )}
          {isDraw && !winnerId && home && away && <>
            <span style={{ fontSize:10, color:'var(--amber)', fontWeight:800, letterSpacing:'.06em', textTransform:'uppercase', flexShrink:0 }}>⚡ Pen</span>
            <button className={"btn btn-sm" + (m.penaltyWinnerId === home.id ? " btn-primary" : "")} style={{ flex:1, fontSize:11 }} onClick={() => onAdvance(home.id)}>
              {home.short || home.name}
            </button>
            <button className={"btn btn-sm" + (m.penaltyWinnerId === away.id ? " btn-primary" : "")} style={{ flex:1, fontSize:11 }} onClick={() => onAdvance(away.id)}>
              {away.short || away.name}
            </button>
          </>}
          {editing && <button className="btn btn-sm btn-ghost" style={{ fontSize:11 }} onClick={() => setEditing(false)}>✕</button>}
        </div>
      )}

      {/* Correction bar */}
      {m.played && (
        <div style={{ padding:'2px 8px 3px', display:'flex', justifyContent:'space-between', alignItems:'center' }}>
          {winnerId && !editing && (
            <button className="btn btn-sm btn-ghost" style={{ fontSize:10, padding:'2px 6px' }} onClick={() => onAdvance(winnerId)}>
              → Pasar ganador
            </button>
          )}
          <button
            onClick={editing ? confirm : () => { setHs(m.homeScore != null ? String(m.homeScore) : ""); setAs(m.awayScore != null ? String(m.awayScore) : ""); setEditing(true); }}
            style={{ background:'none', border:'none', color: editing ? 'var(--accent)' : 'var(--muted)', fontSize:10, cursor:'pointer', padding:'2px 4px', marginLeft:'auto' }}
          >{editing ? '✓ Guardar' : '✎ Corregir'}</button>
        </div>
      )}
    </div>
  );
}

function stageLabelFor(numTeams, t) {
  if (numTeams === 2) return t("stage_final");
  if (numTeams === 4) return t("stage_sf");
  if (numTeams === 8) return t("stage_qf");
  if (numTeams === 16) return t("stage_r16");
  return numTeams + "vos";
}

// ============================================================
// Stats
// ============================================================
function StatsView({ state, dispatch, t }) {
  // Aggregate scorers across group + bracket matches
  const allMatches = [
    ...state.matches,
    ...state.bracket.rounds.flatMap((r) => r.matches.map((m) => ({ ...m, scorers: m.scorers || [] }))),
  ];
  const scorerMap = {};
  allMatches.forEach((m) => {
    (m.scorers || []).forEach((s) => {
      const key = s.playerId || s.teamId + ":" + (s.name || "?");
      scorerMap[key] = scorerMap[key] || { count: 0, playerId: s.playerId, teamId: s.teamId, name: s.name };
      scorerMap[key].count++;
    });
  });
  const scorers = Object.values(scorerMap)
    .map((s) => {
      let player = null, team = state.teams.find((tm) => tm.id === s.teamId);
      if (s.playerId) {
        state.teams.forEach((tm) => tm.players.forEach((p) => {
          if (p.id === s.playerId) { player = p; team = tm; }
        }));
      }
      return { ...s, player, team };
    })
    .sort((a, b) => b.count - a.count);

  const teamRows = computeStandings(state.teams, state.matches, state.meta);

  return (
    <div data-screen-label="07 Stats">
      <div className="page-head">
        <div>
          <h1 className="page-title">{t("stats_title")}</h1>
          <div className="page-sub">{t("stats_sub")}</div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
        <div className="card">
          <div className="card-h">
            <h3 className="card-title">⚽ {t("scorers")}</h3>
            <span className="muted mono" style={{ fontSize: 11 }}>{scorers.length}</span>
          </div>
          {scorers.length === 0 ? (
            <div className="muted" style={{ fontSize: 12 }}>—</div>
          ) : (
            <table className="table">
              <thead>
                <tr><th>#</th><th>{t("player_name")}</th><th>{t("team")}</th><th className="num">{t("goals")}</th></tr>
              </thead>
              <tbody>
                {scorers.slice(0, 15).map((s, i) => (
                  <tr key={i}>
                    <td className="pos">{i + 1}</td>
                    <td>{s.player?.name || s.name || "—"}</td>
                    <td>{s.team ? <TeamPickerInline team={s.team} /> : "—"}</td>
                    <td className="num"><b style={{ fontFamily: "var(--display)", fontSize: 16 }}>{s.count}</b></td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>

        <div className="card">
          <div className="card-h">
            <h3 className="card-title">📊 Equipos</h3>
          </div>
          <table className="table">
            <thead>
              <tr><th>#</th><th>{t("team")}</th><th className="num">{t("pj")}</th><th className="num">{t("gf")}</th><th className="num">{t("gc")}</th><th className="num">{t("pts")}</th></tr>
            </thead>
            <tbody>
              {teamRows.map((r, i) => (
                <tr key={r.team.id}>
                  <td className="pos">{i + 1}</td>
                  <td><TeamPickerInline team={r.team} /></td>
                  <td className="num">{r.pj}</td>
                  <td className="num">{r.gf}</td>
                  <td className="num">{r.gc}</td>
                  <td className="num"><b>{r.pts}</b></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// Live scoreboard
// ============================================================
function LiveView({ state, dispatch, t }) {
  // Build combined match list: groups + bracket rounds
  const allMatchOptions = React.useMemo(() => {
    const opts = [];
    if (state.matches.length > 0) {
      opts.push({ type: 'group-header', label: '── Fase de Grupos ──' });
      state.matches.forEach((m) => {
        const h = state.teams.find((tm) => tm.id === m.homeId);
        const a = state.teams.find((tm) => tm.id === m.awayId);
        opts.push({ type: 'match', source: 'group', id: m.id, label: (h?.name || '?') + ' vs ' + (a?.name || '?') });
      });
    }
    state.bracket.rounds.forEach((r, ri) => {
      const validMatches = r.matches.filter((m) => m.homeId || m.awayId);
      if (validMatches.length === 0) return;
      opts.push({ type: 'group-header', label: '── ' + r.label + ' ──' });
      validMatches.forEach((m, mi) => {
        const h = state.teams.find((tm) => tm.id === m.homeId);
        const a = state.teams.find((tm) => tm.id === m.awayId);
        opts.push({ type: 'match', source: 'bracket', id: m.id, roundIdx: ri, matchIdx: r.matches.indexOf(m), label: (h?.name || '?') + ' vs ' + (a?.name || '?') });
      });
    });
    return opts;
  }, [state.matches, state.bracket.rounds, state.teams]);

  const firstMatch = allMatchOptions.find((o) => o.type === 'match');
  const [matchId, setMatchId] = React.useState(firstMatch?.id || "");
  const [running, setRunning] = React.useState(false);
  const [seconds, setSeconds] = React.useState(0);
  const [period, setPeriod] = React.useState("half_1");

  React.useEffect(() => {
    if (!running) return;
    const id = setInterval(() => setSeconds((s) => s + 1), 1000);
    return () => clearInterval(id);
  }, [running]);

  // Find match from either source
  const matchOpt = allMatchOptions.find((o) => o.type === 'match' && o.id === matchId);
  const match = matchOpt?.source === 'bracket'
    ? state.bracket.rounds[matchOpt.roundIdx]?.matches[matchOpt.matchIdx]
    : state.matches.find((m) => m.id === matchId);
  const home = match && state.teams.find((tm) => tm.id === match.homeId);
  const away = match && state.teams.find((tm) => tm.id === match.awayId);

  const mm = String(Math.floor(seconds / 60)).padStart(2, "0");
  const ss = String(seconds % 60).padStart(2, "0");

  function updateMatch(patch) {
    if (!match || !matchOpt) return;
    if (matchOpt.source === 'bracket') {
      const newRounds = state.bracket.rounds.map((r, i) =>
        i === matchOpt.roundIdx
          ? { ...r, matches: r.matches.map((m, j) => j === matchOpt.matchIdx ? { ...m, ...patch } : m) }
          : r
      );
      dispatch({ type: "SET_BRACKET", bracket: { rounds: newRounds } });
    } else {
      dispatch({ type: "UPDATE_MATCH", id: match.id, patch });
    }
  }

  function addScorer(scorer) {
    if (!match || !matchOpt) return;
    if (matchOpt.source === 'bracket') {
      const newRounds = state.bracket.rounds.map((r, i) =>
        i === matchOpt.roundIdx
          ? { ...r, matches: r.matches.map((m, j) =>
              j === matchOpt.matchIdx ? { ...m, scorers: [...(m.scorers || []), scorer] } : m
            )}
          : r
      );
      dispatch({ type: "SET_BRACKET", bracket: { rounds: newRounds } });
    } else {
      dispatch({ type: "ADD_SCORER", matchId: match.id, scorer });
    }
  }

  function bump(side, delta) {
    if (!match) return;
    const key = side === "home" ? "homeScore" : "awayScore";
    const curr = match[key] === null ? 0 : +match[key];
    updateMatch({ [key]: Math.max(0, curr + delta), played: true });
  }

  function logScorer(side) {
    if (!match) return;
    const team = side === "home" ? home : away;
    if (!team) return;
    const playerName = prompt(t("player_name") + " (" + team.name + ")", "");
    if (!playerName) { bump(side, 1); return; }
    const player = team.players.find((p) => p.name.toLowerCase() === playerName.toLowerCase());
    addScorer({ teamId: team.id, playerId: player?.id, name: playerName, minute: Math.floor(seconds / 60) });
    bump(side, 1);
  }

  // Stage badge for bracket matches
  const stageBadge = matchOpt?.source === 'bracket'
    ? state.bracket.rounds[matchOpt.roundIdx]?.label
    : null;

  return (
    <div data-screen-label="08 Live">
      <div className="page-head">
        <div>
          <h1 className="page-title">{t("live_title")}</h1>
          <div className="page-sub">{t("live_sub")}</div>
        </div>
        <div className="page-actions">
          <select className="select" value={matchId} onChange={(e) => { setMatchId(e.target.value); setSeconds(0); setRunning(false); }} style={{ minWidth: 260 }}>
            <option value="">— {t("select_match")} —</option>
            {allMatchOptions.map((o, i) =>
              o.type === 'group-header'
                ? <option key={i} disabled style={{ color: 'var(--muted)', fontStyle: 'italic' }}>{o.label}</option>
                : <option key={o.id} value={o.id}>{o.label}</option>
            )}
          </select>
        </div>
      </div>

      {!match ? (
        <div className="empty"><h3>{t("select_match")}</h3></div>
      ) : (
        <div className="scoreboard">
          <div className="row gap-8 center" style={{ marginBottom: 16, justifyContent: "space-between" }}>
            <div className="row gap-8 center">
              <span className="live-dot">LIVE</span>
              {stageBadge && <span className="tag accent">{stageBadge}</span>}
            </div>
            <div className="row gap-8">
              <select className="select" value={period} onChange={(e) => setPeriod(e.target.value)} style={{ width: 140 }}>
                <option value="half_1">{t("half_1")}</option>
                <option value="half_time">{t("half_time")}</option>
                <option value="half_2">{t("half_2")}</option>
                <option value="full_time">{t("full_time")}</option>
              </select>
            </div>
          </div>
          <div className="scoreboard-grid">
            <div className="score-team">
              {home && <div className="score-team-badge" style={{ background: home.color }}>{home.short || abbrev(home.name)}</div>}
              <div className="score-team-name">{home?.name || "—"}</div>
              <div className="score-num">{match.homeScore ?? 0}</div>
              <div className="score-controls">
                <button className="score-btn minus" onClick={() => bump("home", -1)}>−</button>
                <button className="score-btn plus" onClick={() => logScorer("home")}>+ ⚽</button>
              </div>
            </div>
            <div className="score-center">
              <div className="score-period">{t(period)}</div>
              <div className="score-clock">{mm}:{ss}</div>
              <div className="row gap-8">
                <button className="btn" onClick={() => setRunning((r) => !r)}>
                  {running ? "⏸ " + t("pause") : "▶ " + t("start")}
                </button>
                <button className="btn btn-ghost" onClick={() => setSeconds(0)}>↺</button>
              </div>
            </div>
            <div className="score-team">
              {away && <div className="score-team-badge" style={{ background: away.color }}>{away.short || abbrev(away.name)}</div>}
              <div className="score-team-name">{away?.name || "—"}</div>
              <div className="score-num">{match.awayScore ?? 0}</div>
              <div className="score-controls">
                <button className="score-btn minus" onClick={() => bump("away", -1)}>−</button>
                <button className="score-btn plus" onClick={() => logScorer("away")}>+ ⚽</button>
              </div>
            </div>
          </div>
          {(match.scorers || []).length > 0 && (
            <div style={{ marginTop: 24, paddingTop: 18, borderTop: "1px solid var(--border)" }}>
              <div style={{ fontSize: 11, letterSpacing: ".15em", color: "var(--muted)", fontWeight: 700, textTransform: "uppercase", marginBottom: 10 }}>
                {t("scorers")}
              </div>
              <div className="row gap-8" style={{ flexWrap: "wrap" }}>
                {match.scorers.map((s, i) => {
                  const tm = state.teams.find((tt) => tt.id === s.teamId);
                  return (
                    <span key={i} className="tag" style={{ background: tm?.color || "var(--surface-2)", color: "white" }}>
                      ⚽ {s.minute}' {s.name || "—"}
                    </span>
                  );
                })}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ============================================================
// Settings
// ============================================================
function SettingsView({ state, dispatch, t, lang, setLang, theme, setTheme }) {
  const fileRef = React.useRef(null);

  function handleExport() {
    const data = JSON.stringify(state, null, 2);
    const blob = new Blob([data], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = (state.meta.name || "torneo") + "-" + new Date().toISOString().slice(0, 10) + ".json";
    a.click();
    URL.revokeObjectURL(url);
  }
  function handleImport(e) {
    const file = e.target.files[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (ev) => {
      try {
        const parsed = JSON.parse(ev.target.result);
        if (!parsed.teams || !parsed.meta) throw new Error("invalid");
        dispatch({ type: "REPLACE", state: parsed });
      } catch (err) {
        alert("Archivo no válido");
      }
    };
    reader.readAsText(file);
  }

  return (
    <div data-screen-label="09 Settings">
      <div className="page-head">
        <div>
          <h1 className="page-title">{t("settings_title")}</h1>
          <div className="page-sub">{t("settings_sub")}</div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
        <div className="card">
          <div className="card-h">
            <h3 className="card-title">{t("section_tournament")}</h3>
          </div>
          <div style={{ display: "grid", gap: 12 }}>
            <div className="field">
              <label>{t("tournament_name")}</label>
              <input className="input" value={state.meta.name}
                onChange={(e) => dispatch({ type: "SET_META", patch: { name: e.target.value } })} />
            </div>
            <div className="row gap-12">
              <div className="field flex-1">
                <label>{t("sport")}</label>
                <select className="select" value={state.meta.sport}
                  onChange={(e) => dispatch({ type: "SET_META", patch: { sport: e.target.value } })}>
                  <option value="futbol">{t("sport_futbol")}</option>
                  <option value="basket">{t("sport_basket")}</option>
                  <option value="volley">{t("sport_volley")}</option>
                  <option value="generic">{t("sport_generic")}</option>
                </select>
              </div>
              <div className="field flex-1">
                <label>{t("format")}</label>
                <select className="select" value={state.meta.format}
                  onChange={(e) => dispatch({ type: "SET_META", patch: { format: e.target.value } })}>
                  <option value="groups_knockout">{t("format_groups_knockout")}</option>
                  <option value="knockout">{t("format_knockout")}</option>
                  <option value="roundrobin">{t("format_roundrobin")}</option>
                  <option value="league">{t("format_league")}</option>
                </select>
              </div>
            </div>
            <div className="row gap-12">
              <div className="field flex-1">
                <label>{t("points_win")}</label>
                <input className="input" type="number" value={state.meta.pointsWin}
                  onChange={(e) => dispatch({ type: "SET_META", patch: { pointsWin: +e.target.value } })} />
              </div>
              <div className="field flex-1">
                <label>{t("points_draw")}</label>
                <input className="input" type="number" value={state.meta.pointsDraw}
                  onChange={(e) => dispatch({ type: "SET_META", patch: { pointsDraw: +e.target.value } })} />
              </div>
              <div className="field flex-1">
                <label>{t("points_loss")}</label>
                <input className="input" type="number" value={state.meta.pointsLoss}
                  onChange={(e) => dispatch({ type: "SET_META", patch: { pointsLoss: +e.target.value } })} />
              </div>
            </div>
          </div>
        </div>

        <div className="card">
          <div className="card-h">
            <h3 className="card-title">{t("venues")}</h3>
            <button className="btn btn-icon" onClick={() => dispatch({ type: "ADD_VENUE" })}>+</button>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
            {state.venues.map((v) => (
              <div key={v.id} className="row gap-8">
                <input className="input" value={v.name}
                  onChange={(e) => dispatch({ type: "UPDATE_VENUE", id: v.id, patch: { name: e.target.value } })} />
                <button className="btn btn-ghost btn-icon" onClick={() => dispatch({ type: "DELETE_VENUE", id: v.id })}>×</button>
              </div>
            ))}
          </div>
        </div>

        <div className="card" style={{ gridColumn: "span 2" }}>
          <div className="card-h">
            <h3 className="card-title">{t("data_title")}</h3>
            <span className="muted" style={{ fontSize: 11 }}>{t("last_saved")}: {new Date(state.lastSavedAt).toLocaleTimeString()}</span>
          </div>
          <p className="muted" style={{ fontSize: 12, marginTop: 0 }}>{t("data_sub")}</p>
          <div className="row gap-8">
            <button className="btn btn-primary" onClick={handleExport}>⬇ {t("export")}</button>
            <button className="btn" onClick={() => fileRef.current.click()}>⬆ {t("import")}</button>
            <input ref={fileRef} type="file" accept="application/json" style={{ display: "none" }} onChange={handleImport} />
            <div className="flex-1"></div>
          <ConfirmBtn
            label={t("reset_all")}
            confirmLabel={t("yes")}
            className="btn btn-danger"
            onConfirm={() => dispatch({ type: "RESET" })}
          />
          </div>
        </div>
      </div>
    </div>
  );
}

window.BracketView = BracketView;
window.StatsView = StatsView;
window.LiveView = LiveView;
window.SettingsView = SettingsView;
