"use client";

import { useRef, useState, type FormEvent } from "react";
import { useRouter } from "next/navigation";
import { Loader2, Pencil } from "lucide-react";
import toast from "react-hot-toast";
import { FormField } from "@/components/shared/form-field";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Switch } from "@/components/ui/switch";
import { updateCustomer } from "./client-api";
import type { CustomerDetailRecord, CustomerWriteValues } from "./types";

function customerToDraft(customer: CustomerDetailRecord): CustomerWriteValues {
  return {
    firstName: customer.firstName,
    lastName: customer.lastName,
    email: customer.email,
    phone: customer.phone,
    active: customer.active,
    address: { ...customer.address },
    basicInformation: {
      ...customer.basicInformation,
      dateOfBirth: customer.basicInformation.dateOfBirth.slice(0, 10),
    },
  };
}

export function CustomerEditDialog({ customer }: { customer: CustomerDetailRecord }) {
  const router = useRouter();
  const [open, setOpen] = useState(false);
  const [draft, setDraft] = useState(() => customerToDraft(customer));
  const [saving, setSaving] = useState(false);
  const pending = useRef(false);

  function changeOpen(nextOpen: boolean) {
    if (pending.current) return;
    if (nextOpen) setDraft(customerToDraft(customer));
    setOpen(nextOpen);
  }

  async function submit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (pending.current) return;
    pending.current = true;
    setSaving(true);
    try {
      const message = await updateCustomer(customer.id, draft);
      setOpen(false);
      toast.success(message);
      router.refresh();
    } catch (error) {
      toast.error(error instanceof Error ? error.message : "Unable to update the customer. Please try again.");
    } finally {
      pending.current = false;
      setSaving(false);
    }
  }

  return (
    <>
      <Button type="button" variant="outline" onClick={() => changeOpen(true)}>
        <Pencil aria-hidden="true" />
        Edit profile
      </Button>
      <Dialog open={open} onOpenChange={changeOpen}>
        <DialogContent className="flex max-h-[92dvh] flex-col gap-0 overflow-hidden p-0 sm:max-w-2xl" showCloseButton={!saving}>
          <DialogHeader className="shrink-0 border-b px-6 py-5 pr-14">
            <DialogTitle>Edit customer profile</DialogTitle>
            <DialogDescription>Update the customer’s personal and address information.</DialogDescription>
          </DialogHeader>
          <form className="flex min-h-0 flex-1 flex-col" onSubmit={submit}>
            <div className="min-h-0 flex-1 space-y-6 overflow-y-auto px-6 py-5">
              <fieldset disabled={saving} className="space-y-6 disabled:opacity-70">
                <section className="space-y-4">
                  <h3 className="font-medium">Personal information</h3>
                  <div className="grid gap-4 sm:grid-cols-2">
                    <FormField
                      name="firstName"
                      label="First name"
                      autoComplete="given-name"
                      value={draft.firstName}
                      onChange={(event) => setDraft((current) => ({ ...current, firstName: event.target.value }))}
                      required
                      maxLength={100}
                    />
                    <FormField
                      name="lastName"
                      label="Last name"
                      autoComplete="family-name"
                      value={draft.lastName}
                      onChange={(event) => setDraft((current) => ({ ...current, lastName: event.target.value }))}
                      required
                      maxLength={100}
                    />
                    <FormField
                      name="email"
                      label="Email address"
                      type="email"
                      autoComplete="email"
                      value={draft.email}
                      onChange={(event) => setDraft((current) => ({ ...current, email: event.target.value }))}
                      required
                      maxLength={254}
                    />
                    <FormField
                      name="phone"
                      label="Phone"
                      type="tel"
                      autoComplete="tel"
                      value={draft.phone}
                      onChange={(event) => setDraft((current) => ({ ...current, phone: event.target.value }))}
                      required
                      maxLength={40}
                    />
                    <FormField
                      name="dateOfBirth"
                      label="Date of birth"
                      type="date"
                      value={draft.basicInformation.dateOfBirth}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        basicInformation: { ...current.basicInformation, dateOfBirth: event.target.value },
                      }))}
                    />
                    <FormField
                      name="placeOfBirth"
                      label="Place of birth"
                      value={draft.basicInformation.placeOfBirth}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        basicInformation: { ...current.basicInformation, placeOfBirth: event.target.value },
                      }))}
                      maxLength={200}
                    />
                    <FormField
                      name="gender"
                      label="Gender"
                      value={draft.basicInformation.gender}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        basicInformation: { ...current.basicInformation, gender: event.target.value },
                      }))}
                      maxLength={50}
                    />
                    <div className="flex items-center justify-between rounded-lg border border-border px-4 py-3">
                      <div>
                        <p className="text-sm font-medium">Account status</p>
                        <p className="mt-1 text-xs text-muted-foreground">{draft.active ? "Active" : "Inactive"}</p>
                      </div>
                      <Switch
                        aria-label="Customer active status"
                        checked={draft.active}
                        onCheckedChange={(active) => setDraft((current) => ({ ...current, active }))}
                      />
                    </div>
                  </div>
                </section>

                <section className="space-y-4">
                  <h3 className="font-medium">Address information</h3>
                  <div className="grid gap-4 sm:grid-cols-2">
                    <FormField
                      className="sm:col-span-2"
                      name="streetAndNumber"
                      label="Street address"
                      autoComplete="street-address"
                      value={draft.address.streetAndNumber}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        address: { ...current.address, streetAndNumber: event.target.value },
                      }))}
                      maxLength={200}
                    />
                    <FormField
                      name="city"
                      label="City"
                      autoComplete="address-level2"
                      value={draft.address.city}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        address: { ...current.address, city: event.target.value },
                      }))}
                      maxLength={200}
                    />
                    <FormField
                      name="state"
                      label="State / province"
                      autoComplete="address-level1"
                      value={draft.address.state}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        address: { ...current.address, state: event.target.value },
                      }))}
                      maxLength={200}
                    />
                    <FormField
                      name="country"
                      label="Country"
                      autoComplete="country-name"
                      value={draft.address.country}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        address: { ...current.address, country: event.target.value },
                      }))}
                      maxLength={200}
                    />
                    <FormField
                      name="postalCode"
                      label="Postal code"
                      autoComplete="postal-code"
                      value={draft.address.postalCode}
                      onChange={(event) => setDraft((current) => ({
                        ...current,
                        address: { ...current.address, postalCode: event.target.value },
                      }))}
                      maxLength={200}
                    />
                  </div>
                </section>
              </fieldset>
            </div>
            <DialogFooter className="mx-0 mb-0 shrink-0 rounded-b-xl border-t px-6 py-4">
              <Button type="button" variant="outline" disabled={saving} onClick={() => changeOpen(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={saving} aria-busy={saving}>
                {saving && <Loader2 aria-hidden="true" className="animate-spin motion-reduce:animate-none" />}
                {saving ? "Saving…" : "Save changes"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </>
  );
}
