"use client";

import Link from "next/link";
import { useMemo, useState } from "react";
import { format, formatDistanceToNowStrict } from "date-fns";
import { fr } from "date-fns/locale";
import { BadgePercent, ChevronDown, ChevronRight, ChevronUp } from "lucide-react";
import { OddsButton } from "@/components/odds-button";
import { SportGlyph } from "@/components/sport-glyph";
import { formatMoney, formatOdds } from "@/lib/utils";

export type SportsLobbySport = {
  id: string;
  slug: string;
  name: string;
};

export type SportsLobbyEvent = {
  id: string;
  homeName: string;
  awayName: string;
  startsAt: string;
  isLive: boolean;
  minute: number | null;
  scoreHome: number | null;
  scoreAway: number | null;
  sport: { slug: string; name: string };
  competition: { country: string; name: string };
  markets: Array<{
    id: string;
    key: string;
    name: string;
    selections: Array<{
      id: string;
      key: string;
      name: string;
      odds: string;
      oddsVersion: number;
    }>;
  }>;
};

export type SportsLobbyBoostedOdd = {
  id: string;
  title: string;
  category: {
    id: string;
    name: string;
    sortOrder: number;
  };
  teamA: string;
  teamB: string;
  startsAt: string;
  betLabel: string;
  originalOdds: string;
  boostedOdds: string;
  maxStake: string;
  allowCombinations: boolean;
  terms: string;
  sortOrder: number;
  event: {
    id: string;
    sport: { slug: string; name: string };
    competition: { country: string; name: string };
  };
  market: {
    id: string;
    name: string;
  };
  selection: {
    id: string;
    oddsVersion: number;
  };
};

export type SportsLobbyPromotion = {
  id: string;
  title: string;
  subtitle: string | null;
  badge: string | null;
  imageUrl: string;
  href: string;
};

type LobbyMode = "home" | "upcoming";

export function SportsLobby({
  events,
  boostedOdds = [],
  promotions = [],
  sports,
  unavailable = false,
  showPromos = true,
  initialMode = "home",
  initialSportSlug = null
}: {
  events: SportsLobbyEvent[];
  boostedOdds?: SportsLobbyBoostedOdd[];
  promotions?: SportsLobbyPromotion[];
  sports: SportsLobbySport[];
  unavailable?: boolean;
  showPromos?: boolean;
  initialMode?: LobbyMode;
  initialSportSlug?: string | null;
}) {
  const [mode, setMode] = useState<LobbyMode>(initialMode);
  const [selectedSport, setSelectedSport] = useState<string | null>(initialSportSlug);
  const scopedEvents = useMemo(() => (selectedSport ? events.filter((event) => event.sport.slug === selectedSport) : events), [events, selectedSport]);
  const scopedBoostedOdds = useMemo(
    () => (selectedSport ? boostedOdds.filter((boostedOdd) => boostedOdd.event.sport.slug === selectedSport) : boostedOdds),
    [boostedOdds, selectedSport]
  );
  const primaryEvents = scopedEvents;
  const groups = useMemo(() => groupEventsByCompetition(primaryEvents), [primaryEvents]);
  const sportSections = useMemo(() => groupCompetitionGroupsBySport(groups), [groups]);

  function focusBoostedOdds() {
    setMode("home");
    setSelectedSport(null);
    requestAnimationFrame(() => document.getElementById("cote-boostee")?.scrollIntoView({ behavior: "smooth", block: "start" }));
  }

  return (
    <div className="space-y-3.5 sm:space-y-5">
      {showPromos ? <SportsPromotionRail promotions={promotions} /> : null}
      <HomeTabs mode={mode} onChange={setMode} />
      <SportScroller sports={sports} selectedSport={selectedSport} onSelect={setSelectedSport} onBoostSelect={focusBoostedOdds} />
      <BoostedOddsSection boosts={scopedBoostedOdds} />

      <section className="grid gap-4">
        <div className="space-y-3">
          {unavailable ? <ProviderUnavailable /> : null}
          {sportSections.length ? (
            <div className="space-y-3">
              {sportSections.map((section) => (
                <SportCompetitionSection key={section.sportSlug} section={section} />
              ))}
            </div>
          ) : (
            <EmptyState text="Aucun match à venir disponible pour ce filtre." />
          )}
        </div>
      </section>
    </div>
  );
}

