// components/admin/PrizeManager.tsx
// Client prize CRUD. Lists prizes, adds a new prize, edits market value / name /
// confirmed flag, deletes. Posts to /api/admin/raffles/[id]/prizes (+ /[prizeId]).
// Market value is entered in soles (the route converts to integer cents).
// Accessible: labeled inputs, text errors, 44px controls.

"use client";

import * as React from "react";
import { useRouter } from "next/navigation";
import { Button, Input, Card } from "@/components/ui";
import { formatPEN } from "@/lib/money";
import type { PrizeDisplayStatus } from "@/lib/types";

export interface PrizeRow {
  id: string;
  position: number;
  name: string;
  description: string | null;
  marketValueCents: number | null;
  sponsorName: string | null;
  imageUrl: string | null;
  isConfirmed: boolean;
  displayStatus: PrizeDisplayStatus;
}

const STATUS_LABEL: Record<PrizeDisplayStatus, string> = {
  por_sortearse: "Por sortearse",
  sorteado: "Sorteado",
  entregado: "Entregado",
};

export function PrizeManager({
  raffleId,
  canEdit,
  prizes,
}: {
  raffleId: string;
  canEdit: boolean;
  prizes: PrizeRow[];
}) {
  const router = useRouter();
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  // New-prize form fields.
  const [name, setName] = React.useState("");
  const [sponsor, setSponsor] = React.useState("");
  const [valueSoles, setValueSoles] = React.useState("");

  async function addPrize(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    setError(null);
    try {
      const res = await fetch(`/api/admin/raffles/${raffleId}/prizes`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: name.trim(),
          sponsorName: sponsor.trim() || undefined,
          marketValueSoles: valueSoles ? Number(valueSoles) : undefined,
        }),
      });
      const data = await res.json().catch(() => ({}));
      if (res.ok) {
        setName("");
        setSponsor("");
        setValueSoles("");
        router.refresh();
      } else {
        setError(data?.error?.message ?? "No se pudo crear el premio.");
      }
    } catch {
      setError("Error de red al crear el premio.");
    } finally {
      setBusy(false);
    }
  }

  async function patchPrize(
    prizeId: string,
    patch: Record<string, unknown>,
  ) {
    setBusy(true);
    setError(null);
    try {
      const res = await fetch(
        `/api/admin/raffles/${raffleId}/prizes/${prizeId}`,
        {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(patch),
        },
      );
      const data = await res.json().catch(() => ({}));
      if (res.ok) router.refresh();
      else setError(data?.error?.message ?? "No se pudo actualizar el premio.");
    } catch {
      setError("Error de red al actualizar el premio.");
    } finally {
      setBusy(false);
    }
  }

  async function deletePrize(prizeId: string) {
    setBusy(true);
    setError(null);
    try {
      const res = await fetch(
        `/api/admin/raffles/${raffleId}/prizes/${prizeId}`,
        { method: "DELETE" },
      );
      const data = await res.json().catch(() => ({}));
      if (res.ok) router.refresh();
      else setError(data?.error?.message ?? "No se pudo eliminar el premio.");
    } catch {
      setError("Error de red al eliminar el premio.");
    } finally {
      setBusy(false);
    }
  }

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

      <Card elevation="tight" className="p-lg">
        <h2 className="font-display text-heading-md font-bold text-ink-strong">
          Premios del sorteo
        </h2>
        {prizes.length === 0 ? (
          <p className="mt-3 font-body text-body-md text-muted">
            Aún no hay premios. Agrega el primero abajo.
          </p>
        ) : (
          <ul className="mt-4 flex flex-col gap-3">
            {prizes.map((p) => (
              <li
                key={p.id}
                className="rounded-md border border-hairline p-4"
              >
                <div className="flex flex-wrap items-start justify-between gap-3">
                  <div>
                    <p className="font-body text-body-lg font-bold text-ink-strong">
                      {p.position + 1}. {p.name}
                    </p>
                    {p.sponsorName ? (
                      <p className="font-body text-caption text-muted">
                        Marca: {p.sponsorName}
                      </p>
                    ) : null}
                    <p className="font-body text-caption text-muted">
                      Valor de mercado:{" "}
                      {p.marketValueCents !== null ? (
                        formatPEN(p.marketValueCents)
                      ) : (
                        <span className="text-primary">sin valorar</span>
                      )}
                    </p>
                    <p className="font-body text-caption text-muted">
                      Estado: {p.isConfirmed ? "confirmado" : "por anunciar"}
                    </p>
                    <p className="font-body text-caption text-muted">
                      Entrega: {STATUS_LABEL[p.displayStatus]}
                    </p>
                  </div>
                  {canEdit ? (
                    <div className="flex flex-wrap gap-2">
                      <PrizeValueEditor
                        prizeId={p.id}
                        current={p.marketValueCents}
                        onSave={(soles) =>
                          patchPrize(p.id, { marketValueSoles: soles })
                        }
                        busy={busy}
                      />
                      <Button
                        type="button"
                        variant="ghost"
                        size="md"
                        disabled={busy}
                        onClick={() =>
                          patchPrize(p.id, { isConfirmed: !p.isConfirmed })
                        }
                      >
                        {p.isConfirmed ? "Marcar por anunciar" : "Confirmar"}
                      </Button>
                      {/* Delivery status (§3). Editable even after the draw is
                          committed, so the public card can flip to "Entregado". */}
                      <label className="flex flex-col justify-end">
                        <span className="sr-only">Estado de entrega del premio</span>
                        <select
                          value={p.displayStatus}
                          disabled={busy}
                          onChange={(e) =>
                            patchPrize(p.id, { displayStatus: e.target.value })
                          }
                          className="min-h-11 rounded-md border border-track bg-canvas px-2 font-body text-caption text-ink-strong focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:opacity-50"
                        >
                          <option value="por_sortearse">Por sortearse</option>
                          <option value="sorteado">Sorteado</option>
                          <option value="entregado">Entregado</option>
                        </select>
                      </label>
                      <button
                        type="button"
                        disabled={busy}
                        onClick={() => deletePrize(p.id)}
                        className="min-h-11 rounded-md border border-primary px-3 font-body text-caption font-medium text-primary hover:bg-primary hover:text-on-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:opacity-50"
                      >
                        Eliminar
                      </button>
                    </div>
                  ) : null}
                </div>
              </li>
            ))}
          </ul>
        )}
      </Card>

      {canEdit ? (
        <Card elevation="tight" className="p-lg">
          <h2 className="font-display text-heading-md font-bold text-ink-strong">
            Agregar premio
          </h2>
          <form
            onSubmit={addPrize}
            className="mt-4 grid grid-cols-1 gap-md sm:grid-cols-3"
          >
            <Input
              label="Nombre del premio"
              value={name}
              onChange={(e) => setName(e.target.value)}
              required
            />
            <Input
              label="Marca (opcional)"
              value={sponsor}
              onChange={(e) => setSponsor(e.target.value)}
            />
            <Input
              label="Valor de mercado (S/)"
              value={valueSoles}
              onChange={(e) => setValueSoles(e.target.value)}
              inputMode="decimal"
              hint="Requerido antes de abrir el sorteo"
            />
            <div className="sm:col-span-3">
              <Button
                type="submit"
                variant="primary"
                disabled={busy || !name.trim()}
              >
                {busy ? "Guardando..." : "Agregar premio"}
              </Button>
            </div>
          </form>
        </Card>
      ) : null}
    </div>
  );
}

