"use client";

import Link from "next/link";
import { startTransition, useState } from "react";
import type {
  BallboxStoreCampaign,
  BallboxStoreScreen,
  BallboxStoreTvAdminCampaign,
  BallboxStoreTvAdminScreen,
  BallboxStoreTvAdminTvDevice,
  BallboxStoreTvAdminVenueOption,
} from "@/lib/tvs-backend-types";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

type TvsAdminClientProps = {
  source: {
    source: string;
    screens: BallboxStoreScreen[];
    campaigns: BallboxStoreCampaign[];
    analytics: {
      onlineScreens: number;
      activeCampaigns: number;
      totalImpressions: number;
    };
  };
  operations: {
    venues: BallboxStoreTvAdminVenueOption[];
    tvDevices: BallboxStoreTvAdminTvDevice[];
    screens: BallboxStoreTvAdminScreen[];
    campaigns: BallboxStoreTvAdminCampaign[];
  };
};

const emptyScreenForm = {
  venueId: "",
  name: "",
  location: "",
  status: "active" as "active" | "inactive",
  tvDeviceId: "",
};

const emptyTvDeviceForm = {
  name: "",
  location: "",
  manifestUrl: "",
};

const emptyCampaignForm = {
  advertiserName: "",
  name: "",
  startAt: "",
  endAt: "",
};

const emptyCreativeForm = {
  url: "",
  duration: "15",
};

const emptyAssignmentForm = {
  screenId: "",
  startsAt: "",
  endsAt: "",
};

const heroCardClass =
  "rounded-3xl border border-border/70 bg-card/90 p-6 shadow-[0_30px_100px_-40px_var(--glow-strong)]";
const metricCardClass =
  "rounded-3xl border border-border/70 bg-card/90 p-6";
const sectionCardClass =
  "rounded-3xl border border-border/70 bg-card/90 p-6";
const itemCardClass =
  "rounded-2xl border border-border/70 bg-background/40 p-4";
const nestedCardClass = "rounded-2xl border border-border/70 bg-background/35 p-4";
const rowCardClass = "rounded-xl border border-border/70 bg-card/70 p-3";
const secondaryTextClass = "text-muted-foreground";
const selectClass = "h-9 rounded-md border border-input bg-transparent px-3 text-sm text-foreground";
const tvsErrorMessages: Record<string, string> = {
  INVALID_PAYLOAD: "Hay datos inválidos en la operación de TVs.",
  VENUE_NOT_FOUND: "El venue seleccionado no existe.",
  TV_DEVICE_NOT_FOUND: "El TV device seleccionado no existe.",
  TV_DEVICE_LINKED_TO_SCREEN: "Ese TV device ya está vinculado a otra pantalla.",
  TV_DEVICE_HAS_IMPRESSIONS: "No se puede borrar el TV device porque ya tiene impresiones.",
  SCREEN_NOT_FOUND: "La pantalla ya no existe.",
  SCREEN_HAS_ASSIGNMENTS: "No se puede borrar la pantalla porque todavía tiene assignments.",
  CAMPAIGN_NOT_FOUND: "La campaña ya no existe.",
  CAMPAIGN_HAS_CREATIVES: "No se puede borrar la campaña porque todavía tiene creatives.",
  CAMPAIGN_HAS_ASSIGNMENTS: "No se puede borrar la campaña porque todavía tiene assignments.",
  CREATIVE_NOT_FOUND: "El creative ya no existe.",
  CREATIVE_HAS_IMPRESSIONS: "No se puede borrar el creative porque ya tiene impresiones.",
  ASSIGNMENT_ALREADY_EXISTS: "Ya existe un assignment para esa combinación de pantalla y campaña.",
  ASSIGNMENT_NOT_FOUND: "El assignment ya no existe.",
};

function normalizeError(error: unknown) {
  if (error instanceof Error) return tvsErrorMessages[error.message] ?? error.message;
  return "Request failed";
}

async function readError(response: Response) {
  const payload = await response.json().catch(() => null);
  return payload?.error ?? `HTTP_${response.status}`;
}

