"use client";

import { useState, type FormEvent } from "react";
import { Button } from "@/components/ui/button";
import { FormField, SelectField } from "@/components/shared/form-field";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Switch } from "@/components/ui/switch";
import type {
  RfidCardFormValues,
  RfidCardRecord,
  RfidFormOptions,
  RfidGroupFormValues,
  RfidGroupRecord,
} from "./types";

export function RfidCardEditorDialog({
  open,
  onOpenChange,
  record,
  groups,
  options,
  onSave,
}: {
  open: boolean;
  onOpenChange(open: boolean): void;
  record?: RfidCardRecord;
  groups: RfidGroupRecord[];
  options: RfidFormOptions;
  onSave(values: RfidCardFormValues): Promise<boolean>;
}) {
  const [saving, setSaving] = useState(false);
  const [draft, setDraft] = useState<RfidCardFormValues>(() => ({
    organizationCode: record?.organizationCode ?? options.organizations[0]?.code ?? "",
    userId: record?.userId ?? options.users[0]?.id ?? "",
    name: record?.name ?? "",
    description: record?.description ?? "",
    active: record?.active ?? true,
    rfidCode: record?.rfidCode ?? "",
    groupId: record?.groupId ?? "",
    expiresAt: record?.expiresAt ?? "",
  }));
  const availableGroups = groups.filter(
    (group) => group.organizationCode === draft.organizationCode,
  );

  function update<K extends keyof RfidCardFormValues>(
    key: K,
    value: RfidCardFormValues[K],
  ) {
    setDraft((current) => ({ ...current, [key]: value }));
  }

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const saved = await onSave({
        ...draft,
        groupId: draft.groupId || undefined,
        expiresAt: draft.expiresAt || undefined,
      });
      if (saved) onOpenChange(false);
    } finally {
      setSaving(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90dvh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>{record ? "Edit RFID" : "Add RFID"}</DialogTitle>
          <DialogDescription>
            {record ? "Update this RFID card." : "Assign an RFID card to an EV driver."}
          </DialogDescription>
        </DialogHeader>
        <form className="space-y-5" onSubmit={submit}>
          {!record && (
            <div className="grid gap-4 sm:grid-cols-2">
              {options.defaultOrganizationCode ? (
                <div className="space-y-2">
                  <span className="text-sm font-medium">Organization</span>
                  <div className="flex h-11 items-center rounded-lg border border-input bg-muted/40 px-3 text-sm text-muted-foreground">
                    {options.organizations.find(({ code }) => code === options.defaultOrganizationCode)?.name ?? options.defaultOrganizationCode}
                  </div>
                </div>
              ) : (
                <SelectField
                  name="organizationCode"
                  label="Organization"
                  required
                  value={draft.organizationCode}
                  onChange={(event) => {
                    update("organizationCode", event.target.value);
                    update("groupId", "");
                  }}
                  options={options.organizations.map(({ code, name }) => ({ value: code, label: name }))}
                />
              )}
              <SelectField
                name="userId"
                label="User"
                required
                value={draft.userId}
                onChange={(event) => update("userId", event.target.value)}
                options={options.users.map(({ id, name }) => ({
                  value: id,
                  label: name,
                }))}
              />
              <FormField
                name="name"
                label="Name"
                required
                value={draft.name}
                onChange={(event) => update("name", event.target.value)}
                placeholder="Enter RFID name"
              />
              <FormField
                name="rfidCode"
                label="RFID code"
                required
                value={draft.rfidCode}
                onChange={(event) => update("rfidCode", event.target.value)}
                placeholder="Enter card code"
              />
              <SelectField
                name="groupId"
                label="Parent RFID / Group"
                value={draft.groupId ?? ""}
                onChange={(event) => update("groupId", event.target.value)}
                options={[
                  { value: "", label: "No parent group" },
                  ...availableGroups.map((group) => ({
                    value: group.id,
                    label: group.groupName,
                  })),
                ]}
              />
              <FormField
                name="expiresAt"
                label="Expiry date"
                type="date"
                value={draft.expiresAt ?? ""}
                onChange={(event) => update("expiresAt", event.target.value)}
              />
              <div className="sm:col-span-2">
                <FormField
                  name="description"
                  label="Description"
                  value={draft.description}
                  onChange={(event) => update("description", event.target.value)}
                  placeholder="Optional description"
                />
              </div>
            </div>
          )}
          {record && (
            <div className="space-y-4">
              <FormField
                name="name"
                label="Name"
                required
                value={draft.name}
                onChange={(event) => update("name", event.target.value)}
              />
              <FormField
                name="rfidCode"
                label="RFID code"
                required
                value={draft.rfidCode}
                onChange={(event) => update("rfidCode", event.target.value)}
              />
            </div>
          )}
          <label className="flex items-center justify-between gap-4 rounded-xl border border-border px-4 py-3">
            <span>
              <span className="block font-medium">Active</span>
              <span className="text-sm text-muted-foreground">
                Allow this card to be used for access.
              </span>
            </span>
            <Switch
              checked={draft.active}
              onCheckedChange={(checked) => update("active", checked === true)}
              aria-label="RFID active status"
            />
          </label>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
          <Button type="submit" disabled={saving}>{saving ? "Saving…" : record ? "Save changes" : "Create RFID"}</Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export function RfidGroupEditorDialog({
  open,
  onOpenChange,
  record,
  organizations,
  defaultOrganizationCode,
  onSave,
}: {
  open: boolean;
  onOpenChange(open: boolean): void;
  record?: RfidGroupRecord;
  organizations: RfidFormOptions["organizations"];
  defaultOrganizationCode: string;
  onSave(values: RfidGroupFormValues): Promise<boolean>;
}) {
  const [saving, setSaving] = useState(false);
  const [draft, setDraft] = useState<RfidGroupFormValues>(() => ({
    organizationCode: record?.organizationCode ?? organizations[0]?.code ?? "",
    groupName: record?.groupName ?? "",
    description: record?.description ?? "",
    active: record?.active ?? true,
  }));

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const saved = await onSave(draft);
      if (saved) onOpenChange(false);
    } finally {
      setSaving(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{record ? "Edit Group RFID" : "Add Group RFID"}</DialogTitle>
          <DialogDescription>
            {record ? "Update this RFID group." : "Create a group for RFID cards."}
          </DialogDescription>
        </DialogHeader>
        <form className="space-y-5" onSubmit={submit}>
          {!record && defaultOrganizationCode ? (
            <div className="space-y-2">
              <span className="text-sm font-medium">Organization</span>
              <div className="flex h-11 items-center rounded-lg border border-input bg-muted/40 px-3 text-sm text-muted-foreground">
                {organizations.find(({ code }) => code === defaultOrganizationCode)?.name ?? defaultOrganizationCode}
              </div>
            </div>
          ) : !record && organizations.length > 0 ? (
            <SelectField
              name="organizationCode"
              label="Organization"
              required
              value={draft.organizationCode}
              onChange={(event) =>
                setDraft((current) => ({ ...current, organizationCode: event.target.value }))
              }
              options={organizations.map(({ code, name }) => ({ value: code, label: name }))}
            />
          ) : null}
          <FormField
            name="groupName"
            label="Group name"
            required
            value={draft.groupName}
            onChange={(event) =>
              setDraft((current) => ({ ...current, groupName: event.target.value }))
            }
            placeholder="Enter group name"
          />
          <FormField
            name="description"
            label="Description"
            value={draft.description}
            onChange={(event) =>
              setDraft((current) => ({ ...current, description: event.target.value }))
            }
            placeholder="Optional description"
          />
          <label className="flex items-center justify-between gap-4 rounded-xl border border-border px-4 py-3">
            <span>
              <span className="block font-medium">Active</span>
              <span className="text-sm text-muted-foreground">
                Allow cards in this group to be used.
              </span>
            </span>
            <Switch
              checked={draft.active}
              onCheckedChange={(checked) =>
                setDraft((current) => ({ ...current, active: checked === true }))
              }
              aria-label="Group RFID active status"
            />
          </label>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button type="submit" disabled={saving}>{saving ? "Saving…" : record ? "Save changes" : "Create group"}</Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

export function RfidDeleteDialog({
  open,
  onOpenChange,
  itemName,
  itemType,
  onConfirm,
}: {
  open: boolean;
  onOpenChange(open: boolean): void;
  itemName: string;
  itemType: "RFID card" | "RFID group";
  onConfirm(): Promise<boolean>;
}) {
  const [deleting, setDeleting] = useState(false);
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Delete {itemType}?</DialogTitle>
          <DialogDescription>
            Delete <span className="font-medium text-foreground">{itemName}</span>? This action will update server data.
          </DialogDescription>
        </DialogHeader>
        <DialogFooter>
          <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            type="button"
            variant="destructive"
            disabled={deleting}
            onClick={async () => {
              setDeleting(true);
              try {
                if (await onConfirm()) onOpenChange(false);
              } finally {
                setDeleting(false);
              }
            }}
          >
            {deleting ? "Deleting…" : "Delete"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