function PrizeValueEditor({
  prizeId,
  current,
  onSave,
  busy,
}: {
  prizeId: string;
  current: number | null;
  onSave: (soles: number) => void;
  busy: boolean;
}) {
  const [open, setOpen] = React.useState(false);
  const [value, setValue] = React.useState(
    current !== null ? String(current / 100) : "",
  );

  if (!open) {
    return (
      <Button type="button" variant="secondary" size="md" onClick={() => setOpen(true)}>
        Editar valor
      </Button>
    );
  }

  return (
    <div className="flex items-end gap-2">
      <div className="flex flex-col gap-1.5">
        <label
          htmlFor={`val-${prizeId}`}
          className="font-body text-micro font-medium text-ink-strong"
        >
          Valor S/
        </label>
        <input
          id={`val-${prizeId}`}
          value={value}
          onChange={(e) => setValue(e.target.value)}
          inputMode="decimal"
          className="min-h-11 w-28 rounded-md border border-track bg-canvas px-3 font-body text-body-md text-ink-strong"
        />
      </div>
      <Button
        type="button"
        size="md"
        disabled={busy || value === "" || Number.isNaN(Number(value))}
        onClick={() => {
          onSave(Number(value));
          setOpen(false);
        }}
      >
        Guardar
      </Button>
    </div>
  );
}
