"use client";

import { useState } from "react";

import { api, type GuestRead, type GuestWrite } from "@/lib/api/browser";

import Modal from "./Modal";
import { Button, ErrorNote, Field, inputClass } from "./ui";

/** The schema marks `group_tag` optional because the API defaults it. The form always
 * renders the control, so locally it is always present — which keeps the handlers free of
 * `?? []` noise on every read. */
type RequiredGuestWrite = GuestWrite & {
  group_tag: NonNullable<GuestWrite["group_tag"]>;
};

/**
 * Add or edit a guest on one event's list (task 3.5).
 *
 * There is no "invited to" checkbox group any more. A guest record belongs to exactly one
 * event (design D11), and that event is the screen the admin is already standing on — a
 * control here could only contradict it. Inviting the same person to a second ceremony is
 * adding them to that ceremony's list, which is a deliberate second act.
 *
 * Phone numbers are sent as typed. Normalisation to E.164 happens in the API with the
 * `phonenumbers` library, because a regex in the browser would accept `০১৭...` in Bangla
 * digits or `+88 01712-345678` and store three different strings for one person — which
 * is exactly what breaks duplicate detection later.
 */
export default function GuestForm({
  guest,
  eventId,
  eventName,
  onClose,
  onSaved,
}: {
  guest: GuestRead | null;
  /** The list being added to. Required when creating; an edit stays on its own event. */
  eventId: string;
  eventName?: string;
  onClose: () => void;
  /** Handed the saved record so a caller can act on the new id — the add flow uses it to
   * go straight to the guest's invitation link, which is the reason they were added. */
  onSaved: (saved: GuestRead) => void;
}) {
  const [form, setForm] = useState<RequiredGuestWrite>(() => ({
    full_name: guest?.full_name ?? "",
    phone: guest?.phone_e164 ?? null,
    whatsapp_phone: guest?.whatsapp_phone_e164 ?? null,
    email: guest?.email ?? null,
    side: guest?.side ?? "common",
    preferred_locale: guest?.preferred_locale ?? "en",
    preferred_channel: guest?.preferred_channel ?? "auto",
    group_tag: guest?.group_tag ?? [],
    max_guests: guest?.invitations[0]?.max_guests ?? 1,
    invitation_type: guest?.invitation_type ?? "single",
  }));
  const [tagText, setTagText] = useState((guest?.group_tag ?? []).join(", "));
  const [error, setError] = useState<unknown>(null);
  const [saving, setSaving] = useState(false);

  const set = <K extends keyof RequiredGuestWrite>(key: K, value: RequiredGuestWrite[K]) =>
    setForm((f) => ({ ...f, [key]: value }));

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    setSaving(true);
    setError(null);
    const payload: RequiredGuestWrite = {
      ...form,
      group_tag: tagText
        .split(",")
        .map((t) => t.trim())
        .filter(Boolean),
      // Empty strings would be stored as an address of "", which then looks deliverable
      // to the send screen. Null is the honest value for "we do not have one".
      email: form.email?.trim() || null,
      phone: form.phone?.trim() || null,
      whatsapp_phone: form.whatsapp_phone?.trim() || null,
    };
    try {
      onSaved(
        guest
          ? await api.updateGuest(guest.id, payload)
          : await api.createGuest(eventId, payload),
      );
    } catch (err) {
      setError(err);
      setSaving(false);
    }
  }

  return (
    <Modal title={guest ? `Edit ${guest.full_name}` : "Add guest"} onClose={onClose}>
      <form onSubmit={submit} className="space-y-4">
        <Field label="Full name">
          <input
            required
            value={form.full_name}
            onChange={(e) => set("full_name", e.target.value)}
            className={inputClass}
          />
        </Field>

        <div className="grid gap-4 sm:grid-cols-2">
          <Field label="Phone" hint="Any Bangladeshi format; stored as +880…">
            <input
              type="tel"
              value={form.phone ?? ""}
              onChange={(e) => set("phone", e.target.value)}
              placeholder="01712345678"
              className={inputClass}
            />
          </Field>
          <Field label="Email" hint="Without this they receive nothing in v1">
            <input
              type="email"
              value={form.email ?? ""}
              onChange={(e) => set("email", e.target.value)}
              className={inputClass}
            />
          </Field>
        </div>

        <div className="grid gap-4 sm:grid-cols-3">
          <Field label="Side">
            <select
              value={form.side}
              onChange={(e) => set("side", e.target.value as GuestWrite["side"])}
              className={inputClass}
            >
              <option value="bride">Bride</option>
              <option value="groom">Groom</option>
              <option value="common">Common</option>
            </select>
          </Field>
          <Field label="Language">
            <select
              value={form.preferred_locale}
              onChange={(e) =>
                set("preferred_locale", e.target.value as GuestWrite["preferred_locale"])
              }
              className={inputClass}
            >
              <option value="en">English</option>
              <option value="bn">বাংলা</option>
            </select>
          </Field>
          <Field label="Seats" hint="Ceiling for their party">
            <input
              type="number"
              min={1}
              max={20}
              value={form.max_guests}
              onChange={(e) => set("max_guests", Number(e.target.value))}
              className={inputClass}
            />
          </Field>
        </div>

        <div className="grid gap-4 sm:grid-cols-2">
          <Field label="Invitation type" hint="Chooses which greeting their invitation shows">
            <select
              value={form.invitation_type}
              onChange={(e) =>
                set("invitation_type", e.target.value as GuestWrite["invitation_type"])
              }
              className={inputClass}
            >
              <option value="single">Single</option>
              <option value="family">Family</option>
            </select>
          </Field>
        </div>

        {/* Warned, not corrected. "You and your family are invited" beside a one-seat
            ceiling is contradictory, but which half is wrong is the host's call — silently
            raising the seats would over-cater, silently switching to single would send the
            wrong greeting. */}
        {form.invitation_type === "family" && form.max_guests === 1 && (
          <p className="rounded-md bg-amber-50 px-3 py-2 text-xs text-amber-900">
            This guest is invited as a family but has only one seat. Their greeting will
            mention their family while the RSVP form allows one person.
          </p>
        )}

        <Field label="Tags" hint="Comma separated, e.g. family, office">
          <input
            value={tagText}
            onChange={(e) => setTagText(e.target.value)}
            className={inputClass}
          />
        </Field>

        {eventName && (
          <p className="text-xs text-stone-500">
            {guest ? "On the guest list for" : "Will be added to"}{" "}
            <span className="font-medium text-stone-700">{eventName}</span>. To invite
            someone to another ceremony, add them from that event.
          </p>
        )}

        <ErrorNote error={error} />

        <div className="flex justify-end gap-2 border-t border-stone-100 pt-4">
          <Button type="button" variant="secondary" onClick={onClose}>
            Cancel
          </Button>
          <Button type="submit" disabled={saving}>
            {saving ? "Saving…" : guest ? "Save changes" : "Add guest"}
          </Button>
        </div>
      </form>
    </Modal>
  );
}