function SportsPromotionRail({ promotions }: { promotions: SportsLobbyPromotion[] }) {
  if (!promotions.length) return null;

  return (
    <section className="-mx-5 overflow-x-auto px-5 [scrollbar-width:none] sm:mx-0 sm:px-0 [&::-webkit-scrollbar]:hidden" aria-label="Promotions sport">
      <div className="flex gap-3">
        {promotions.map((promotion) => (
          <Link
            key={promotion.id}
            href={promotion.href}
            className="group relative h-[128px] w-[82vw] max-w-[430px] shrink-0 overflow-hidden rounded-lg border border-white/10 bg-[#10161f] shadow-panel sm:h-[150px] sm:w-[390px]"
          >
            <div
              className="absolute inset-0 bg-cover bg-center transition duration-300 group-hover:scale-[1.03]"
              style={{ backgroundImage: `url(${promotion.imageUrl})` }}
            />
            <div className="absolute inset-0 bg-[linear-gradient(90deg,rgba(4,8,14,.94)_0%,rgba(4,8,14,.74)_42%,rgba(4,8,14,.22)_100%)]" />
            <div className="relative flex h-full max-w-[72%] flex-col justify-end p-3.5 sm:p-4">
              {promotion.badge ? (
                <span className="mb-2 w-fit rounded-md border border-felt/35 bg-felt/15 px-2 py-1 text-[10px] font-black uppercase text-felt">
                  {promotion.badge}
                </span>
              ) : null}
              <h2 className="line-clamp-2 text-lg font-black leading-tight text-white sm:text-xl">{promotion.title}</h2>
              {promotion.subtitle ? <p className="mt-1 line-clamp-2 text-xs font-semibold leading-5 text-slate-300">{promotion.subtitle}</p> : null}
            </div>
          </Link>
        ))}
      </div>
    </section>
  );
}

function HomeTabs({ mode, onChange }: { mode: LobbyMode; onChange: (mode: LobbyMode) => void }) {
  const items: Array<{ key: LobbyMode; label: string }> = [
    { key: "home", label: "Accueil" },
    { key: "upcoming", label: "À venir" }
  ];

  return (
    <nav className="border-b border-white/10" aria-label="Accueil sportsbook">
      <div className="flex items-center justify-between gap-3">
        {items.map((item) => (
          <button
            key={item.key}
            type="button"
            onClick={() => onChange(item.key)}
            className={mode === item.key ? "relative flex h-10 flex-1 items-center justify-center gap-2 text-sm font-extrabold text-felt" : "flex h-10 flex-1 items-center justify-center gap-2 text-sm font-semibold text-white"}
          >
            {item.label}
            {mode === item.key ? <span className="absolute inset-x-0 -bottom-px h-0.5 rounded-full bg-felt" /> : null}
          </button>
        ))}
      </div>
    </nav>
  );
}

function SportScroller({
  sports,
  selectedSport,
  onSelect,
  onBoostSelect
}: {
  sports: SportsLobbySport[];
  selectedSport: string | null;
  onSelect: (slug: string | null) => void;
  onBoostSelect: () => void;
}) {
  const items = [
    { id: "popular", slug: "popular", name: "Populaire", special: null },
    { id: "boosted", slug: "boosted", name: "Cote boostée", special: "boosted" },
    ...[...sports].sort((left, right) => sportRank(left.slug) - sportRank(right.slug) || left.name.localeCompare(right.name)).map((sport) => ({ ...sport, special: null }))
  ];

  return (
    <section className="-mx-5 overflow-x-auto px-5 [scrollbar-width:none] sm:mx-0 sm:px-0 [&::-webkit-scrollbar]:hidden" aria-label="Sports">
      <div className="flex gap-3">
        {items.map((sport) => {
          const isActive = sport.slug === "popular" ? selectedSport === null : selectedSport === sport.slug;
          const handleClick = sport.special === "boosted" ? onBoostSelect : () => onSelect(sport.slug === "popular" ? null : sport.slug);
          return (
            <button key={sport.slug} type="button" onClick={handleClick} className="w-[72px] shrink-0 sm:w-[78px]">
              <span
                className={
                  isActive && sport.special !== "boosted"
                    ? "mx-auto grid h-[54px] w-[58px] place-items-center rounded-lg border border-felt bg-felt/10 text-felt shadow-[0_0_18px_rgba(15,191,143,.12)] sm:h-[62px] sm:w-[68px]"
                    : "mx-auto grid h-[54px] w-[58px] place-items-center rounded-lg border border-white/10 bg-white/[0.055] text-slate-200 sm:h-[62px] sm:w-[68px]"
                }
              >
                <SportGlyph slug={sport.slug} label={sport.name} className="h-6 w-6 sm:h-7 sm:w-7" />
              </span>
              <span className={isActive && sport.special !== "boosted" ? "mt-1.5 block truncate text-center text-[11px] font-extrabold text-felt" : "mt-1.5 block truncate text-center text-[11px] font-semibold text-slate-400"}>
                {sport.slug === "basketball" ? "Basket" : sport.name}
              </span>
            </button>
          );
        })}
      </div>
    </section>
  );
}

