import type { Dispatch, SetStateAction } from "react";
import {
  createSportsEventForm,
  readSportsAdminError,
  toDateTimeLocalInput,
  toPayloadDate,
  updateEventDraft,
  updateEventDraftVenue,
  type SportsEventFormState,
} from "@/components/sports-admin-client-config";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import type { BallboxStoreSportsAdminData, BallboxStoreSportsEvent } from "@/lib/sports-backend-events";

type SportsAdminEventsSectionProps = {
  eyebrow: string;
  title: string;
  createPlaceholder: string;
  createButtonLabel: string;
  createEndpoint: string;
  itemEndpointSegment: string;
  createdMessage: string;
  updatedMessage: string;
  deletedMessage: string;
  venues: BallboxStoreSportsAdminData["venues"];
  items: BallboxStoreSportsEvent[];
  setItems: Dispatch<SetStateAction<BallboxStoreSportsEvent[]>>;
  form: SportsEventFormState;
  setForm: Dispatch<SetStateAction<SportsEventFormState>>;
  busy: boolean;
  selectClassName: string;
  runMutation: (task: () => Promise<void>, successMessage: string) => Promise<void>;
};

export function SportsAdminEventsSection({
  eyebrow,
  title,
  createPlaceholder,
  createButtonLabel,
  createEndpoint,
  itemEndpointSegment,
  createdMessage,
  updatedMessage,
  deletedMessage,
  venues,
  items,
  setItems,
  form,
  setForm,
  busy,
  selectClassName,
  runMutation,
}: SportsAdminEventsSectionProps) {
  const eventFormDefaults = createSportsEventForm({ venues });

  return (
    <div className="rounded-3xl border border-border/70 bg-card/90 p-6">
      <p className="text-xs uppercase tracking-[0.24em] text-primary">{eyebrow}</p>
      <h3 className="mt-2 text-xl font-semibold">{title}</h3>

      <div className="mt-5 grid gap-3">
        <select
          value={form.venueId}
          onChange={(event) => setForm((current) => ({ ...current, venueId: event.target.value }))}
          disabled={busy}
          className={selectClassName}
        >
          {venues.map((venue) => (
            <option key={venue.id} value={venue.id}>
              {(venue.clubName ?? "ATC no disponible")} · {venue.name}
            </option>
          ))}
        </select>
        <Input
          value={form.title}
          onChange={(event) => setForm((current) => ({ ...current, title: event.target.value }))}
          placeholder={createPlaceholder}
          disabled={busy}
        />
        <Input
          value={form.startsAt}
          onChange={(event) => setForm((current) => ({ ...current, startsAt: event.target.value }))}
          type="datetime-local"
          disabled={busy}
        />
        <Button
          loading={busy}
          disabled={busy || !form.venueId || !form.title.trim() || !form.startsAt}
          onClick={() =>
            runMutation(async () => {
              const response = await fetch(createEndpoint, {
                method: "POST",
                headers: { "content-type": "application/json" },
                body: JSON.stringify({
                  venueId: form.venueId,
                  title: form.title,
                  startsAt: toPayloadDate(form.startsAt),
                }),
              });
              if (!response.ok) throw new Error(await readSportsAdminError(response));
              setForm(eventFormDefaults);
            }, createdMessage)
          }
        >
          {createButtonLabel}
        </Button>
      </div>

      <div className="mt-5 space-y-3">
        {items.map((item) => (
          <div key={item.id} className="rounded-2xl border border-border/70 bg-background/40 p-4">
            <div className="grid gap-3">
              <select
                value={item.venueId}
                onChange={(event) =>
                  setItems((current) => updateEventDraftVenue(current, item.id, event.target.value, { venues }))
                }
                disabled={busy}
                className={selectClassName}
              >
                {venues.map((venue) => (
                  <option key={venue.id} value={venue.id}>
                    {(venue.clubName ?? "ATC no disponible")} · {venue.name}
                  </option>
                ))}
              </select>
              <Input
                value={item.title}
                onChange={(event) => setItems((current) => updateEventDraft(current, item.id, { title: event.target.value }))}
                disabled={busy}
              />
              <Input
                value={toDateTimeLocalInput(item.startsAt)}
                onChange={(event) =>
                  setItems((current) => updateEventDraft(current, item.id, { startsAt: toPayloadDate(event.target.value) }))
                }
                type="datetime-local"
                disabled={busy}
              />
              <div className="flex gap-3">
                <Button
                  loading={busy}
                  variant="outline"
                  disabled={busy}
                  onClick={() =>
                    runMutation(async () => {
                      const response = await fetch(`/api/admin/sports/${itemEndpointSegment}/${item.id}`, {
                        method: "PATCH",
                        headers: { "content-type": "application/json" },
                        body: JSON.stringify({
                          venueId: item.venueId,
                          title: item.title,
                          startsAt: item.startsAt,
                        }),
                      });
                      if (!response.ok) throw new Error(await readSportsAdminError(response));
                    }, updatedMessage)
                  }
                >
                  Save
                </Button>
                <Button
                  loading={busy}
                  variant="destructive"
                  disabled={busy}
                  onClick={() =>
                    runMutation(async () => {
                      const response = await fetch(`/api/admin/sports/${itemEndpointSegment}/${item.id}`, {
                        method: "DELETE",
                      });
                      if (!response.ok) throw new Error(await readSportsAdminError(response));
                    }, deletedMessage)
                  }
                >
                  Delete
                </Button>
              </div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
