"use client";

import { useMemo, useState } from "react";
import type { FormEvent, ReactNode } from "react";

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import type { CustomerContact, CustomerContactPayload } from "@/types/customer";

const emptyContact: CustomerContactPayload = {
  first_name: "",
  last_name: "",
  position: "",
  email: "",
  phone: "",
  mobile: "",
  is_primary: false,
  notes: "",
};

type Props = {
  open: boolean;
  contact?: CustomerContact | null;
  pending?: boolean;
  serverError?: string;
  onOpenChange: (open: boolean) => void;
  onSubmit: (payload: CustomerContactPayload) => Promise<void>;
};

export default function CustomerContactFormDialog({
  open,
  contact,
  pending = false,
  serverError,
  onOpenChange,
  onSubmit,
}: Props) {
  const initialForm = contact
    ? {
        first_name: contact.first_name,
        last_name: contact.last_name,
        position: contact.position,
        email: contact.email,
        phone: contact.phone,
        mobile: contact.mobile,
        is_primary: contact.is_primary,
        notes: contact.notes,
      }
    : emptyContact;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-2xl">
        {open && (
          <ContactForm
            key={contact?.id ?? "new"}
            initialForm={initialForm}
            pending={pending}
            serverError={serverError}
            onCancel={() => onOpenChange(false)}
            onSubmit={onSubmit}
          />
        )}
      </DialogContent>
    </Dialog>
  );
}

function ContactForm({
  initialForm,
  pending,
  serverError,
  onCancel,
  onSubmit,
}: {
  initialForm: CustomerContactPayload;
  pending: boolean;
  serverError?: string;
  onCancel: () => void;
  onSubmit: (payload: CustomerContactPayload) => Promise<void>;
}) {
  const [form, setForm] = useState<CustomerContactPayload>(initialForm);
  const errors = useMemo(() => ({
    name: form.first_name.trim() || form.last_name.trim()
      ? ""
      : "Vorname oder Nachname erforderlich",
    email: !form.email || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)
      ? ""
      : "Gültige E-Mail erforderlich",
  }), [form.email, form.first_name, form.last_name]);
  const valid = Object.values(errors).every((error) => !error);

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

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!valid) {
      return;
    }

    await onSubmit({
      ...form,
      email: form.email?.trim() || null,
    });
  }

  return (
    <form onSubmit={handleSubmit} className="space-y-5">
      <DialogHeader>
        <DialogTitle>Ansprechpartner {initialForm.first_name || initialForm.last_name ? "bearbeiten" : "hinzufügen"}</DialogTitle>
        <DialogDescription>Ansprechpartnerdaten und Primärkennzeichnung pflegen.</DialogDescription>
      </DialogHeader>

      <div className="grid gap-4 sm:grid-cols-2">
        <Field label="Vorname" error={errors.name}>
          <Input value={form.first_name} onChange={(event) => update("first_name", event.target.value)} />
        </Field>
        <Field label="Nachname">
          <Input value={form.last_name} onChange={(event) => update("last_name", event.target.value)} />
        </Field>
        <Field label="Position">
          <Input value={form.position} onChange={(event) => update("position", event.target.value)} />
        </Field>
        <Field label="E-Mail" error={errors.email}>
          <Input type="email" value={form.email ?? ""} onChange={(event) => update("email", event.target.value)} />
        </Field>
        <Field label="Telefon">
          <Input value={form.phone} onChange={(event) => update("phone", event.target.value)} />
        </Field>
        <Field label="Mobil">
          <Input value={form.mobile} onChange={(event) => update("mobile", event.target.value)} />
        </Field>
        <label className="flex h-8 items-center gap-2 rounded-lg border px-2.5 text-sm">
          <input
            type="checkbox"
            checked={form.is_primary}
            onChange={(event) => update("is_primary", event.target.checked)}
          />
          Primärer Ansprechpartner
        </label>
      </div>

      <Field label="Notizen">
        <Input value={form.notes} onChange={(event) => update("notes", event.target.value)} />
      </Field>

      {serverError && <p className="text-sm text-red-600">{serverError}</p>}

      <DialogFooter>
        <Button type="button" variant="outline" disabled={pending} onClick={onCancel}>
          Abbrechen
        </Button>
        <Button type="submit" disabled={!valid || pending}>
          {pending ? "Speichern..." : "Speichern"}
        </Button>
      </DialogFooter>
    </form>
  );
}

function Field({
  label,
  error,
  children,
}: {
  label: string;
  error?: string;
  children: ReactNode;
}) {
  return (
    <div className="space-y-1.5">
      <Label>{label}</Label>
      {children}
      {error && <p className="text-xs text-red-600">{error}</p>}
    </div>
  );
}