function BoostedOddsSection({ boosts }: { boosts: SportsLobbyBoostedOdd[] }) {
  const groups = useMemo(() => groupBoostedOdds(boosts), [boosts]);

  return (
    <section id="cote-boostee" className="space-y-2.5 scroll-mt-24">
      <div className="flex w-fit items-center gap-2 px-0.5 text-white">
        <BadgePercent className="h-6 w-6 text-felt" />
        <h2 className="text-base font-extrabold">Cote boostée</h2>
        <ChevronRight className="h-4 w-4 text-slate-400" />
      </div>

      {groups.length ? (
        <div className="space-y-2.5">
          {groups.map((group) => (
            <BoostedOddCategoryCard key={group.id} group={group} />
          ))}
        </div>
      ) : (
        <article className="overflow-hidden rounded-lg border border-white/10 bg-[#151a22] shadow-panel">
          <div className="bg-[#202631] px-3 py-4 text-center text-xs font-semibold text-slate-400">Aucune cote boostée active pour ce filtre.</div>
        </article>
      )}
    </section>
  );
}

function BoostedOddCategoryCard({ group }: { group: BoostedOddGroup }) {
  const [collapsed, setCollapsed] = useState(false);

  return (
    <article className="overflow-hidden rounded-lg border border-white/10 bg-[#151a22] shadow-panel">
      <div className="flex min-h-12 items-center justify-between gap-3 border-b border-white/10 px-3 py-2.5">
        <div className="flex min-w-0 items-center gap-2">
          <BadgePercent className="h-5 w-5 shrink-0 text-felt" />
          <span className="truncate text-[13px] font-semibold text-felt">{group.name}</span>
        </div>
        <button
          type="button"
          onClick={() => setCollapsed((value) => !value)}
          className="grid h-8 w-8 shrink-0 place-items-center rounded-full text-slate-300 hover:bg-white/[0.06] hover:text-white"
          aria-label={collapsed ? "Déplier la catégorie" : "Replier la catégorie"}
        >
          {collapsed ? <ChevronDown className="h-4 w-4" /> : <ChevronUp className="h-4 w-4" />}
        </button>
      </div>

      {!collapsed ? (
        <div className="divide-y divide-[#151922]">
          {group.boosts.map((boost) => (
            <BoostedOddRow key={boost.id} boost={boost} />
          ))}
        </div>
      ) : null}
    </article>
  );
}

type BoostedOddGroup = {
  id: string;
  name: string;
  sortOrder: number;
  boosts: SportsLobbyBoostedOdd[];
};

function groupBoostedOdds(boosts: SportsLobbyBoostedOdd[]): BoostedOddGroup[] {
  const groups = new Map<string, BoostedOddGroup>();

  for (const boost of boosts) {
    const current = groups.get(boost.category.id);
    if (current) {
      current.boosts.push(boost);
    } else {
      groups.set(boost.category.id, {
        id: boost.category.id,
        name: boost.category.name,
        sortOrder: boost.category.sortOrder,
        boosts: [boost]
      });
    }
  }

  return Array.from(groups.values())
    .map((group) => ({
      ...group,
      boosts: [...group.boosts].sort((left, right) => left.sortOrder - right.sortOrder || new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime())
    }))
    .sort((left, right) => left.sortOrder - right.sortOrder || left.name.localeCompare(right.name));
}

type CompetitionGroup = {
  id: string;
  sportSlug: string;
  sportName: string;
  competitionName: string;
  country: string;
  events: SportsLobbyEvent[];
};

type SportCompetitionGroup = {
  sportSlug: string;
  sportName: string;
  groups: CompetitionGroup[];
};

