/**
 * WorldCup page — FIFA-premium redesign (2026-06).
 *
 * Dark luxury theme · gold accent system · glassmorphism · fully
 * responsive. Three layouts in one route:
 *   1. List view    — hero card + stat cards + pill tabs + premium
 *                     glass match cards (default).
 *   2. Standings     — Football-Data.org group tables (Groups tab).
 *   3. Bracket view  — desktop horizontal flex tree, tablet swipe,
 *                     phone accordion (auto-switch by breakpoint).
 *
 * Data: live via `useWorldCupFixtures` (PHP proxy → Football-Data.org)
 * with transparent fallback to demo data. Each match's broadcaster is
 * fuzzy-matched against the user's Xtream / M3U channels for a gold
 * "Watch on [Channel]" deep-link into /live-tv.
 *
 * Design tokens & component classes live in ./worldcup.css.
 */
import "./worldcup.css";
import { useEffect, useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { motion, AnimatePresence } from "framer-motion";
import {
  ArrowLeft,
  Trophy,
  Users,
  Calendar,
  CalendarDays,
  Building2,
  PlayCircle,
  Tv,
  ListChecks,
  ChevronDown,
} from "lucide-react";

import { useAuth } from "@/hooks/useAuth";
import { useProfiles } from "@/hooks/useProfiles";
import { useLiveChannels } from "@/hooks/useXtreamData";
import { TOURNAMENT, flagUrl, type Match } from "@/lib/worldCupData";
import { useWorldCupFixtures, type StandingGroup, type StandingRow } from "@/hooks/useWorldCupFixtures";
import { matchBroadcasterToChannel } from "@/lib/matchBroadcasterToChannel";
import { FocusableButton, FocusableSection } from "@/components/focusable";
import { isTizen, isWebOS } from "@/lib/platform";

type FilterKey = "all" | "live" | "today" | "tomorrow" | "groups" | "knockout";

const FILTERS: { key: FilterKey; label: string }[] = [
  { key: "all", label: "All Matches" },
  { key: "live", label: "Live Now" },
  { key: "today", label: "Today" },
  { key: "tomorrow", label: "Tomorrow" },
  { key: "groups", label: "Groups" },
  { key: "knockout", label: "Knockout" },
];

const isoYmd = (d: Date) => d.toISOString().slice(0, 10);
const fmtTime = (iso: string) =>
  new Date(iso).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", hour12: false });
const fmtDateHeader = (iso: string) =>
  new Date(iso).toLocaleDateString(undefined, { weekday: "long", month: "long", day: "numeric", year: "numeric" });
const todayYmd = () => isoYmd(new Date());
const tomorrowYmd = () => {
  const d = new Date();
  d.setDate(d.getDate() + 1);
  return isoYmd(d);
};

/** Decide the winning side of a finished knockout tie (score then pens). */
const winnerOf = (m: Match): "home" | "away" | null => {
  if (m.homeScore == null || m.awayScore == null) return null;
  if (m.homeScore > m.awayScore) return "home";
  if (m.awayScore > m.homeScore) return "away";
  if (m.homePenalty != null && m.awayPenalty != null) {
    if (m.homePenalty > m.awayPenalty) return "home";
    if (m.awayPenalty > m.homePenalty) return "away";
  }
  return null;
};

const WorldCup = () => {
  const navigate = useNavigate();
  const { user } = useAuth();
  const { activeProfile } = useProfiles();
  const { data: channels = [] } = useLiveChannels(activeProfile ?? null);
  const [filter, setFilter] = useState<FilterKey>("all");

  const { matches: fixtures, standings, source } = useWorldCupFixtures(60_000);

  // Samsung Tizen + LG webOS — feature withheld until store approval.
  useEffect(() => {
    if (isTizen() || isWebOS()) navigate("/", { replace: true });
  }, [navigate]);
  if (isTizen() || isWebOS()) return null;

  const liveCount = useMemo(() => fixtures.filter((m) => m.status === "LIVE").length, [fixtures]);

  const matches = useMemo<Match[]>(() => {
    switch (filter) {
      case "live":
        return fixtures.filter((m) => m.status === "LIVE");
      case "today":
        return fixtures.filter((m) => m.kickoffIso.startsWith(todayYmd()));
      case "tomorrow":
        return fixtures.filter((m) => m.kickoffIso.startsWith(tomorrowYmd()));
      case "groups":
        return fixtures.filter((m) => !!m.group);
      case "knockout":
        return [];
      default:
        return fixtures;
    }
  }, [filter, fixtures]);

  const matchesByDay = useMemo(() => {
    const out: Record<string, Match[]> = {};
    for (const m of matches) {
      const day = m.kickoffIso.slice(0, 10);
      (out[day] ||= []).push(m);
    }
    return Object.entries(out).sort(([a], [b]) => (a < b ? -1 : 1));
  }, [matches]);

  const goBack = () => {
    if (window.history.length > 1) navigate(-1);
    else navigate("/", { replace: true });
  };

  const findChannel = (broadcaster?: string) =>
    matchBroadcasterToChannel(broadcaster, channels as any);

  return (
    <motion.div
      data-testid="worldcup-page"
      initial={{ opacity: 0, y: 12 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.4, ease: "easeOut" }}
      className="wc-root relative h-[100dvh] overflow-y-auto overscroll-contain text-white"
      style={{ background: "var(--wc-bg-primary)" }}
    >
      {/* Nebula background + dark readability overlay */}
      <div
        className="fixed inset-0 bg-cover bg-center pointer-events-none"
        style={{ backgroundImage: "url('/images/nebula-bg.png')" }}
        aria-hidden
      />
      <div
        className="fixed inset-0 pointer-events-none"
        style={{ background: "linear-gradient(180deg, rgba(0,0,0,.35), rgba(0,0,0,.65))" }}
        aria-hidden
      />

      <div className="relative z-10 wc-page">
        {/* ── Top bar ─────────────────────────────────────────── */}
        <header className="flex items-center gap-3 mb-5">
          <FocusableButton
            focusKey="worldcup-back"
            onEnter={goBack}
            onClick={goBack}
            data-testid="worldcup-back-btn"
            aria-label="Back"
            subtle
            className="flex h-10 w-10 items-center justify-center rounded-full text-[var(--wc-gold)]"
            style={{ border: "1px solid var(--wc-border-gold)", background: "rgba(255,255,255,.03)" }}
          >
            <ArrowLeft className="h-4 w-4" strokeWidth={2.2} />
          </FocusableButton>
          <p className="text-[11px] uppercase tracking-[0.3em] text-[var(--wc-text-muted)] flex-1">
            FIFA World Cup
          </p>
          {user?.role === "user" && (
            <span
              className="hidden sm:inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-[11px] font-medium text-[var(--wc-gold)]"
              style={{ border: "1px solid var(--wc-border-gold)", background: "rgba(212,175,55,.08)" }}
              data-testid="worldcup-premium-chip"
            >
              <Trophy className="h-3 w-3" /> Premium
            </span>
          )}
        </header>

        {/* ── Hero card ───────────────────────────────────────── */}
        <section className="wc-hero mb-5" data-testid="worldcup-hero">
          <div className="flex flex-col md:flex-row items-center gap-6 text-center md:text-left">
            <div
              className="wc-trophy shrink-0 rounded-full flex items-center justify-center"
              style={{
                background: "radial-gradient(circle at 30% 28%, rgba(247,215,109,.28), rgba(212,175,55,.06))",
                border: "1px solid var(--wc-border-gold)",
                boxShadow: "0 0 50px rgba(212,175,55,.18)",
              }}
            >
              <Trophy className="h-1/2 w-1/2 text-[var(--wc-gold)]" strokeWidth={1.4} />
            </div>
            <div className="min-w-0 flex-1">
              <h1 className="wc-title" style={{ fontFamily: "Cinzel, serif" }} data-testid="worldcup-page-title">
                WORLD CUP 2026
              </h1>
              <div className="flex items-center gap-3 justify-center md:justify-start mt-2 flex-wrap">
                {liveCount > 0 ? (
                  <span className="inline-flex items-center gap-2 text-sm font-medium text-[var(--wc-text-secondary)]">
                    <span className="wc-live-dot wc-pulse" /> Live Now · {liveCount} {liveCount === 1 ? "match" : "matches"}
                  </span>
                ) : (
                  <span className="text-sm text-[var(--wc-text-muted)]">
                    {filter === "knockout" ? "Knockout Stage" : "Fixtures & Results"}
                  </span>
                )}
                <span
                  data-testid="worldcup-data-source"
                  className="wc-chip"
                  style={source === "live" ? undefined : { borderColor: "rgba(255,255,255,.14)", color: "var(--wc-text-muted)" }}
                >
                  {source === "live" ? "Live Data" : "Demo Data"}
                </span>
              </div>
              <p className="mt-3 text-sm text-[var(--wc-text-muted)]">
                {TOURNAMENT.name} · Jun 11 – Jul 19, 2026 · USA · Canada · Mexico
              </p>
            </div>
          </div>
        </section>

        {/* ── Stat cards ──────────────────────────────────────── */}
        <section className="grid grid-cols-2 md:grid-cols-4 gap-3 mb-5" data-testid="worldcup-info-strip">
          <StatCard icon={<Users className="h-4 w-4" />} value={`${TOURNAMENT.teamCount}`} label="Teams" />
          <StatCard icon={<Building2 className="h-4 w-4" />} value={`${TOURNAMENT.venueCount}`} label="Venues" />
          <StatCard icon={<ListChecks className="h-4 w-4" />} value={`${fixtures.length}`} label="Matches" />
          <StatCard icon={<CalendarDays className="h-4 w-4" />} value="Jul 19" label="The Final" />
        </section>

        {/* ── Pill tabs ───────────────────────────────────────── */}
        <FocusableSection
          focusKey="worldcup-filters"
          className="flex gap-2.5 overflow-x-auto pb-1 mb-6 no-scrollbar"
          data-testid="worldcup-filters"
        >
          {FILTERS.map((f) => {
            const active = filter === f.key;
            return (
              <FocusableButton
                key={f.key}
                focusKey={`worldcup-filter-${f.key}`}
                onEnter={() => setFilter(f.key)}
                onClick={() => setFilter(f.key)}
                data-testid={`worldcup-filter-${f.key}-btn`}
                subtle
                className={`wc-tab ${active ? "is-active" : ""}`}
              >
                {f.label}
                {f.key === "live" && <span className="wc-live-dot" />}
              </FocusableButton>
            );
          })}
        </FocusableSection>

        {/* ── Body ────────────────────────────────────────────── */}
        <main className="pb-24">
          {filter === "knockout" ? (
            <BracketView matches={fixtures} />
          ) : filter === "groups" && standings.length > 0 ? (
            <StandingsView groups={standings} />
          ) : matchesByDay.length === 0 ? (
            <EmptyState />
          ) : (
            matchesByDay.map(([day, list]) => (
              <section key={day} className="mb-7" data-testid={`worldcup-day-${day}`}>
                <h2 className="wc-section-head mb-3 flex items-baseline gap-2">
                  {day === todayYmd() ? "Today" : day === tomorrowYmd() ? "Tomorrow" : "Matchday"}
                  <span className="text-[var(--wc-text-muted)] font-normal text-sm">{fmtDateHeader(day)}</span>
                </h2>
                <div className="grid grid-cols-1 xl:grid-cols-2 gap-3">
                  {list.map((m) => (
                    <MatchCard
                      key={m.id}
                      match={m}
                      channel={findChannel(m.broadcaster)}
                      onPlay={(channelId) =>
                        navigate("/live-tv", { state: { autoPlayChannelId: channelId } })
                      }
                    />
                  ))}
                </div>
              </section>
            ))
          )}
        </main>
      </div>
    </motion.div>
  );
};

/* ── Stat card ─────────────────────────────────────────────────── */
const StatCard = ({ icon, value, label }: { icon: React.ReactNode; value: string; label: string }) => (
  <div className="wc-stat flex items-center gap-3">
    <span
      className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl text-[var(--wc-gold)]"
      style={{ background: "rgba(212,175,55,.1)", border: "1px solid var(--wc-border-gold)" }}
    >
      {icon}
    </span>
    <div className="min-w-0">
      <p className="text-[var(--wc-text-primary)] text-lg font-bold leading-tight truncate">{value}</p>
      <p className="text-[var(--wc-text-muted)] text-[11px] tracking-wide uppercase truncate">{label}</p>
    </div>
  </div>
);

/* ── Match card ────────────────────────────────────────────────── */
const MatchCard = ({
  match,
  channel,
  onPlay,
}: {
  match: Match;
  channel: { id: string | number; name: string } | null;
  onPlay: (channelId: string | number) => void;
}) => {
  const live = match.status === "LIVE";
  const ft = match.status === "FT";
  const upcoming = match.status === "UPCOMING";

  return (
    <div data-testid={`worldcup-match-${match.id}`} className={`wc-match ${live ? "is-live" : ""}`}>
      {/* Meta row */}
      <div className="flex items-center justify-between gap-2 mb-3 text-[11px] text-[var(--wc-text-muted)]">
        <span className="flex items-center gap-2 min-w-0">
          {match.group && <span className="wc-chip shrink-0">{match.group}</span>}
          <span className="truncate">{match.venue}</span>
        </span>
        {live ? (
          <span className="inline-flex items-center gap-1.5 shrink-0 text-[#ff6258] font-semibold">
            <span className="wc-live-dot wc-pulse" /> {match.liveLabel || "LIVE"}
          </span>
        ) : ft ? (
          <span className="shrink-0 font-bold tracking-wider text-[var(--wc-text-secondary)]">FT</span>
        ) : (
          <span className="shrink-0 text-[var(--wc-gold)] font-semibold">{fmtTime(match.kickoffIso)}</span>
        )}
      </div>

      {/* Teams + score */}
      <div className="grid grid-cols-[1fr_auto_1fr] items-center gap-3">
        <TeamSide team={match.home} />
        {upcoming ? (
          <div className="flex flex-col items-center">
            <span className="text-xl font-bold tracking-widest text-[var(--wc-gold-soft)]">VS</span>
            <span className="text-[11px] mt-1 text-[var(--wc-text-muted)]">{fmtTime(match.kickoffIso)}</span>
          </div>
        ) : (
          <span className="wc-score tabular-nums" data-testid={`worldcup-score-${match.id}`}>
            {match.homeScore}<span className="text-[var(--wc-text-muted)] mx-1">–</span>{match.awayScore}
          </span>
        )}
        <TeamSide team={match.away} />
      </div>

      {/* Broadcaster strip */}
      {match.broadcaster && (
        <div className="mt-3 pt-3 border-t border-white/5 flex items-center gap-1.5 text-[11px] text-[var(--wc-text-muted)]">
          <Tv className="h-3 w-3 text-[var(--wc-gold)]/70" />
          {match.broadcaster}
        </div>
      )}

      {/* Smart-channel CTA */}
      {channel && (
        <FocusableButton
          focusKey={`worldcup-play-${match.id}`}
          onEnter={() => onPlay(channel.id)}
          onClick={() => onPlay(channel.id)}
          data-testid={`worldcup-play-btn-${match.id}`}
          className="w-full mt-3 inline-flex items-center justify-center gap-2 rounded-xl text-xs font-semibold py-3 text-black transition"
          style={{ background: "linear-gradient(135deg, var(--wc-gold-light), var(--wc-gold))" }}
        >
          <PlayCircle className="h-4 w-4" />
          Watch on {channel.name}
        </FocusableButton>
      )}
    </div>
  );
};

const TeamSide = ({ team }: { team: { code: string; name: string } }) => (
  <div className="flex flex-col items-center gap-2 text-center min-w-0">
    <FlagImg code={team.code} />
    <span className="wc-team-name leading-tight truncate max-w-full">{team.name}</span>
  </div>
);

const FlagImg = ({ code, small = false }: { code: string; small?: boolean }) => (
  <img
    src={flagUrl(code, small ? 40 : 80)}
    alt=""
    aria-hidden
    className={small ? "h-5 w-7 rounded-sm object-cover shrink-0 border border-white/10" : "wc-flag shrink-0"}
    loading="lazy"
    style={{ pointerEvents: "none" }}
  />
);

const EmptyState = () => (
  <div className="text-center py-16 text-[var(--wc-text-muted)]" data-testid="worldcup-empty-state">
    <Calendar className="h-10 w-10 mx-auto mb-3 opacity-40" />
    <p className="text-sm">No matches in this view.</p>
  </div>
);

/* ── Standings (Groups tab) ────────────────────────────────────── */
const FormDots = ({ form }: { form?: string | null }) => {
  if (!form) return null;
  const items = form.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean).slice(-5);
  const color = (r: string) => (r === "W" ? "bg-emerald-500" : r === "L" ? "bg-red-500" : "bg-zinc-500");
  return (
    <div className="flex items-center gap-1 justify-end" data-testid="standings-form">
      {items.map((r, i) => (
        <span
          key={i}
          title={r}
          className={`inline-flex h-4 w-4 items-center justify-center rounded-full text-[8px] font-bold text-white ${color(r)}`}
        >
          {r}
        </span>
      ))}
    </div>
  );
};

