import type { Dispatch, SetStateAction } from "react";
import { NetworkAdminCreateMachineForm } from "@/components/network-admin-create-machine-form";
import type { Club, MachineFormState, Venue, VenueStatus } from "@/components/network-admin-client-config";
import { readNetworkAdminError } from "@/components/network-admin-mutation-helpers";
import { NetworkAdminVenueHeader } from "@/components/network-admin-venue-header";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

type NetworkAdminVenueCardProps = {
  clubId: string;
  venue: Venue;
  busy: boolean;
  setClubs: Dispatch<SetStateAction<Club[]>>;
  machineForm: MachineFormState;
  setMachineForms: Dispatch<SetStateAction<Record<string, MachineFormState>>>;
  emptyMachineForm: MachineFormState;
  venueStatusOptions: VenueStatus[];
  selectClassName: string;
  mutedPanelClassName: string;
  insetPanelClassName: string;
  wellClassName: string;
  runMutation: (task: () => Promise<void>, successMessage: string) => Promise<void>;
};

export function NetworkAdminVenueCard({
  clubId,
  venue,
  busy,
  setClubs,
  machineForm,
  setMachineForms,
  emptyMachineForm,
  venueStatusOptions,
  selectClassName,
  mutedPanelClassName,
  insetPanelClassName,
  wellClassName,
  runMutation,
}: NetworkAdminVenueCardProps) {
  function updateVenue(patch: Partial<Pick<Venue, "name" | "slug" | "status">>) {
    setClubs((current) =>
      current.map((item) =>
        item.id !== clubId
          ? item
          : {
              ...item,
              venues: item.venues.map((candidate) => (candidate.id === venue.id ? { ...candidate, ...patch } : candidate)),
            }
      )
    );
  }

  function updateMachine(machineId: string, patch: Partial<Venue["vendingMachines"][number]>) {
    setClubs((current) =>
      current.map((item) =>
        item.id !== clubId
          ? item
          : {
              ...item,
              venues: item.venues.map((candidate) =>
                candidate.id !== venue.id
                  ? candidate
                  : {
                      ...candidate,
                      vendingMachines: candidate.vendingMachines.map((entry) =>
                        entry.id === machineId ? { ...entry, ...patch } : entry
                      ),
                    }
              ),
            }
      )
    );
  }

  return (
    <div className={mutedPanelClassName}>
      <NetworkAdminVenueHeader venue={venue} />

      <div className="grid gap-3 md:grid-cols-[1.2fr_1fr_1fr_auto_auto]">
        <Input value={venue.name} onChange={(event) => updateVenue({ name: event.target.value })} disabled={busy} />
        <Input value={venue.slug} onChange={(event) => updateVenue({ slug: event.target.value })} disabled={busy} />
        <select
          value={venue.status}
          onChange={(event) => updateVenue({ status: event.target.value as VenueStatus })}
          disabled={busy}
          className={selectClassName}
        >
          {venueStatusOptions.map((status) => (
            <option key={status} value={status}>
              {status}
            </option>
          ))}
        </select>
        <Button
          loading={busy}
          variant="outline"
          disabled={busy}
          onClick={() =>
            runMutation(async () => {
              const response = await fetch(`/api/network/${clubId}/venues/${venue.id}`, {
                method: "PATCH",
                headers: { "content-type": "application/json" },
                body: JSON.stringify({ name: venue.name, slug: venue.slug, status: venue.status }),
              });

              if (!response.ok) throw new Error(await readNetworkAdminError(response));
            }, "Venue updated")
          }
        >
          Save
        </Button>
        <Button
          loading={busy}
          variant="destructive"
          disabled={busy}
          onClick={() =>
            runMutation(async () => {
              const response = await fetch(`/api/network/${clubId}/venues/${venue.id}`, { method: "DELETE" });
              if (!response.ok) throw new Error(await readNetworkAdminError(response));
            }, "Venue deleted")
          }
        >
          Delete
        </Button>
      </div>

      <p className="mt-4 text-sm text-muted-foreground">
        Screens: {venue.screens}
        {venue.screenIds.length > 0 ? ` · ${venue.screenIds.join(", ")}` : ""}
      </p>

      <div className={wellClassName}>
        <p className="text-xs uppercase tracking-[0.24em] text-primary">Add vending machine</p>
        <NetworkAdminCreateMachineForm
          busy={busy}
          venueId={venue.id}
          machineForm={machineForm}
          setMachineForms={setMachineForms}
          emptyMachineForm={emptyMachineForm}
          runMutation={runMutation}
        />
      </div>

      <div className="mt-4 space-y-3">
        {venue.vendingMachines.map((machine) => (
          <div key={machine.id} className={insetPanelClassName}>
            <div className="mb-3 flex flex-wrap items-center justify-between gap-3">
              <p className="text-xs uppercase tracking-[0.22em] text-primary">Machine</p>
              <span className="rounded-full border border-border/70 bg-card/80 px-3 py-1 text-xs text-muted-foreground">
                screen {machine.screenId ?? "none"}
              </span>
            </div>
            <div className="grid gap-3 md:grid-cols-[1.4fr_1fr_auto_auto]">
              <Input value={machine.label} onChange={(event) => updateMachine(machine.id, { label: event.target.value })} disabled={busy} />
              <label className="flex h-9 items-center gap-3 rounded-md border border-input bg-card/70 px-3 text-sm">
                <input
                  type="checkbox"
                  checked={machine.active}
                  onChange={(event) => updateMachine(machine.id, { active: event.target.checked })}
                  disabled={busy}
                />
                active
              </label>
              <Button
                loading={busy}
                variant="outline"
                disabled={busy}
                onClick={() =>
                  runMutation(async () => {
                    const response = await fetch(`/api/network/venues/${venue.id}/vending-machines/${machine.id}`, {
                      method: "PATCH",
                      headers: { "content-type": "application/json" },
                      body: JSON.stringify({ label: machine.label, active: machine.active }),
                    });

                    if (!response.ok) throw new Error(await readNetworkAdminError(response));
                  }, "Vending machine updated")
                }
              >
                Save
              </Button>
              <Button
                loading={busy}
                variant="destructive"
                disabled={busy}
                onClick={() =>
                  runMutation(async () => {
                    const response = await fetch(`/api/network/venues/${venue.id}/vending-machines/${machine.id}`, {
                      method: "DELETE",
                    });

                    if (!response.ok) throw new Error(await readNetworkAdminError(response));
                  }, "Vending machine deleted")
                }
              >
                Delete
              </Button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}