function SportCompetitionSection({ section }: { section: SportCompetitionGroup }) {
  return (
    <section className="min-w-0 space-y-2.5">
      <div className="flex w-fit items-center gap-2 px-0.5 text-white">
        <SportGlyph slug={section.sportSlug} label={section.sportName} className="h-6 w-6" />
        <h2 className="text-base font-extrabold">{section.sportName}</h2>
        <ChevronRight className="h-4 w-4 text-slate-400" />
      </div>

      <div className="grid min-w-0 gap-2.5">
        {section.groups.map((group) => (
          <CompetitionGroupSection key={group.id} group={group} />
        ))}
      </div>
    </section>
  );
}

function CompetitionGroupSection({ group }: { group: CompetitionGroup }) {
  const [collapsed, setCollapsed] = useState(false);
  const title = `${group.sportName} / ${group.competitionName}`;

  return (
    <section className="min-w-0 max-w-full overflow-hidden rounded-lg border border-white/10 bg-[#151a22] shadow-panel">
      <button
        type="button"
        onClick={() => setCollapsed((value) => !value)}
        className="flex min-h-12 w-full items-center justify-between gap-3 border-b border-white/10 px-3 py-2.5 text-left"
        aria-expanded={!collapsed}
      >
        <span className="flex min-w-0 items-center gap-2">
          <SportGlyph slug={group.sportSlug} label={group.sportName} className="h-5 w-5 shrink-0" />
          <span className="min-w-0">
            <span className="block truncate text-[13px] font-semibold text-white">{title}</span>
            {group.country ? <span className="mt-0.5 block truncate text-[10px] font-semibold uppercase tracking-[0.08em] text-slate-500">{group.country}</span> : null}
          </span>
        </span>
        <span className="flex shrink-0 items-center gap-2">
          <span className="rounded-md border border-felt/20 bg-felt/10 px-2 py-1 text-[10px] font-black text-felt">{group.events.length}</span>
          {collapsed ? <ChevronDown className="h-4 w-4 text-slate-400" /> : <ChevronUp className="h-4 w-4 text-slate-400" />}
        </span>
      </button>

      {!collapsed ? (
        <div className="min-w-0 space-y-2 p-2 sm:space-y-2.5 sm:p-2.5">
          {group.events.map((event) => (
            <ClientEventCard key={event.id} event={event} showCompetitionHeader={false} />
          ))}
        </div>
      ) : null}
    </section>
  );
}

function BoostedOddRow({ boost }: { boost: SportsLobbyBoostedOdd }) {
  const eventName = `${boost.teamA} vs ${boost.teamB}`;

  return (
    <div className="bg-[#202631]">
      <div className="bg-[#171c25] px-3 py-1.5 text-center text-[10px] font-normal leading-4 text-slate-400">
        <div className="truncate">
          Boostée de {formatOdds(boost.originalOdds)} · Mise max {formatMoney(Number(boost.maxStake))} · {boost.terms}
        </div>
      </div>

      <div className="px-3 py-3">
        <div className="mb-2 min-w-0 text-[12px] font-semibold text-felt">{formatEventClock(boost.startsAt)}</div>

        <div className="grid gap-1.5">
          <div className="flex min-w-0 items-center gap-2">
            <TeamMark sport={boost.event.sport} />
            <span className="truncate text-[13px] font-bold text-white">{boost.teamA}</span>
          </div>
          <div className="flex min-w-0 items-center gap-2">
            <TeamMark sport={boost.event.sport} />
            <span className="truncate text-[13px] font-bold text-white">{boost.teamB}</span>
          </div>
        </div>

        <div className="mt-3">
          <OddsButton
            compact
            selection={{
              selectionId: boost.selection.id,
              eventId: boost.event.id,
              marketId: boost.market.id,
              eventName,
              marketName: boost.market.name,
              selectionName: boost.betLabel,
              odds: boost.boostedOdds,
              oddsVersion: boost.selection.oddsVersion,
              boosted: true,
              originalOdds: boost.originalOdds,
              maxStake: boost.maxStake,
              allowCombinations: boost.allowCombinations,
              terms: boost.terms
            }}
          />
        </div>
      </div>
    </div>
  );
}