const StandingsTable = ({ group }: { group: StandingGroup }) => (
  <section
    className="mb-5 rounded-2xl overflow-hidden"
    style={{ border: "1px solid var(--wc-border)", background: "rgba(12,18,28,.7)" }}
    data-testid={`standings-group-${group.group.replace(/\s+/g, "-").toLowerCase()}`}
  >
    <header
      className="px-4 py-3 flex items-center gap-2"
      style={{ background: "rgba(212,175,55,.1)", borderBottom: "1px solid var(--wc-border)" }}
    >
      <Trophy className="h-4 w-4 text-[var(--wc-gold)]" />
      <h3 className="text-sm font-bold tracking-[0.15em] text-white uppercase">{group.group}</h3>
    </header>
    <div className="overflow-x-auto">
      <table className="w-full text-xs">
        <thead>
          <tr className="text-[var(--wc-text-muted)] text-[10px] uppercase tracking-wider">
            <th className="text-left py-2 pl-3 pr-2 font-medium">#</th>
            <th className="text-left py-2 pr-2 font-medium">Team</th>
            {["P", "W", "D", "L", "GF", "GA", "GD", "PTS"].map((h) => (
              <th key={h} className="text-center py-2 px-1.5 font-medium w-7">{h}</th>
            ))}
            <th className="text-right py-2 pr-3 pl-2 font-medium hidden sm:table-cell">Form</th>
          </tr>
        </thead>
        <tbody>
          {group.table.map((r: StandingRow) => {
            const qualifies = r.position <= 2;
            return (
              <tr
                key={`${group.group}-${r.position}`}
                className="border-t border-white/5 hover:bg-white/5 transition-colors"
                data-testid={`standings-row-${r.code || r.position}`}
              >
                <td className="py-2.5 pl-3 pr-2">
                  <span
                    className={`inline-flex h-5 w-5 items-center justify-center rounded text-[10px] font-bold ${
                      qualifies ? "bg-emerald-500/20 text-emerald-400" : "text-[var(--wc-text-muted)]"
                    }`}
                  >
                    {r.position}
                  </span>
                </td>
                <td className="py-2.5 pr-2">
                  <div className="flex items-center gap-2">
                    {r.crest ? (
                      <img src={r.crest} alt="" className="h-4 w-5 object-contain" loading="lazy" />
                    ) : r.code ? (
                      <img src={flagUrl(r.code)} alt="" className="h-4 w-5 object-cover rounded-sm" loading="lazy" />
                    ) : null}
                    <span className="font-medium text-white truncate max-w-[120px]">{r.name}</span>
                  </div>
                </td>
                <td className="text-center px-1.5 text-[var(--wc-text-secondary)]">{r.played}</td>
                <td className="text-center px-1.5 text-[var(--wc-text-secondary)]">{r.won}</td>
                <td className="text-center px-1.5 text-[var(--wc-text-secondary)]">{r.draw}</td>
                <td className="text-center px-1.5 text-[var(--wc-text-secondary)]">{r.lost}</td>
                <td className="text-center px-1.5 text-[var(--wc-text-secondary)]">{r.gf}</td>
                <td className="text-center px-1.5 text-[var(--wc-text-secondary)]">{r.ga}</td>
                <td className="text-center px-1.5 text-[var(--wc-text-secondary)]">{r.gd > 0 ? `+${r.gd}` : r.gd}</td>
                <td className="text-center px-1.5 font-bold text-white">{r.points}</td>
                <td className="text-right pr-3 pl-2 hidden sm:table-cell"><FormDots form={r.form} /></td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  </section>
);

const StandingsView = ({ groups }: { groups: StandingGroup[] }) => (
  <div data-testid="worldcup-standings">
    <div className="flex items-center gap-3 mb-4 text-[11px] text-[var(--wc-text-muted)]">
      <span className="flex items-center gap-1">
        <span className="inline-block h-3 w-3 rounded bg-emerald-500/30" /> Qualifies (Top 2)
      </span>
      <span className="hidden sm:inline">·</span>
      <span className="hidden sm:flex items-center gap-1">
        Form (last 5):
        <span className="inline-flex h-3.5 w-3.5 items-center justify-center rounded-full bg-emerald-500 text-[7px] text-white font-bold">W</span>
        <span className="inline-flex h-3.5 w-3.5 items-center justify-center rounded-full bg-zinc-500 text-[7px] text-white font-bold">D</span>
        <span className="inline-flex h-3.5 w-3.5 items-center justify-center rounded-full bg-red-500 text-[7px] text-white font-bold">L</span>
      </span>
    </div>
    {groups.map((g) => (
      <StandingsTable key={g.group} group={g} />
    ))}
  </div>
);

/* ── Knockout bracket ──────────────────────────────────────────── */
const KO_ROUNDS = [
  { key: "Round of 32", label: "Round of 32" },
  { key: "Round of 16", label: "Round of 16" },
  { key: "Quarter-final", label: "Quarter Finals" },
  { key: "Semi-final", label: "Semi Finals" },
  { key: "Final", label: "Final" },
] as const;

const fmtKoDate = (ymd: string): string => {
  if (!ymd) return "";
  return new Date(`${ymd}T00:00:00Z`).toLocaleDateString(undefined, {
    month: "short",
    day: "2-digit",
    timeZone: "UTC",
  });
};
const roundDateRange = (list: Match[]): string => {
  const ds = list.map((m) => (m.kickoffIso || "").slice(0, 10)).filter(Boolean).sort();
  if (!ds.length) return "";
  return ds[0] === ds[ds.length - 1] ? fmtKoDate(ds[0]) : `${fmtKoDate(ds[0])} – ${fmtKoDate(ds[ds.length - 1])}`;
};

const BracketView = ({ matches }: { matches: Match[] }) => {
  const byRound = (key: string) =>
    matches
      .filter((m) => (m.round || "") === key)
      .sort(
        (a, b) =>
          (a.kickoffIso || "").localeCompare(b.kickoffIso || "") || a.id.localeCompare(b.id),
      );

  const thirdList = byRound("Match for third place");
  const rounds = KO_ROUNDS.map((r) => ({ ...r, list: byRound(r.key) }));
  const hasKnockout = rounds.some((r) => r.list.length > 0);

  if (!hasKnockout) {
    return (
      <div className="text-center py-16 text-[var(--wc-text-muted)]" data-testid="worldcup-bracket-empty">
        <Trophy className="h-10 w-10 mx-auto mb-3 opacity-40" />
        <p className="text-sm">Knockout bracket appears once the fixtures are published.</p>
      </div>
    );
  }

  return (
    <div data-testid="worldcup-bracket">
      {/* Desktop — horizontal flex scroll (≥ lg) */}
      <div className="hidden lg:block overflow-x-auto pb-4 no-scrollbar">
        <div className="flex gap-10 items-stretch w-max" style={{ minHeight: 520 }}>
          {rounds.map((r) => (
            <div key={r.key} className="flex flex-col" style={{ width: 240 }}>
              <BracketColHead label={r.label} list={r.list} />
              <div className="flex-1 flex flex-col justify-around gap-4">
                {r.list.map((m) => (
                  <BracketMatchCard key={m.id} match={m} isFinal={r.key === "Final"} />
                ))}
              </div>
            </div>
          ))}
          {thirdList.length > 0 && (
            <div className="flex flex-col" style={{ width: 240 }}>
              <BracketColHead label="Third Place" list={thirdList} />
              <div className="flex-1 flex flex-col justify-around gap-4">
                {thirdList.map((m) => (
                  <BracketMatchCard key={m.id} match={m} isFinal={false} />
                ))}
              </div>
            </div>
          )}
        </div>
      </div>

      {/* Tablet — horizontal swipe (md → lg) */}
      <div className="hidden md:block lg:hidden">
        <div className="wc-bracket-swipe no-scrollbar">
          {rounds.concat(thirdList.length ? [{ key: "third", label: "Third Place", list: thirdList } as any] : []).map((r) => (
            <div key={r.key} className="shrink-0" style={{ width: 260 }}>
              <BracketColHead label={r.label} list={r.list} />
              <div className="flex flex-col gap-3">
                {r.list.map((m: Match) => (
                  <BracketMatchCard key={m.id} match={m} isFinal={r.key === "Final"} />
                ))}
              </div>
            </div>
          ))}
        </div>
        <p className="text-center text-[10px] text-[var(--wc-text-muted)] mt-2 tracking-wide">Swipe to explore rounds →</p>
      </div>

      {/* Phone — accordion */}
      <div className="md:hidden">
        <BracketAccordion rounds={rounds} thirdList={thirdList} />
      </div>
    </div>
  );
};

const BracketColHead = ({ label, list }: { label: string; list: Match[] }) => (
  <header className="text-center mb-3">
    <p className="wc-bracket-col-head">{label}</p>
    <p className="text-[var(--wc-text-muted)] text-[11px]">{roundDateRange(list)}</p>
  </header>
);

const BracketAccordion = ({
  rounds,
  thirdList,
}: {
  rounds: { key: string; label: string; list: Match[] }[];
  thirdList: Match[];
}) => {
  const items = rounds
    .filter((r) => r.list.length > 0)
    .concat(thirdList.length ? [{ key: "third", label: "Third Place", list: thirdList }] : []);
  // Default-open the Final if present, else the first populated round.
  const firstOpen = items.find((r) => r.key === "Final")?.key ?? items[0]?.key ?? "";
  const [open, setOpen] = useState<string>(firstOpen);

  return (
    <div className="space-y-2.5">
      {items.map((r) => {
        const isOpen = open === r.key;
        return (
          <div key={r.key} className="wc-acc-item" data-testid={`worldcup-bracket-acc-${r.key}`}>
            <button
              type="button"
              className="wc-acc-head"
              onClick={() => setOpen(isOpen ? "" : r.key)}
              aria-expanded={isOpen}
            >
              <span className="flex items-center gap-2">
                {r.key === "Final" && <Trophy className="h-4 w-4 text-[var(--wc-gold)]" />}
                <span>{r.label}</span>
                <span className="text-[11px] font-normal text-[var(--wc-text-muted)]">{roundDateRange(r.list)}</span>
              </span>
              <ChevronDown
                className={`h-4 w-4 text-[var(--wc-text-muted)] transition-transform ${isOpen ? "rotate-180" : ""}`}
              />
            </button>
            <AnimatePresence initial={false}>
              {isOpen && (
                <motion.div
                  initial={{ height: 0, opacity: 0 }}
                  animate={{ height: "auto", opacity: 1 }}
                  exit={{ height: 0, opacity: 0 }}
                  transition={{ duration: 0.25 }}
                  className="overflow-hidden"
                >
                  <div className="p-3 pt-0 space-y-3">
                    {r.list.map((m) => (
                      <BracketMatchCard key={m.id} match={m} isFinal={r.key === "Final"} fullWidth />
                    ))}
                  </div>
                </motion.div>
              )}
            </AnimatePresence>
          </div>
        );
      })}
    </div>
  );
};

const BracketMatchCard = ({
  match,
  isFinal,
  fullWidth,
}: {
  match: Match;
  isFinal: boolean;
  fullWidth?: boolean;
}) => {
  const win = winnerOf(match);
  return (
    <div
      className={`wc-bracket-match ${isFinal ? "is-final" : ""}`}
      style={fullWidth ? { width: "100%" } : undefined}
    >
      {isFinal && (
        <p className="text-[var(--wc-gold)] text-[10px] font-bold tracking-[0.25em] text-center mb-2">FINAL</p>
      )}
      <BracketTeamRow team={match.home} score={match.homeScore} pen={match.homePenalty} winner={win === "home"} />
      <div className="h-px bg-white/10 my-1.5" />
      <BracketTeamRow team={match.away} score={match.awayScore} pen={match.awayPenalty} winner={win === "away"} />
    </div>
  );
};

const BracketTeamRow = ({
  team,
  score,
  pen,
  winner,
}: {
  team: { code: string; name: string };
  score: number | null;
  pen?: number;
  winner?: boolean;
}) => (
  <div className={`flex items-center gap-2 ${winner ? "" : "opacity-60"}`}>
    <FlagImg code={team.code} small />
    <span className={`flex-1 truncate text-sm ${winner ? "font-semibold text-white" : "text-[var(--wc-text-secondary)]"}`}>
      {team.name}
    </span>
    <span className={`tabular-nums text-sm font-bold ${winner ? "text-[var(--wc-gold)]" : "text-[var(--wc-text-secondary)]"}`}>
      {score ?? "-"}
      {pen != null && <span className="text-[var(--wc-text-muted)] text-xs ml-1">({pen})</span>}
    </span>
  </div>
);

export default WorldCup;
