// components/landing/PrizeGrid.tsx
// Data-driven prize grid (ux.md 1.4). Renders prize cards from the active
// raffle's prize list. Unconfirmed prizes (isConfirmed=false) show a tasteful
// "Premio por confirmar" placeholder instead of a blank or a fabricated prize.
// A single bridging impact line under the grid ties winning to giving, so one
// grid serves both audiences.
//
// Resilience: when there are zero prizes (empty/unseeded DB), the grid renders a
// calm placeholder state, never an empty hole or an error.

import * as React from "react";
import type { PublicPrize, PrizeDisplayStatus } from "@/lib/types";
import { Card, Badge } from "@/components/ui";
import { AnimatedHeading } from "./AnimatedHeading";
import { formatDrawDate } from "./format";

export interface PrizeGridProps {
  prizes: PublicPrize[];
}

// The live card-timeline tag (§3). "Entregado" is the terminal, celebratory
// state shown once the prize is handed over.
function statusTag(s: PrizeDisplayStatus): { label: string; tone: "primary" | "neutral" } {
  switch (s) {
    case "entregado":
      return { label: "Entregado", tone: "primary" };
    case "sorteado":
      return { label: "Sorteado", tone: "primary" };
    default:
      return { label: "Por sortearse", tone: "neutral" };
  }
}

function PrizeCard({ prize }: { prize: PublicPrize }) {
  const confirmed = prize.isConfirmed;
  const tag = statusTag(prize.displayStatus);
  const drawDate = formatDrawDate(prize.drawDate);
  return (
    <Card
      as="li"
      elevation="drop"
      className="flex flex-col gap-3 p-0 overflow-hidden"
    >
      <div className="relative flex aspect-[4/3] w-full items-center justify-center overflow-hidden bg-track">
        {confirmed && prize.imageUrl ? (
          // Plain <img>: prize images come from arbitrary sponsor hosts not in
          // next.config.ts remotePatterns (owned by another agent), so the
          // next/image optimizer would reject them. Lazy-loaded, alt-labeled.
          // eslint-disable-next-line @next/next/no-img-element
          <img
            src={prize.imageUrl}
            alt={prize.name}
            loading="lazy"
            decoding="async"
            className="absolute inset-0 h-full w-full object-cover"
          />
        ) : (
          // No real image: a quiet token tile, never a broken or fake image.
          <span
            aria-hidden="true"
            className="font-impact text-heading-lg font-bold text-muted opacity-40"
          >
            Teletón
          </span>
        )}
      </div>
      <div className="flex flex-col gap-2 px-md pb-md">
        <div className="flex items-start justify-between gap-2">
          <h3 className="font-body text-heading-sm font-bold text-ink-strong">
            {confirmed ? prize.name : "Premio por confirmar"}
          </h3>
          {confirmed ? (
            <Badge tone={tag.tone}>{tag.label}</Badge>
          ) : (
            <Badge tone="neutral">Por confirmar</Badge>
          )}
        </div>
        {confirmed && drawDate ? (
          <p className="font-body text-caption font-medium text-muted">
            Sorteo: {drawDate}
          </p>
        ) : null}
        {confirmed && prize.description ? (
          <p className="font-body text-body-md text-muted">
            {prize.description}
          </p>
        ) : !confirmed ? (
          <p className="font-body text-body-md text-muted">
            Estamos cerrando este premio con las marcas. Pronto te contamos cuál
            es.
          </p>
        ) : null}
        {confirmed && prize.sponsorName ? (
          <p className="font-body text-caption text-muted">
            Gracias a {prize.sponsorName}.
          </p>
        ) : null}
      </div>
    </Card>
  );
}

function EmptyState() {
  return (
    <Card
      as="li"
      elevation="drop"
      className="col-span-full mx-auto flex w-full max-w-[420px] flex-col items-center gap-2 text-center"
    >
      <Badge tone="neutral" className="mx-auto">
        Por confirmar
      </Badge>
      <h3 className="font-body text-heading-sm font-bold text-ink-strong">
        Premios por confirmar
      </h3>
      <p className="font-body text-body-md text-muted">
        Estamos cerrando los premios con las marcas que apoyan a Teletón. Vuelve
        pronto para verlos.
      </p>
    </Card>
  );
}

export function PrizeGrid({ prizes }: PrizeGridProps) {
  const hasPrizes = prizes.length > 0;
  return (
    <section className="bg-canvas px-5 py-section" aria-labelledby="premios-title">
      <div className="mx-auto max-w-[1200px]">
        <AnimatedHeading
          as="h2"
          id="premios-title"
          className="text-center font-display text-heading-lg font-bold text-ink-strong"
        >
          Los premios
        </AnimatedHeading>
        <ul className="mt-lg grid grid-cols-1 gap-md sm:grid-cols-2 lg:grid-cols-3">
          {hasPrizes ? (
            prizes.map((prize) => <PrizeCard key={prize.id} prize={prize} />)
          ) : (
            <EmptyState />
          )}
        </ul>

        {/* The bridging impact line: the structural device that makes one grid
            serve both audiences (ux.md 1.4). */}
        <p className="mx-auto mt-lg max-w-[58ch] text-pretty text-center font-body text-body-lg text-ink-strong">
          Cada boleto que compras se convierte en atenciones para los chicos de
          Teletón. Mientras más boletos, más posibilidades de ganar. Nunca está
          garantizado, pero siempre suma a la causa.
        </p>
      </div>
    </section>
  );
}