function ClientEventCard({ event, showCompetitionHeader = true }: { event: SportsLobbyEvent; showCompetitionHeader?: boolean }) {
  const markets = event.markets.slice(0, 3);
  const primaryMarket = markets.find((market) => market.key === "1x2" || market.key === "match_winner") ?? markets[0];
  const primarySelections = primaryMarket ? sortSelections(primaryMarket.selections) : [];
  const eventName = `${event.homeName} vs ${event.awayName}`;
  const eventHref = `/events/${event.id}`;
  const eventClock = formatEventClock(event.startsAt);
  const marketLabel = primaryMarket ? (isWinnerMarket(primaryMarket) ? "1x2" : primaryMarket.name) : "Cotes";

  return (
    <article className="min-w-0 max-w-full overflow-hidden rounded-lg border border-white/10 bg-[#151a22] shadow-panel">
      {showCompetitionHeader ? (
        <Link href={eventHref} className="flex min-w-0 items-center gap-2 border-b border-white/10 px-3 py-2.5">
          <SportGlyph slug={event.sport.slug} label={event.sport.name} className="h-5 w-5" />
          <span className="truncate text-[13px] font-semibold text-slate-200">{event.competition.country}</span>
          <span className="text-slate-600">/</span>
          <span className="truncate text-[13px] font-semibold text-felt">{event.competition.name}</span>
        </Link>
      ) : null}

      <div className="border-b border-white/[0.06] bg-black/10 px-3 py-2 text-center text-[11px] font-semibold text-slate-400">{marketLabel}</div>

      <div className="min-w-0 bg-[#202631] px-2.5 py-3 sm:px-3">
        <div className="mb-2 flex items-center gap-2 text-[12px] font-semibold text-felt">
          <span className="truncate">{eventClock}</span>
        </div>

        <Link href={eventHref} className="grid gap-1.5">
          <div className="flex min-w-0 items-center gap-2">
            <TeamMark sport={event.sport} />
            <span className="truncate text-[13px] font-bold text-white">{event.homeName}</span>
          </div>
          <div className="flex min-w-0 items-center gap-2">
            <TeamMark sport={event.sport} />
            <span className="truncate text-[13px] font-bold text-white">{event.awayName}</span>
          </div>
        </Link>

        {primaryMarket ? (
          <div className={`mt-3 grid min-w-0 gap-1.5 sm:gap-2 ${primarySelections.length >= 3 ? "grid-cols-3" : "grid-cols-2"}`}>
            {primarySelections.slice(0, 3).map((selection) => (
              <OddsButton
                key={selection.id}
                compact
                selection={{
                  selectionId: selection.id,
                  eventId: event.id,
                  marketId: primaryMarket.id,
                  eventName,
                  marketName: primaryMarket.name,
                  selectionName: displaySelectionName(selection, primaryMarket, event),
                  odds: selection.odds,
                  oddsVersion: selection.oddsVersion
                }}
              />
            ))}
          </div>
        ) : null}
      </div>
    </article>
  );
}

function groupEventsByCompetition(events: SportsLobbyEvent[]) {
  const groups = new Map<string, CompetitionGroup>();

  for (const event of events) {
    const id = `${event.sport.slug}:${event.competition.country}:${event.competition.name}`;
    const current = groups.get(id);
    if (current) {
      current.events.push(event);
    } else {
      groups.set(id, {
        id,
        sportSlug: event.sport.slug,
        sportName: event.sport.name,
        competitionName: event.competition.name,
        country: event.competition.country,
        events: [event]
      });
    }
  }

  return Array.from(groups.values())
    .map((group) => ({
      ...group,
      events: [...group.events].sort(
        (left, right) => new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime() || `${left.homeName} ${left.awayName}`.localeCompare(`${right.homeName} ${right.awayName}`)
      )
    }))
    .sort((left, right) => {
      const rankDiff = competitionRank(left) - competitionRank(right);
      if (rankDiff !== 0) return rankDiff;
      const timeDiff = new Date(left.events[0]?.startsAt ?? 0).getTime() - new Date(right.events[0]?.startsAt ?? 0).getTime();
      if (timeDiff !== 0) return timeDiff;
      return `${left.sportName} ${left.competitionName}`.localeCompare(`${right.sportName} ${right.competitionName}`);
    });
}

