// components/admin/ConfigPanel.tsx
// Client panel for per-event config + the guarded status transitions. Calls the
// admin Server Actions (which enforce requireRole("admin") and write the audit
// log). The "Abrir sorteo" button is disabled while the publish gate has
// blockers, and the blockers are listed as text (accessible, never color-only).

"use client";

import * as React from "react";
import { useRouter } from "next/navigation";
import { Button, Input, Checkbox, Card } from "@/components/ui";
import {
  setResolutionRefAction,
  freezePricingAction,
  markBasesPublishedAction,
  setDrawConfigAction,
  openEventAction,
  closeEventAction,
  type ActionResult,
} from "@/app/admin/_lib/actions";

interface ConfigShape {
  mininterResolutionRef: string | null;
  pricingFrozenAt: string | null;
  basesPublished: boolean;
  winnersPerPrize: number;
  allowMultiWin: boolean;
  exclusionNote: string | null;
}

export function ConfigPanel({
  raffleId,
  status,
  config,
  blockers,
}: {
  raffleId: string;
  status: string;
  config: ConfigShape;
  blockers: string[];
}) {
  const router = useRouter();
  const [busy, setBusy] = React.useState(false);
  const [msg, setMsg] = React.useState<{ text: string; ok: boolean } | null>(null);

  const [ref, setRef] = React.useState(config.mininterResolutionRef ?? "");
  const [winners, setWinners] = React.useState(String(config.winnersPerPrize));
  const [multiWin, setMultiWin] = React.useState(config.allowMultiWin);
  const [exclusion, setExclusion] = React.useState(config.exclusionNote ?? "");

  async function run(fn: () => Promise<ActionResult>) {
    setBusy(true);
    setMsg(null);
    const res = await fn();
    setBusy(false);
    setMsg({ text: res.message ?? res.error ?? "", ok: res.ok });
    if (res.ok) router.refresh();
  }

  return (
    <div className="flex flex-col gap-lg">
      {msg ? (
        <p
          role="alert"
          className={
            "rounded-md border px-4 py-3 font-body text-body-md " +
            (msg.ok
              ? "border-steelblue text-ink-strong"
              : "border-primary bg-primary-tint/20 text-ink-strong")
          }
        >
          {msg.text}
        </p>
      ) : null}

      {/* MININTER resolution reference */}
      <Card elevation="tight" className="p-lg">
        <h2 className="font-display text-heading-md font-bold text-ink-strong">
          Resolución MININTER
        </h2>
        <p className="mt-2 font-body text-caption text-muted">
          Adjunta la referencia de la resolución (silencio negativo: sin
          resolución, el sorteo no está autorizado). Es requisito para abrir.
        </p>
        <div className="mt-4 flex flex-wrap items-end gap-3">
          <div className="grow">
            <Input
              label="Referencia de la resolución"
              value={ref}
              onChange={(e) => setRef(e.target.value)}
              placeholder="Ej. R.D. 000-2026-IN/DGIN"
            />
          </div>
          <Button
            type="button"
            disabled={busy || !ref.trim()}
            onClick={() => run(() => setResolutionRefAction(raffleId, ref))}
          >
            Guardar referencia
          </Button>
        </div>
      </Card>

      {/* Pricing freeze + bases */}
      <Card elevation="tight" className="p-lg">
        <h2 className="font-display text-heading-md font-bold text-ink-strong">
          Congelar precio y bases
        </h2>
        <p className="mt-2 font-body text-caption text-muted">
          {config.pricingFrozenAt
            ? `Precio congelado el ${new Date(config.pricingFrozenAt).toLocaleString("es-PE")}.`
            : "El precio aún no está congelado. Congélalo antes de presentar las bases."}
        </p>
        <div className="mt-4 flex flex-wrap gap-3">
          <Button
            type="button"
            variant="secondary"
            disabled={busy || Boolean(config.pricingFrozenAt)}
            onClick={() => run(() => freezePricingAction(raffleId))}
          >
            {config.pricingFrozenAt ? "Precio congelado" : "Congelar precio"}
          </Button>
          <Button
            type="button"
            variant="secondary"
            disabled={busy}
            onClick={() =>
              run(() => markBasesPublishedAction(raffleId, !config.basesPublished))
            }
          >
            {config.basesPublished
              ? "Marcar bases como NO publicadas"
              : "Marcar bases como publicadas"}
          </Button>
        </div>
      </Card>

      {/* Draw config */}
      <Card elevation="tight" className="p-lg">
        <h2 className="font-display text-heading-md font-bold text-ink-strong">
          Configuración del sorteo
        </h2>
        <div className="mt-4 grid grid-cols-1 gap-md sm:grid-cols-2">
          <Input
            label="Ganadores por premio"
            value={winners}
            onChange={(e) => setWinners(e.target.value)}
            inputMode="numeric"
            hint="Normalmente 1"
          />
          <div className="flex items-center">
            <Checkbox
              id="allow-multi-win"
              label="Una persona puede ganar más de un premio"
              checked={multiWin}
              onChange={(e) => setMultiWin(e.target.checked)}
            />
          </div>
          <div className="sm:col-span-2">
            <Input
              label="Nota de exclusiones (personal Teletón y familias)"
              value={exclusion}
              onChange={(e) => setExclusion(e.target.value)}
            />
          </div>
        </div>
        <div className="mt-4">
          <Button
            type="button"
            disabled={busy}
            onClick={() =>
              run(() =>
                setDrawConfigAction(raffleId, {
                  winnersPerPrize: Number(winners) || 1,
                  allowMultiWin: multiWin,
                  exclusionNote: exclusion.trim() || undefined,
                }),
              )
            }
          >
            Guardar configuración del sorteo
          </Button>
        </div>
      </Card>

      {/* Status transitions behind the publish gate */}
      <Card elevation="tight" className="p-lg">
        <h2 className="font-display text-heading-md font-bold text-ink-strong">
          Estado del sorteo
        </h2>
        {status === "draft" ? (
          <>
            {blockers.length > 0 ? (
              <div className="mt-3">
                <p className="font-body text-body-md font-bold text-primary">
                  No se puede abrir todavía. Faltan requisitos:
                </p>
                <ul className="mt-2 flex list-disc flex-col gap-1 pl-5 font-body text-body-md text-ink-strong">
                  {blockers.map((b, i) => (
                    <li key={i}>{b}</li>
                  ))}
                </ul>
              </div>
            ) : (
              <p className="mt-3 font-body text-body-md text-steelblue">
                Todos los requisitos cumplidos. El sorteo puede abrirse.
              </p>
            )}
            <div className="mt-4">
              <Button
                type="button"
                variant="primary"
                disabled={busy || blockers.length > 0}
                onClick={() => run(() => openEventAction(raffleId))}
              >
                Abrir sorteo
              </Button>
            </div>
          </>
        ) : status === "open" ? (
          <div className="mt-4">
            <p className="font-body text-body-md text-muted">
              El sorteo está abierto. Ciérralo para estabilizar el pool antes del
              sorteo en vivo.
            </p>
            <div className="mt-3">
              <Button
                type="button"
                variant="secondary"
                disabled={busy}
                onClick={() => run(() => closeEventAction(raffleId))}
              >
                Cerrar sorteo
              </Button>
            </div>
          </div>
        ) : (
          <p className="mt-3 font-body text-body-md text-muted">
            Estado actual: {status}. No hay transiciones disponibles desde aquí.
          </p>
        )}
      </Card>
    </div>
  );
}