export function TvsAdminClient({ source, operations }: TvsAdminClientProps) {
  const [adminData, setAdminData] = useState(operations);
  const [busy, setBusy] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [messageTone, setMessageTone] = useState<"success" | "error">("success");
  const [screenForm, setScreenForm] = useState({
    ...emptyScreenForm,
    venueId: operations.venues[0]?.id ?? "",
  });
  const [tvDeviceForm, setTvDeviceForm] = useState(emptyTvDeviceForm);
  const [campaignForm, setCampaignForm] = useState(emptyCampaignForm);
  const [creativeForms, setCreativeForms] = useState<Record<string, typeof emptyCreativeForm>>({});
  const [assignmentForms, setAssignmentForms] = useState<Record<string, typeof emptyAssignmentForm>>({});

  async function reloadAdminData() {
    const response = await fetch("/api/admin/tvs/operations", { cache: "no-store" });
    if (!response.ok) {
      throw new Error(await readError(response));
    }

    const payload = (await response.json()) as { item: TvsAdminClientProps["operations"] };
    startTransition(() => {
      setAdminData(payload.item);
    });
  }

  async function runMutation(task: () => Promise<void>, successMessage: string) {
    setBusy(true);
    setMessage(null);
    setMessageTone("success");

    try {
      await task();
      await reloadAdminData();
      setMessage(successMessage);
    } catch (error) {
      setMessageTone("error");
      setMessage(normalizeError(error));
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="space-y-6">
      <section className="grid gap-4 xl:grid-cols-[minmax(0,1.2fr)_repeat(3,minmax(0,0.6fr))]">
        <div className={heroCardClass}>
          <div className="flex flex-wrap items-start justify-between gap-4">
            <div className="space-y-2">
              <p className="text-xs uppercase tracking-[0.24em] text-primary">Runtime overview</p>
              <h2 className="text-2xl font-semibold tracking-tight">Operación diaria de pantallas y pauta</h2>
              <p className={`max-w-2xl text-sm ${secondaryTextClass}`}>
                Alta rápida, vínculo con TV device, campañas activas y chequeo de runtime desde un solo panel.
              </p>
            </div>
            <div className="flex flex-wrap gap-2">
              <Link
                href="/admin/screens"
                className="rounded-full border border-border/70 bg-background/40 px-4 py-2 text-sm text-foreground transition hover:border-primary/60"
              >
                Runtime index
              </Link>
              <Link
                href="/api/tvs/screens"
                className="rounded-full border border-primary/40 px-4 py-2 text-sm text-primary transition hover:bg-primary hover:text-primary-foreground"
              >
                TV API
              </Link>
            </div>
          </div>

          <div className={`mt-4 flex flex-wrap items-center gap-3 text-sm ${secondaryTextClass}`}>
            <span className="rounded-full border border-border/70 bg-background/40 px-3 py-1.5 text-foreground">{source.source}</span>
            <span>Canonical Ballbox model persisted in Postgres</span>
            <span>{adminData.screens.length} screens</span>
            <span>{adminData.tvDevices.length} tv devices</span>
          </div>
        </div>

        <div className={metricCardClass}>
          <p className={`text-xs uppercase tracking-[0.2em] ${secondaryTextClass}`}>Online screens</p>
          <p className="mt-3 text-4xl font-semibold">{source.analytics.onlineScreens}</p>
        </div>
        <div className={metricCardClass}>
          <p className={`text-xs uppercase tracking-[0.2em] ${secondaryTextClass}`}>Active campaigns</p>
          <p className="mt-3 text-4xl font-semibold">{source.analytics.activeCampaigns}</p>
        </div>
        <div className={metricCardClass}>
          <p className={`text-xs uppercase tracking-[0.2em] ${secondaryTextClass}`}>Total impressions</p>
          <p className="mt-3 text-4xl font-semibold">{source.analytics.totalImpressions.toLocaleString("es-AR")}</p>
        </div>
      </section>

      <section className="space-y-6">
        <div className={sectionCardClass}>
          <div className="flex flex-wrap items-center justify-between gap-4">
            <div>
              <p className="text-xs uppercase tracking-[0.24em] text-primary">Operational CRUD</p>
              <h2 className="mt-2 text-2xl font-semibold">Screens</h2>
              <p className={`mt-1 text-sm ${secondaryTextClass}`}>Pantallas, venue, estado operativo y vínculo con TV device.</p>
            </div>
          </div>

          <div className="mt-5 grid gap-3 md:grid-cols-[1.1fr_1fr_1fr_1fr_auto]">
            <select
              value={screenForm.venueId}
              onChange={(event) => setScreenForm((current) => ({ ...current, venueId: event.target.value }))}
              disabled={busy}
              className={selectClass}
            >
              {adminData.venues.map((venue) => (
                <option key={venue.id} value={venue.id}>
                  {(venue.clubName ?? "ATC no disponible")} · {venue.venueName}
                </option>
              ))}
            </select>
            <Input
              value={screenForm.name}
              onChange={(event) => setScreenForm((current) => ({ ...current, name: event.target.value }))}
              placeholder="Screen name"
              disabled={busy}
            />
            <Input
              value={screenForm.location}
              onChange={(event) => setScreenForm((current) => ({ ...current, location: event.target.value }))}
              placeholder="Location"
              disabled={busy}
            />
            <select
              value={screenForm.tvDeviceId}
              onChange={(event) => setScreenForm((current) => ({ ...current, tvDeviceId: event.target.value }))}
              disabled={busy}
              className={selectClass}
            >
              <option value="">No TV device</option>
              {adminData.tvDevices
                .filter((tvDevice) => !tvDevice.linkedScreenId)
                .map((tvDevice) => (
                  <option key={tvDevice.id} value={tvDevice.id}>
                    {tvDevice.name}
                  </option>
                ))}
            </select>
            <Button
              loading={busy}
              disabled={busy || !screenForm.venueId || screenForm.name.trim().length === 0}
              onClick={() =>
                runMutation(async () => {
                  const response = await fetch("/api/admin/tvs/screens", {
                    method: "POST",
                    headers: { "content-type": "application/json" },
                    body: JSON.stringify({
                      venueId: screenForm.venueId,
                      name: screenForm.name,
                      location: screenForm.location,
                      tvDeviceId: screenForm.tvDeviceId || undefined,
                      status: screenForm.status,
                    }),
                  });

                  if (!response.ok) {
                    throw new Error(await readError(response));
                  }

                  setScreenForm({
                    ...emptyScreenForm,
                    venueId: adminData.venues[0]?.id ?? "",
                  });
                }, "Screen created")
              }
            >
              Add
            </Button>
          </div>

          <div className="mt-5 space-y-3">
            {adminData.screens.map((screen) => (
              <div key={screen.id} className={itemCardClass}>
                <div className="grid gap-3 xl:grid-cols-[minmax(0,1.25fr)_minmax(180px,1fr)_minmax(160px,0.9fr)_140px_minmax(180px,1fr)_auto_auto]">
                  <Input
                    value={screen.name}
                    onChange={(event) =>
                      setAdminData((current) => ({
                        ...current,
                        screens: current.screens.map((item) =>
                          item.id === screen.id ? { ...item, name: event.target.value } : item
                        ),
                      }))
                    }
                    disabled={busy}
                  />
                  <select
                    value={screen.venueId}
                    onChange={(event) => {
                      const nextVenue = adminData.venues.find((venue) => venue.id === event.target.value);
                      if (!nextVenue) return;

                      setAdminData((current) => ({
                        ...current,
                        screens: current.screens.map((item) =>
                          item.id === screen.id
                            ? {
                                ...item,
                                venueId: nextVenue.id,
                                venueName: nextVenue.venueName,
                                clubId: nextVenue.clubId,
                                clubName: nextVenue.clubName,
                              }
                            : item
                        ),
                      }));
                    }}
                    disabled={busy}
                    className={selectClass}
                  >
                    {adminData.venues.map((venue) => (
                      <option key={venue.id} value={venue.id}>
                        {(venue.clubName ?? "ATC no disponible")} · {venue.venueName}
                      </option>
                    ))}
                  </select>
                  <Input
                    value={screen.location ?? ""}
                    onChange={(event) =>
                      setAdminData((current) => ({
                        ...current,
                        screens: current.screens.map((item) =>
                          item.id === screen.id ? { ...item, location: event.target.value } : item
                        ),
                      }))
                    }
                    disabled={busy}
                  />
                  <select
                    value={screen.lifecycleStatus}
                    onChange={(event) =>
                      setAdminData((current) => ({
                        ...current,
                        screens: current.screens.map((item) =>
                          item.id === screen.id
                            ? { ...item, lifecycleStatus: event.target.value as "active" | "inactive" }
                            : item
                        ),
                      }))
                    }
                    disabled={busy}
                    className={selectClass}
                  >
                    <option value="active">active</option>
                    <option value="inactive">inactive</option>
                  </select>
                  <select
                    value={screen.tvDeviceId ?? ""}
                    onChange={(event) => {
                      const nextTvDevice = adminData.tvDevices.find((tvDevice) => tvDevice.id === event.target.value);
                      setAdminData((current) => ({
                        ...current,
                        screens: current.screens.map((item) =>
                          item.id === screen.id
                            ? {
                                ...item,
                                tvDeviceId: nextTvDevice?.id ?? null,
                                tvDeviceName: nextTvDevice?.name ?? null,
                              }
                            : item
                        ),
                      }));
                    }}
                    disabled={busy}
                    className={selectClass}
                  >
                    <option value="">No TV device</option>
                    {adminData.tvDevices
                      .filter((tvDevice) => !tvDevice.linkedScreenId || tvDevice.linkedScreenId === screen.id)
                      .map((tvDevice) => (
                        <option key={tvDevice.id} value={tvDevice.id}>
                          {tvDevice.name}
                        </option>
                      ))}
                  </select>
                  <Button
                    loading={busy}
                    variant="outline"
                    disabled={busy}
                    onClick={() =>
                      runMutation(async () => {
                        const response = await fetch(`/api/admin/tvs/screens/${screen.id}`, {
                          method: "PATCH",
                          headers: { "content-type": "application/json" },
                          body: JSON.stringify({
                            venueId: screen.venueId,
                            name: screen.name,
                            location: screen.location ?? "",
                            status: screen.lifecycleStatus,
                            tvDeviceId: screen.tvDeviceId ?? "",
                          }),
                        });

                        if (!response.ok) {
                          throw new Error(await readError(response));
                        }
                      }, "Screen updated")
                    }
                  >
                    Save
                  </Button>
                  <Button
                    loading={busy}
                    variant="destructive"
                    disabled={busy}
                    onClick={() =>
                      runMutation(async () => {
                        const response = await fetch(`/api/admin/tvs/screens/${screen.id}`, { method: "DELETE" });
                        if (!response.ok) {
                          throw new Error(await readError(response));
                        }
                      }, "Screen deleted")
                    }
                  >
                    Delete
                  </Button>
                </div>

                <div className={`mt-3 flex flex-wrap gap-3 text-sm ${secondaryTextClass}`}>
                  <span>{(screen.clubName ?? "ATC no disponible")} · {screen.venueName}</span>
                  <span>Runtime: {screen.operationalStatus}</span>
                  <span>Assignments: {screen.assignmentCount}</span>
                  <span>Last seen: {screen.lastSeen ? new Date(screen.lastSeen).toLocaleString("es-AR") : "never"}</span>
                  <Link className="text-primary transition hover:text-primary/80" href={`/player/${screen.id}`}>
                    Lightweight player
                  </Link>
                  <Link className="text-primary transition hover:text-primary/80" href={`/api/tvs/manifest/${screen.id}`}>
                    Manifest
                  </Link>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="grid gap-6 xl:grid-cols-[minmax(300px,0.8fr)_minmax(0,1.2fr)]">
          <section className={`min-w-0 ${sectionCardClass}`}>
            <div className="min-w-0">
              <p className="text-xs uppercase tracking-[0.24em] text-primary">Operational CRUD</p>
              <h2 className="mt-2 break-words text-xl font-semibold leading-tight xl:text-2xl">TV devices</h2>
              <p className={`mt-1 text-sm ${secondaryTextClass}`}>Dispositivos físicos, manifest override y salud de conexión.</p>
            </div>

            <div className="mt-5 grid gap-3">
              <Input
                value={tvDeviceForm.name}
                onChange={(event) => setTvDeviceForm((current) => ({ ...current, name: event.target.value }))}
                placeholder="TV device name"
                disabled={busy}
              />
              <Input
                value={tvDeviceForm.location}
                onChange={(event) => setTvDeviceForm((current) => ({ ...current, location: event.target.value }))}
                placeholder="Location"
                disabled={busy}
              />
              <Input
                value={tvDeviceForm.manifestUrl}
                onChange={(event) => setTvDeviceForm((current) => ({ ...current, manifestUrl: event.target.value }))}
                placeholder="https://..."
                disabled={busy}
              />
              <Button
                loading={busy}
                disabled={busy || tvDeviceForm.name.trim().length === 0}
                onClick={() =>
                  runMutation(async () => {
                    const response = await fetch("/api/admin/tvs/tv-devices", {
                      method: "POST",
                      headers: { "content-type": "application/json" },
                      body: JSON.stringify({
                        name: tvDeviceForm.name,
                        location: tvDeviceForm.location,
                        manifestUrl: tvDeviceForm.manifestUrl || undefined,
                      }),
                    });

                    if (!response.ok) {
                      throw new Error(await readError(response));
                    }

                    setTvDeviceForm(emptyTvDeviceForm);
                  }, "TV device created")
                }
              >
                Add TV device
              </Button>
            </div>

            <div className="mt-5 space-y-3">
              {adminData.tvDevices.map((tvDevice) => (
                <div key={tvDevice.id} className={itemCardClass}>
                  <div className="grid gap-3">
                    <Input
                      value={tvDevice.name}
                      onChange={(event) =>
                        setAdminData((current) => ({
                          ...current,
                          tvDevices: current.tvDevices.map((item) =>
                            item.id === tvDevice.id ? { ...item, name: event.target.value } : item
                          ),
                        }))
                      }
                      disabled={busy}
                    />
                    <Input
                      value={tvDevice.location ?? ""}
                      onChange={(event) =>
                        setAdminData((current) => ({
                          ...current,
                          tvDevices: current.tvDevices.map((item) =>
                            item.id === tvDevice.id ? { ...item, location: event.target.value } : item
                          ),
                        }))
                      }
                      disabled={busy}
                    />
                    <Input
                      value={tvDevice.manifestUrl ?? ""}
                      onChange={(event) =>
                        setAdminData((current) => ({
                          ...current,
                          tvDevices: current.tvDevices.map((item) =>
                            item.id === tvDevice.id ? { ...item, manifestUrl: event.target.value } : item
                          ),
                        }))
                      }
                      disabled={busy}
                    />
                    <div className="flex flex-wrap gap-2">
                      <Button
                        loading={busy}
                        variant="outline"
                        disabled={busy}
                        onClick={() =>
                          runMutation(async () => {
                            const response = await fetch(`/api/admin/tvs/tv-devices/${tvDevice.id}`, {
                              method: "PATCH",
                              headers: { "content-type": "application/json" },
                              body: JSON.stringify({
                                name: tvDevice.name,
                                location: tvDevice.location ?? "",
                                manifestUrl: tvDevice.manifestUrl ?? "",
                              }),
                            });

                            if (!response.ok) {
                              throw new Error(await readError(response));
                            }
                          }, "TV device updated")
                        }
                      >
                        Save
                      </Button>
                      <Button
                        loading={busy}
                        variant="destructive"
                        disabled={busy}
                        onClick={() =>
                          runMutation(async () => {
                            const response = await fetch(`/api/admin/tvs/tv-devices/${tvDevice.id}`, { method: "DELETE" });
                            if (!response.ok) {
                              throw new Error(await readError(response));
                            }
                          }, "TV device deleted")
                        }
                      >
                        Delete
                      </Button>
                    </div>
                  </div>

                  <div className={`mt-3 space-y-1 text-sm ${secondaryTextClass}`}>
                    <p>Linked screen: {tvDevice.linkedScreenName ?? "none"}</p>
                    <p>Last seen: {tvDevice.lastSeen ? new Date(tvDevice.lastSeen).toLocaleString("es-AR") : "never"}</p>
                    <p>Impressions: {tvDevice.impressionCount}</p>
                  </div>
                </div>
              ))}
            </div>
          </section>

          <section className={`min-w-0 ${sectionCardClass}`}>
            <p className="text-xs uppercase tracking-[0.24em] text-primary">Operational CRUD</p>
            <h2 className="mt-2 text-2xl font-semibold">Campaigns</h2>
            <p className={`mt-1 text-sm ${secondaryTextClass}`}>Pauta, creatives y assignments con espacio real para operar.</p>
            <div className="mt-5 grid gap-3 lg:grid-cols-2 2xl:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_180px_180px_auto]">
              <Input
                value={campaignForm.advertiserName}
                onChange={(event) => setCampaignForm((current) => ({ ...current, advertiserName: event.target.value }))}
                placeholder="Advertiser"
                disabled={busy}
              />
              <Input
                value={campaignForm.name}
                onChange={(event) => setCampaignForm((current) => ({ ...current, name: event.target.value }))}
                placeholder="Campaign name"
                disabled={busy}
              />
              <Input
                type="datetime-local"
                value={campaignForm.startAt}
                onChange={(event) => setCampaignForm((current) => ({ ...current, startAt: event.target.value }))}
                disabled={busy}
              />
              <Input
                type="datetime-local"
                value={campaignForm.endAt}
                onChange={(event) => setCampaignForm((current) => ({ ...current, endAt: event.target.value }))}
                disabled={busy}
              />
              <Button
                loading={busy}
                disabled={
                  busy ||
                  campaignForm.advertiserName.trim().length === 0 ||
                  campaignForm.name.trim().length === 0 ||
                  campaignForm.startAt.length === 0 ||
                  campaignForm.endAt.length === 0
                }
                onClick={() =>
                  runMutation(async () => {
                    const response = await fetch("/api/admin/tvs/campaigns", {
                      method: "POST",
                      headers: { "content-type": "application/json" },
                      body: JSON.stringify({
                        advertiserName: campaignForm.advertiserName,
                        name: campaignForm.name,
                        startAt: new Date(campaignForm.startAt).toISOString(),
                        endAt: new Date(campaignForm.endAt).toISOString(),
                      }),
                    });

                    if (!response.ok) {
                      throw new Error(await readError(response));
                    }

                    setCampaignForm(emptyCampaignForm);
                  }, "Campaign created")
                }
              >
                Add campaign
              </Button>
            </div>

            <div className="mt-5 space-y-3">
              {adminData.campaigns.map((campaign) => {
                const creativeForm = creativeForms[campaign.id] ?? emptyCreativeForm;
                const assignmentForm = assignmentForms[campaign.id] ?? {
                  ...emptyAssignmentForm,
                  screenId: adminData.screens[0]?.id ?? "",
                };

                return (
                <div key={campaign.id} className={itemCardClass}>
                  <div className="flex flex-wrap items-start justify-between gap-4">
                    <div className="space-y-1">
                      <p className="text-xs uppercase tracking-[0.2em] text-primary/90">{campaign.advertiserName}</p>
                      <h3 className="text-lg font-semibold">{campaign.name}</h3>
                    </div>
                    <div className="flex flex-wrap gap-2">
                      <Button
                        loading={busy}
                        variant="outline"
                        disabled={busy}
                        onClick={() =>
                          runMutation(async () => {
                            const response = await fetch(`/api/admin/tvs/campaigns/${campaign.id}`, {
                              method: "PATCH",
                              headers: { "content-type": "application/json" },
                              body: JSON.stringify({
                                advertiserName: campaign.advertiserName,
                                name: campaign.name,
                                startAt: campaign.startAt,
                                endAt: campaign.endAt,
                              }),
                            });

                            if (!response.ok) {
                              throw new Error(await readError(response));
                            }
                          }, "Campaign updated")
                        }
                      >
                        Save campaign
                      </Button>
                      <Button
                        loading={busy}
                        variant="destructive"
                        disabled={busy}
                        onClick={() =>
                          runMutation(async () => {
                            const response = await fetch(`/api/admin/tvs/campaigns/${campaign.id}`, {
                              method: "DELETE",
                            });
                            if (!response.ok) {
                              throw new Error(await readError(response));
                            }
                          }, "Campaign deleted")
                        }
                      >
                        Delete
                      </Button>
                    </div>
                  </div>

                  <div className="mt-4 grid gap-3 lg:grid-cols-2">
                    <Input
                      value={campaign.advertiserName}
                      onChange={(event) =>
                        setAdminData((current) => ({
                          ...current,
                          campaigns: current.campaigns.map((item) =>
                            item.id === campaign.id ? { ...item, advertiserName: event.target.value } : item
                          ),
                        }))
                      }
                      disabled={busy}
                    />
                    <Input
                      value={campaign.name}
                      onChange={(event) =>
                        setAdminData((current) => ({
                          ...current,
                          campaigns: current.campaigns.map((item) =>
                            item.id === campaign.id ? { ...item, name: event.target.value } : item
                          ),
                        }))
                      }
                      disabled={busy}
                    />
                    <div className="grid gap-3 md:grid-cols-2">
                      <Input
                        type="datetime-local"
                        value={campaign.startAt.slice(0, 16)}
                        onChange={(event) =>
                          setAdminData((current) => ({
                            ...current,
                            campaigns: current.campaigns.map((item) =>
                              item.id === campaign.id
                                ? { ...item, startAt: new Date(event.target.value).toISOString() }
                                : item
                            ),
                          }))
                        }
                        disabled={busy}
                      />
                      <Input
                        type="datetime-local"
                        value={campaign.endAt.slice(0, 16)}
                        onChange={(event) =>
                          setAdminData((current) => ({
                            ...current,
                            campaigns: current.campaigns.map((item) =>
                              item.id === campaign.id ? { ...item, endAt: new Date(event.target.value).toISOString() } : item
                            ),
                          }))
                        }
                        disabled={busy}
                      />
                    </div>
                  </div>

                  <div className={nestedCardClass}>
                    <p className="text-sm font-medium">Creatives</p>
                    <div className="mt-3 grid gap-3 lg:grid-cols-[minmax(0,1fr)_120px_auto]">
                      <Input
                        value={creativeForm.url}
                        onChange={(event) =>
                          setCreativeForms((current) => ({
                            ...current,
                            [campaign.id]: { ...creativeForm, url: event.target.value },
                          }))
                        }
                        placeholder="/videos/hero.mp4"
                        disabled={busy}
                      />
                      <Input
                        type="number"
                        min="1"
                        value={creativeForm.duration}
                        onChange={(event) =>
                          setCreativeForms((current) => ({
                            ...current,
                            [campaign.id]: { ...creativeForm, duration: event.target.value },
                          }))
                        }
                        disabled={busy}
                      />
                      <Button
                        loading={busy}
                        disabled={busy || creativeForm.url.trim().length === 0}
                        onClick={() =>
                          runMutation(async () => {
                            const response = await fetch(`/api/admin/tvs/campaigns/${campaign.id}/creatives`, {
                              method: "POST",
                              headers: { "content-type": "application/json" },
                              body: JSON.stringify({
                                url: creativeForm.url,
                                duration: Number(creativeForm.duration || 15),
                              }),
                            });

                            if (!response.ok) {
                              throw new Error(await readError(response));
                            }

                            setCreativeForms((current) => ({ ...current, [campaign.id]: emptyCreativeForm }));
                          }, "Creative created")
                        }
                      >
                        Add creative
                      </Button>
                    </div>

                    <div className="mt-3 space-y-2">
                      {campaign.creatives.map((creative) => (
                        <div key={creative.id} className={rowCardClass}>
                          <div className="grid gap-3 lg:grid-cols-[minmax(0,1fr)_120px_auto_auto]">
                            <Input
                              value={creative.url}
                              onChange={(event) =>
                                setAdminData((current) => ({
                                  ...current,
                                  campaigns: current.campaigns.map((item) =>
                                    item.id !== campaign.id
                                      ? item
                                      : {
                                          ...item,
                                          creatives: item.creatives.map((candidate) =>
                                            candidate.id === creative.id ? { ...candidate, url: event.target.value } : candidate
                                          ),
                                        }
                                  ),
                                }))
                              }
                              disabled={busy}
                            />
                            <Input
                              type="number"
                              min="1"
                              value={String(creative.duration)}
                              onChange={(event) =>
                                setAdminData((current) => ({
                                  ...current,
                                  campaigns: current.campaigns.map((item) =>
                                    item.id !== campaign.id
                                      ? item
                                      : {
                                          ...item,
                                          creatives: item.creatives.map((candidate) =>
                                            candidate.id === creative.id
                                              ? { ...candidate, duration: Number(event.target.value || 1) }
                                              : candidate
                                          ),
                                        }
                                  ),
                                }))
                              }
                              disabled={busy}
                            />
                            <Button
                              loading={busy}
                              variant="outline"
                              disabled={busy}
                              onClick={() =>
                                runMutation(async () => {
                                  const response = await fetch(`/api/admin/tvs/creatives/${creative.id}`, {
                                    method: "PATCH",
                                    headers: { "content-type": "application/json" },
                                    body: JSON.stringify({
                                      url: creative.url,
                                      duration: creative.duration,
                                    }),
                                  });
                                  if (!response.ok) {
                                    throw new Error(await readError(response));
                                  }
                                }, "Creative updated")
                              }
                            >
                              Save
                            </Button>
                            <Button
                              loading={busy}
                              variant="destructive"
                              disabled={busy}
                              onClick={() =>
                                runMutation(async () => {
                                  const response = await fetch(`/api/admin/tvs/creatives/${creative.id}`, {
                                    method: "DELETE",
                                  });
                                  if (!response.ok) {
                                    throw new Error(await readError(response));
                                  }
                                }, "Creative deleted")
                              }
                            >
                              Delete
                            </Button>
                          </div>
                          <p className={`mt-2 text-sm ${secondaryTextClass}`}>Impressions: {creative.impressionCount}</p>
                        </div>
                      ))}
                    </div>
                  </div>

                  <div className={nestedCardClass}>
                    <p className="text-sm font-medium">Assignments</p>
                    <div className="mt-3 grid gap-3 lg:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)_auto]">
                      <select
                        value={assignmentForm.screenId}
                        onChange={(event) =>
                          setAssignmentForms((current) => ({
                            ...current,
                            [campaign.id]: { ...assignmentForm, screenId: event.target.value },
                          }))
                        }
                        disabled={busy}
                        className={selectClass}
                      >
                        {adminData.screens.map((screen) => (
                          <option key={screen.id} value={screen.id}>
                            {screen.name}
                          </option>
                        ))}
                      </select>
                      <Input
                        type="datetime-local"
                        value={assignmentForm.startsAt}
                        onChange={(event) =>
                          setAssignmentForms((current) => ({
                            ...current,
                            [campaign.id]: { ...assignmentForm, startsAt: event.target.value },
                          }))
                        }
                        disabled={busy}
                      />
                      <Input
                        type="datetime-local"
                        value={assignmentForm.endsAt}
                        onChange={(event) =>
                          setAssignmentForms((current) => ({
                            ...current,
                            [campaign.id]: { ...assignmentForm, endsAt: event.target.value },
                          }))
                        }
                        disabled={busy}
                      />
                      <Button
                        loading={busy}
                        disabled={busy || assignmentForm.screenId.length === 0}
                        onClick={() =>
                          runMutation(async () => {
                            const response = await fetch(`/api/admin/tvs/campaigns/${campaign.id}/assignments`, {
                              method: "POST",
                              headers: { "content-type": "application/json" },
                              body: JSON.stringify({
                                screenId: assignmentForm.screenId,
                                active: true,
                                startsAt: assignmentForm.startsAt ? new Date(assignmentForm.startsAt).toISOString() : undefined,
                                endsAt: assignmentForm.endsAt ? new Date(assignmentForm.endsAt).toISOString() : undefined,
                              }),
                            });
                            if (!response.ok) {
                              throw new Error(await readError(response));
                            }

                            setAssignmentForms((current) => ({
                              ...current,
                              [campaign.id]: { ...emptyAssignmentForm, screenId: adminData.screens[0]?.id ?? "" },
                            }));
                          }, "Assignment created")
                        }
                      >
                        Add assignment
                      </Button>
                    </div>

                    <div className="mt-3 space-y-2">
                      {campaign.assignments.map((assignment) => (
                        <div key={assignment.id} className={rowCardClass}>
                          <div className="grid gap-3 xl:grid-cols-[minmax(0,1fr)_120px_minmax(0,1fr)_minmax(0,1fr)_auto_auto]">
                            <select
                              value={assignment.screenId}
                              onChange={(event) =>
                                setAdminData((current) => ({
                                  ...current,
                                  campaigns: current.campaigns.map((item) =>
                                    item.id !== campaign.id
                                      ? item
                                      : {
                                          ...item,
                                          assignments: item.assignments.map((candidate) =>
                                            candidate.id === assignment.id
                                              ? {
                                                  ...candidate,
                                                  screenId: event.target.value,
                                                  screenName:
                                                    adminData.screens.find((screen) => screen.id === event.target.value)?.name ??
                                                    candidate.screenName,
                                                }
                                              : candidate
                                          ),
                                        }
                                  ),
                                }))
                              }
                              disabled={busy}
                              className={selectClass}
                            >
                              {adminData.screens.map((screen) => (
                                <option key={screen.id} value={screen.id}>
                                  {screen.name}
                                </option>
                              ))}
                            </select>
                            <select
                              value={assignment.active ? "true" : "false"}
                              onChange={(event) =>
                                setAdminData((current) => ({
                                  ...current,
                                  campaigns: current.campaigns.map((item) =>
                                    item.id !== campaign.id
                                      ? item
                                      : {
                                          ...item,
                                          assignments: item.assignments.map((candidate) =>
                                            candidate.id === assignment.id
                                              ? { ...candidate, active: event.target.value === "true" }
                                              : candidate
                                          ),
                                        }
                                  ),
                                }))
                              }
                              disabled={busy}
                              className={selectClass}
                            >
                              <option value="true">active</option>
                              <option value="false">inactive</option>
                            </select>
                            <Input
                              type="datetime-local"
                              value={assignment.startsAt ? assignment.startsAt.slice(0, 16) : ""}
                              onChange={(event) =>
                                setAdminData((current) => ({
                                  ...current,
                                  campaigns: current.campaigns.map((item) =>
                                    item.id !== campaign.id
                                      ? item
                                      : {
                                          ...item,
                                          assignments: item.assignments.map((candidate) =>
                                            candidate.id === assignment.id
                                              ? {
                                                  ...candidate,
                                                  startsAt: event.target.value
                                                    ? new Date(event.target.value).toISOString()
                                                    : null,
                                                }
                                              : candidate
                                          ),
                                        }
                                  ),
                                }))
                              }
                              disabled={busy}
                            />
                            <Input
                              type="datetime-local"
                              value={assignment.endsAt ? assignment.endsAt.slice(0, 16) : ""}
                              onChange={(event) =>
                                setAdminData((current) => ({
                                  ...current,
                                  campaigns: current.campaigns.map((item) =>
                                    item.id !== campaign.id
                                      ? item
                                      : {
                                          ...item,
                                          assignments: item.assignments.map((candidate) =>
                                            candidate.id === assignment.id
                                              ? {
                                                  ...candidate,
                                                  endsAt: event.target.value ? new Date(event.target.value).toISOString() : null,
                                                }
                                              : candidate
                                          ),
                                        }
                                  ),
                                }))
                              }
                              disabled={busy}
                            />
                            <Button
                              loading={busy}
                              variant="outline"
                              disabled={busy}
                              onClick={() =>
                                runMutation(async () => {
                                  const response = await fetch(`/api/admin/tvs/assignments/${assignment.id}`, {
                                    method: "PATCH",
                                    headers: { "content-type": "application/json" },
                                    body: JSON.stringify({
                                      screenId: assignment.screenId,
                                      active: assignment.active,
                                      startsAt: assignment.startsAt ?? "",
                                      endsAt: assignment.endsAt ?? "",
                                    }),
                                  });
                                  if (!response.ok) {
                                    throw new Error(await readError(response));
                                  }
                                }, "Assignment updated")
                              }
                            >
                              Save
                            </Button>
                            <Button
                              loading={busy}
                              variant="destructive"
                              disabled={busy}
                              onClick={() =>
                                runMutation(async () => {
                                  const response = await fetch(`/api/admin/tvs/assignments/${assignment.id}`, {
                                    method: "DELETE",
                                  });
                                  if (!response.ok) {
                                    throw new Error(await readError(response));
                                  }
                                }, "Assignment deleted")
                              }
                            >
                              Delete
                            </Button>
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
                );
              })}
            </div>
          </section>
        </div>
      </section>

      {message ? (
        <p
          className={
            messageTone === "success"
              ? "rounded-2xl border border-primary/30 bg-primary/10 px-4 py-3 text-sm text-foreground"
              : "rounded-2xl border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-foreground"
          }
        >
          {message}
        </p>
      ) : null}
    </div>
  );
}