function groupCompetitionGroupsBySport(groups: CompetitionGroup[]): SportCompetitionGroup[] {
  const sections = new Map<string, SportCompetitionGroup>();

  for (const group of groups) {
    const current = sections.get(group.sportSlug);
    if (current) {
      current.groups.push(group);
    } else {
      sections.set(group.sportSlug, {
        sportSlug: group.sportSlug,
        sportName: group.sportName,
        groups: [group]
      });
    }
  }

  return Array.from(sections.values()).sort((left, right) => {
    const leftTopGroup = left.groups[0];
    const rightTopGroup = right.groups[0];
    const rankDiff = (leftTopGroup ? competitionRank(leftTopGroup) : 99) - (rightTopGroup ? competitionRank(rightTopGroup) : 99);
    if (rankDiff !== 0) return rankDiff;
    return sportRank(left.sportSlug) - sportRank(right.sportSlug) || left.sportName.localeCompare(right.sportName);
  });
}

function competitionRank(group: CompetitionGroup) {
  const value = `${group.sportName} ${group.competitionName} ${group.country}`.toLowerCase();

  if (matchesAny(value, ["world cup", "coupe du monde", "fifa club world cup", "fifa"])) return 1;
  if (matchesAny(value, ["champions league", "ligue des champions", "uefa champions"])) return 2;
  if (matchesAny(value, ["europa league", "conference league", "uefa europa", "uefa conference"])) return 3;
  if (matchesAny(value, ["euro ", "euro 20", "nations league", "copa america"])) return 4;
  if (matchesAny(value, ["premier league", "la liga", "serie a", "bundesliga", "ligue 1"])) return 5;
  if (matchesAny(value, ["wimbledon", "roland garros", "us open", "australian open", "atp", "wta"])) return 6;
  if (matchesAny(value, ["nba", "nfl", "nhl", "mlb"])) return 7;
  return 50 + sportRank(group.sportSlug);
}

function matchesAny(value: string, needles: string[]) {
  return needles.some((needle) => value.includes(needle));
}

function sportRank(slug: string) {
  const ranks: Record<string, number> = {
    football: 1,
    tennis: 2,
    basketball: 3,
    rugby: 4,
    "american-football": 5,
    hockey: 6,
    volleyball: 7,
    handball: 8,
    "table-tennis": 9,
    mma: 10,
    baseball: 11,
    esports: 12
  };
  return ranks[slug] ?? 99;
}

function displaySelectionName<T extends { key: string; name: string }>(selection: T, market: { key: string; name: string }, event: SportsLobbyEvent) {
  if (!isWinnerMarket(market)) return selection.name;
  const rank = selectionRank(selection);
  if (rank === 1) return event.homeName;
  if (rank === 2) return "Match nul";
  if (rank === 3) return event.awayName;
  return selection.name;
}

function isWinnerMarket(market: { key: string; name: string }) {
  const value = `${market.key} ${market.name}`.toLowerCase().replaceAll(" ", "");
  return value.includes("1x2") || value.includes("matchwinner") || value.includes("vainqueur");
}

function sortSelections<T extends { key: string; name: string }>(selections: T[]) {
  return [...selections].sort((left, right) => selectionRank(left) - selectionRank(right) || left.name.localeCompare(right.name));
}

function selectionRank(selection: { key: string; name: string }) {
  const key = selection.key.toLowerCase();
  const name = selection.name.toLowerCase();

  if (key === "home" || name === "1") return 1;
  if (key === "draw" || name === "x") return 2;
  if (key === "away" || name === "2") return 3;
  if (key === "over") return 4;
  if (key === "under") return 5;
  return 10;
}

function TeamMark({ sport }: { sport: { slug: string; name: string } }) {
  return (
    <span className="grid h-5 w-7 shrink-0 place-items-center overflow-hidden text-felt/90 leading-none" aria-hidden="true">
      <SportGlyph slug={sport.slug} label={sport.name} className="h-[18px] w-[18px]" />
    </span>
  );
}

function formatEventClock(value: string) {
  const startsAt = new Date(value);
  const base = format(startsAt, "d MMM, HH:mm", { locale: fr });
  if (startsAt.getTime() <= Date.now()) return base;
  return `${base} - ${formatDistanceToNowStrict(startsAt, { locale: fr, addSuffix: true })}`;
}

function ProviderUnavailable() {
  return (
    <div className="rounded-lg border border-ember/30 bg-ember/10 p-3 text-sm font-semibold text-ember">
      Les cotes sportives sont temporairement indisponibles. Réessayez dans quelques instants.
    </div>
  );
}

function EmptyState({ text }: { text: string }) {
  return <div className="surface rounded-lg p-6 text-sm font-semibold text-slate-400">{text}</div>;
}
