"use client";

import React, { useEffect, useMemo, useRef, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import { apiFetch, fetchAllUsers } from "@/lib/api";
import { scoreUser } from "@/lib/fuzzyMatch";
import { useDismissingState } from "@/hooks/useDismissingState";
import { UserPlus, CreditCard } from "lucide-react";

// ─── Pricing helpers ─────────────────────────────────────────────────────────

function effectiveOptionUnit(opt: any): number {
  const base = opt.price || 0;
  const tiers = (Array.isArray(opt.earlyBirdTiers) ? opt.earlyBirdTiers : []).filter((t: any) => !t.variantId);
  if (tiers.length === 0) return base;
  const now = new Date();
  const applicable = tiers
    .map((t: any) => ({ ...t, deadline: new Date(t.deadline) }))
    .filter((t: any) => now < t.deadline)
    .sort((a: any, b: any) => a.deadline - b.deadline || (a.order || 0) - (b.order || 0) || a.price - b.price);
  return applicable.length > 0 ? applicable[0].price : base;
}

function effectiveVariantUnit(opt: any, variant: any): number {
  const base = variant.price !== null && variant.price !== undefined ? variant.price : opt.price || 0;
  const allTiers = Array.isArray(opt.earlyBirdTiers) ? opt.earlyBirdTiers : [];
  const variantTiers = allTiers.filter((t: any) => t.variantId === variant.id);
  const tiers = variantTiers.length > 0 ? variantTiers : allTiers.filter((t: any) => !t.variantId);
  if (tiers.length === 0) return base;
  const now = new Date();
  const applicable = tiers
    .map((t: any) => ({ ...t, deadline: new Date(t.deadline) }))
    .filter((t: any) => now < t.deadline)
    .sort((a: any, b: any) => a.deadline - b.deadline || (a.order || 0) - (b.order || 0) || a.price - b.price);
  return applicable.length > 0 ? applicable[0].price : base;
}

function fmtPrice(n: number) {
  return n === 0 ? "Free" : `R ${n.toFixed(2)}`;
}

// Effective unit price for an existing registration option (as returned by /api/registrations).
// Prefers priceSnapshot (authoritative price captured at registration time) and only falls
// back to a live early-bird calculation for legacy rows without a snapshot.
function optionUnitPrice(opt: any): number {
  if (opt.priceSnapshot !== null && opt.priceSnapshot !== undefined) {
    return Number(opt.priceSnapshot);
  }
  const eo = opt.eventOption;
  if (opt.variant) return effectiveVariantUnit(eo, opt.variant);
  return effectiveOptionUnit(eo);
}

// ─── Component ───────────────────────────────────────────────────────────────

export default function ManualRegistrationPage() {
  const { user, loading, token } = useAuth();
  const router = useRouter();

  const canView = useMemo(() => {
    const role = user?.role;
    return role === "admin" || role === "supervisor";
  }, [user]);

  useEffect(() => {
    if (loading) return;
    if (!user) router.replace("/login");
  }, [user, loading, router]);

  const [events, setEvents] = useState<any[]>([]);
  const [selectedEventId, setSelectedEventId] = useState<string>("");
  const [options, setOptions] = useState<any[]>([]);

  // All system users for fuzzy lookup
  const [allUsers, setAllUsers] = useState<any[]>([]);

  const [guest, setGuest] = useState({ name: "", email: "", phoneNumber: "" });
  const [registerAsGuest, setRegisterAsGuest] = useState(false);
  const [notifPref, setNotifPref] = useState<"email" | "whatsapp" | "both">("email");
  const [quantities, setQuantities] = useState<Record<string, number>>({});

  // User search state
  const [userQuery, setUserQuery] = useState("");
  const [dropdownOpen, setDropdownOpen] = useState(false);
  const searchRef = useRef<HTMLDivElement>(null);

  const [submitting, setSubmitting] = useState(false);
  const [message, setMessage] = useDismissingState<string | null>(null);
  const [error, setError] = useDismissingState<string | null>(null);

  // ── Tabs ──────────────────────────────────────────────────────────────────
  const [tab, setTab] = useState<"register" | "payment">("register");

  // ── Record Payment tab state ─────────────────────────────────────────────
  const [allRegistrations, setAllRegistrations] = useState<any[]>([]);
  const [payUserId, setPayUserId] = useState<string>("");
  const [payUserQuery, setPayUserQuery] = useState("");
  const [payDropdownOpen, setPayDropdownOpen] = useState(false);
  const paySearchRef = useRef<HTMLDivElement>(null);
  const [payRegistrationId, setPayRegistrationId] = useState<string>("");
  const [payAmount, setPayAmount] = useState<string>("");
  const [payMethod, setPayMethod] = useState<string>("cash");
  const [payPaidAtLocal, setPayPaidAtLocal] = useState<string>("");
  const [paySubmitting, setPaySubmitting] = useState(false);
  const [payMessage, setPayMessage] = useDismissingState<string | null>(null);
  const [payError, setPayError] = useDismissingState<string | null>(null);

  // Load all users for client-side fuzzy matching
  useEffect(() => {
    if (!token) return;
    fetchAllUsers(token)
      .then(users => setAllUsers(users))
      .catch(() => {});
  }, [token]);

  // Load all registrations for the Record Payment tab (embeds payments, so outstanding
  // balances can be computed without a per-registration fetch loop).
  useEffect(() => {
    if (!token) return;
    apiFetch<any[]>("/api/registrations", { authToken: token })
      .then(regs => setAllRegistrations(Array.isArray(regs) ? regs : []))
      .catch(() => {});
  }, [token]);

  const regOutstanding = useMemo(() => {
    const map: Record<string, { totalDue: number; totalPaid: number; outstanding: number }> = {};
    for (const r of allRegistrations) {
      const totalDue = (r.registrationOptions || []).reduce((sum: number, opt: any) => sum + optionUnitPrice(opt) * (opt.quantity || 0), 0);
      const totalPaid = (r.payments || []).reduce((s: number, p: any) => s + (p.amount || 0), 0);
      map[r.id] = { totalDue, totalPaid, outstanding: Math.max(0, totalDue - totalPaid) };
    }
    return map;
  }, [allRegistrations]);

  const payMatchedUsers = useMemo(() => {
    if (payUserQuery.trim().length < 2) return [];
    return allUsers
      .map(u => ({ u, score: scoreUser(u, payUserQuery) }))
      .filter(x => x.score >= 0.45)
      .sort((a, b) => b.score - a.score)
      .slice(0, 6)
      .map(x => x.u);
  }, [payUserQuery, allUsers]);

  const selectPayUser = (u: any) => {
    setPayUserId(u.id);
    setPayUserQuery(u.name || "");
    setPayDropdownOpen(false);
    setPayRegistrationId("");
  };

  // Close payment-tab user dropdown on outside click
  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (paySearchRef.current && !paySearchRef.current.contains(e.target as Node)) {
        setPayDropdownOpen(false);
      }
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  const regsForPayUser = useMemo(() => {
    if (!payUserId) return [];
    return allRegistrations
      .filter((r: any) => String(r.userId || r.user?.id) === String(payUserId))
      .filter((r: any) => (regOutstanding[r.id]?.outstanding ?? 0) > 0.000001)
      .sort((a: any, b: any) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
  }, [allRegistrations, payUserId, regOutstanding]);

  const createManualPayment = async () => {
    if (!token) return;
    setPayError(null);
    setPayMessage(null);
    const amt = parseFloat(payAmount || "0");
    if (!amt || amt <= 0) { setPayError("Enter a valid amount"); return; }
    if (!payRegistrationId) { setPayError("Please select a registration"); return; }
    try {
      setPaySubmitting(true);
      await apiFetch<any>("/api/payments", {
        method: "POST",
        authToken: token,
        body: {
          amount: amt,
          method: payMethod,
          userId: payUserId || undefined,
          registrationId: payRegistrationId,
          isDonation: false,
          paidAt: payPaidAtLocal ? new Date(payPaidAtLocal).toISOString() : undefined,
        }
      });
      setPayMessage(`Payment recorded (R ${amt.toFixed(2)}).`);
      setPayAmount("");
      setPayPaidAtLocal("");
      // Refresh registrations so the displayed outstanding balance updates
      try {
        const regs = await apiFetch<any[]>("/api/registrations", { authToken: token });
        setAllRegistrations(Array.isArray(regs) ? regs : []);
      } catch {}
    } catch (e: any) {
      setPayError(e?.message || "Failed to record payment");
    } finally {
      setPaySubmitting(false);
    }
  };

  // Fuzzy match results (top 6, score threshold 0.45)
  const matchedUsers = useMemo(() => {
    if (userQuery.trim().length < 2) return [];
    return allUsers
      .map(u => ({ u, score: scoreUser(u, userQuery) }))
      .filter(x => x.score >= 0.45)
      .sort((a, b) => b.score - a.score)
      .slice(0, 6)
      .map(x => x.u);
  }, [userQuery, allUsers]);

  const selectUser = (u: any) => {
    setGuest({ name: u.name || "", email: u.email || "", phoneNumber: u.phoneNumber || "" });
    setUserQuery(u.name || "");
    setDropdownOpen(false);
  };

  // Close dropdown on outside click
  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (searchRef.current && !searchRef.current.contains(e.target as Node)) {
        setDropdownOpen(false);
      }
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  useEffect(() => {
    (async () => {
      try {
        if (!token) return;
        const evs = await apiFetch<any[]>("/api/events/all", { authToken: token });
        const now = Date.now();
        const active = (evs || []).filter(ev => {
          const t = new Date(ev.endDate).getTime();
          // Manual registration is rejected server-side for closed (cashed-up) events —
          // don't offer them here even in the rare case one is closed before it ends.
          return !isNaN(t) && t > now && ev.cashupStatus !== 'closed';
        });
        active.sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime());
        setEvents(active);
      } catch (e: any) {
        // ignore
      }
    })();
  }, [token]);

  useEffect(() => {
    const ev = events.find(e => e.id === selectedEventId);
    if (ev) {
      const opts = ev.options || ev.eventOptions || [];
      setOptions(opts);
      const map: Record<string, number> = {};
      opts.forEach((o: any) => {
        if ((o.variants || []).length > 0) {
          (o.variants as any[]).forEach(v => { map[`${o.id}::${v.id}`] = 0; });
        } else {
          map[o.id] = 0;
        }
      });
      setQuantities(map);
    } else {
      setOptions([]);
      setQuantities({});
    }
  }, [selectedEventId, events]);

  const totalDue = useMemo(() => {
    return options.reduce((sum, o) => {
      if ((o.variants || []).length > 0) {
        return sum + (o.variants as any[]).reduce((vs: number, v: any) => vs + (quantities[`${o.id}::${v.id}`] || 0) * effectiveVariantUnit(o, v), 0);
      }
      return sum + (quantities[o.id] || 0) * effectiveOptionUnit(o);
    }, 0);
  }, [options, quantities]);

  const submit = async () => {
    if (!token) return;
    setError(null);
    setMessage(null);
    if (!selectedEventId) { setError("Please select an event."); return; }
    if (!guest.name || (!registerAsGuest && !guest.email)) { setError("Guest name and email are required."); return; }
    const opts = Object.entries(quantities)
      .filter(([, qty]) => qty > 0)
      .map(([key, quantity]) => {
        const [eventOptionId, variantId] = key.split("::");
        return { eventOptionId, quantity, ...(variantId ? { variantId } : {}) };
      });
    if (opts.length === 0) { setError("Please select at least one ticket option."); return; }

    try {
      setSubmitting(true);
      const hasEmail = !!guest.email.trim();
      const hasPhone = !!guest.phoneNumber.trim();
      const resolvedPref = hasEmail && hasPhone ? notifPref : hasPhone ? "whatsapp" : "email";
      const res = await apiFetch<any>("/api/registrations/manual", {
        method: "POST",
        authToken: token,
        body: {
          eventId: selectedEventId,
          options: opts,
          user: guest,
          guestOnly: registerAsGuest,
          notificationPreference: resolvedPref,
        }
      });
      setMessage("Manual registration created successfully.");

      // Pre-load the Record Payment tab with this registration so it's ready to go the
      // moment a supervisor clicks over — the tab itself is never switched to automatically.
      setAllRegistrations(prev => [res, ...prev.filter((r: any) => r.id !== res.id)]);
      setPayUserId(res.userId || res.user?.id || "");
      setPayUserQuery(res.user?.name || guest.name || "");
      setPayRegistrationId(res.id);
      setPayDropdownOpen(false);

      // Reset guest/ticket fields so the next registration starts from a clean slate
      setGuest({ name: "", email: "", phoneNumber: "" });
      setRegisterAsGuest(false);
      setNotifPref("email");
      setUserQuery("");
      setDropdownOpen(false);
      setQuantities(prev => Object.fromEntries(Object.keys(prev).map(k => [k, 0])));
    } catch (e: any) {
      setError(e?.message || "Failed to create manual registration");
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <div className="max-w-4xl mx-auto w-full p-6">
      <div className="flex items-center justify-between mb-4 flex-wrap gap-3">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl bg-brand-50 flex items-center justify-center shrink-0">
            <UserPlus className="w-5 h-5 text-brand-600" />
          </div>
          <h1 className="text-2xl font-semibold text-gray-900">Manual registration</h1>
        </div>
        <button className="px-3 py-1.5 text-sm rounded-lg bg-gray-100 hover:bg-gray-200 text-gray-800 shadow-sm" onClick={() => router.push('/dashboard')}>Back</button>
      </div>

      {!canView && (
        <div className="p-3 border rounded bg-yellow-50 text-yellow-800 text-sm mb-4">
          You need supervisor or admin access to use this page.
        </div>
      )}

      <div className="mb-4 flex items-center gap-2">
        <label className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded border ${tab === 'register' ? 'bg-brand-600 text-white border-brand-600' : 'bg-white text-gray-800 border-gray-200'} cursor-pointer`}>
          <input type="radio" name="tab" value="register" className="hidden" checked={tab==='register'} onChange={() => setTab('register')} />
          <UserPlus className="w-4 h-4" />
          Register
        </label>
        <label className={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm rounded border ${tab === 'payment' ? 'bg-brand-600 text-white border-brand-600' : 'bg-white text-gray-800 border-gray-200'} cursor-pointer`}>
          <input type="radio" name="tab" value="payment" className="hidden" checked={tab==='payment'} onChange={() => setTab('payment')} />
          <CreditCard className="w-4 h-4" />
          Record Payment
        </label>
      </div>

      {tab === 'register' && (
      <>
      {message && <div className="p-3 mb-3 border rounded bg-emerald-50 text-emerald-800 text-sm">{message}</div>}
      {error && <div className="p-3 mb-3 border rounded bg-red-50 text-red-700 text-sm">{error}</div>}

      <div className="grid md:grid-cols-2 gap-6">
        <div className="border rounded-xl p-4 bg-white shadow-sm">
          <div className="text-lg font-semibold mb-3">1) Choose event</div>
          <select className="w-full border rounded px-3 py-2 text-sm" value={selectedEventId} onChange={e => setSelectedEventId(e.target.value)}>
            <option value="">Select an event…</option>
            {events.map(ev => (
              <option key={ev.id} value={ev.id}>{ev.title}</option>
            ))}
          </select>
          {selectedEventId && (
            <div className="mt-3 text-xs text-gray-600">
              {(() => {
                const ev = events.find(e => e.id === selectedEventId);
                if (!ev) return null;
                return <>
                  <div>{new Date(ev.startDate).toLocaleString()} - {new Date(ev.endDate).toLocaleString()}</div>
                </>;
              })()}
            </div>
          )}
        </div>

        <div className="border rounded-xl p-4 bg-white shadow-sm">
          <div className="text-lg font-semibold mb-3">2) Guest details</div>

          {/* ── User lookup ─────────────────────────────────────────── */}
          <div ref={searchRef} className="relative mb-4">
            <label className="block text-xs font-medium text-gray-500 mb-1">
              Search existing user <span className="font-normal">(name, email or phone)</span>
            </label>
            <input
              className="w-full border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
              placeholder="Start typing to find a user…"
              value={userQuery}
              autoComplete="off"
              onChange={e => { setUserQuery(e.target.value); setDropdownOpen(true); }}
              onFocus={() => { if (userQuery.length >= 2) setDropdownOpen(true); }}
            />

            {dropdownOpen && userQuery.trim().length >= 2 && (
              <div className="absolute z-30 top-full left-0 right-0 mt-1 bg-white border border-gray-200 rounded-xl shadow-lg overflow-hidden">
                {matchedUsers.length > 0 ? (
                  <>
                    <div className="px-3 py-1.5 text-[11px] text-gray-400 bg-gray-50 border-b">
                      {matchedUsers.length} match{matchedUsers.length !== 1 ? "es" : ""} — click to auto-fill
                    </div>
                    {matchedUsers.map(u => (
                      <button
                        key={u.id}
                        type="button"
                        className="w-full text-left px-3 py-2.5 hover:bg-brand-50 border-b border-gray-100 last:border-b-0 transition-colors"
                        onClick={() => selectUser(u)}
                      >
                        <div className="text-sm font-medium text-gray-900">{u.name}</div>
                        <div className="text-xs text-gray-500 mt-0.5 flex gap-2 flex-wrap">
                          {u.email && <span>{u.email}</span>}
                          {u.phoneNumber && <span>· {u.phoneNumber}</span>}
                        </div>
                      </button>
                    ))}
                  </>
                ) : (
                  <div className="px-3 py-3 text-sm text-gray-500 italic">
                    No matching users found — fill in details below manually.
                  </div>
                )}
              </div>
            )}
          </div>

          <div className="border-t pt-3 mb-3">
            <div className="flex items-center gap-2">
              <input id="registerAsGuest" type="checkbox" checked={registerAsGuest} onChange={e => setRegisterAsGuest(e.target.checked)} />
              <label htmlFor="registerAsGuest" className="text-sm text-gray-700">Guest (do not link to an existing account)</label>
            </div>
          </div>

          <div className="grid gap-2">
            <input
              className="border rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
              placeholder="Full name"
              value={guest.name}
              onChange={e => setGuest({ ...guest, name: e.target.value })}
            />
            <input
              className="border rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
              placeholder={registerAsGuest ? "Email (optional for guest)" : "Email"}
              type="email"
              value={guest.email}
              onChange={e => setGuest({ ...guest, email: e.target.value })}
              required={!registerAsGuest}
            />
            <input
              className="border rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
              placeholder="Phone (optional)"
              value={guest.phoneNumber}
              onChange={e => {
                const v = e.target.value;
                setGuest({ ...guest, phoneNumber: v });
                if (v.trim() && !guest.email.trim()) setNotifPref("whatsapp");
                else if (!v.trim() && guest.email.trim()) setNotifPref("email");
              }}
            />

            {/* Preference selector */}
            {(() => {
              const hasEmail = !!guest.email.trim();
              const hasPhone = !!guest.phoneNumber.trim();
              if (!hasEmail && !hasPhone) return null;
              if (hasEmail && !hasPhone) return (
                <p className="text-xs text-gray-500">Tickets will be sent via <strong>email</strong>.</p>
              );
              if (hasPhone && !hasEmail) return (
                <p className="text-xs text-gray-500">Tickets will be sent via <strong>WhatsApp</strong>.</p>
              );
              return (
                <div>
                  <label className="block text-xs font-medium text-gray-600 mb-1">Send tickets via</label>
                  <div className="flex rounded-lg border overflow-hidden text-xs font-medium">
                    {(["email", "whatsapp", "both"] as const).map((p) => (
                      <button
                        key={p}
                        type="button"
                        onClick={() => setNotifPref(p)}
                        className={`flex-1 py-2 transition-colors ${
                          notifPref === p
                            ? p === "whatsapp" ? "bg-green-600 text-white border-green-600"
                              : p === "both" ? "bg-brand-600 text-white"
                              : "bg-blue-600 text-white"
                            : "bg-white text-gray-600 hover:bg-gray-50"
                        }`}
                      >
                        {p === "email" ? "Email" : p === "whatsapp" ? "WhatsApp" : "Both"}
                      </button>
                    ))}
                  </div>
                </div>
              );
            })()}

            {guest.name && (
              <button
                type="button"
                onClick={() => { setGuest({ name: "", email: "", phoneNumber: "" }); setUserQuery(""); setNotifPref("email"); }}
                className="text-xs text-gray-400 hover:text-gray-600 text-left"
              >
                ✕ Clear
              </button>
            )}
          </div>
        </div>
      </div>

      <div className="mt-6 border rounded-xl p-4 bg-white shadow-sm">
        <div className="text-lg font-semibold mb-3">3) Select ticket options</div>
        {options.length === 0 ? (
          <div className="text-sm text-gray-500">Select an event to view options.</div>
        ) : (
          <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-3">
            {options.map(opt => {
              const hasVariants = (opt.variants || []).length > 0;
              if (hasVariants) {
                return (
                  <div key={opt.id} className="border rounded overflow-hidden col-span-full sm:col-span-1">
                    <div className="px-3 py-2 bg-gray-50 border-b text-sm font-medium text-gray-800">
                      {opt.name}{opt.isMainTicket ? <span className="ml-1.5 text-xs text-brand-600 font-normal">• Main</span> : null}
                    </div>
                    {(opt.variants as any[]).map((v: any) => {
                      const unit = effectiveVariantUnit(opt, v);
                      const basePrice = v.price !== null && v.price !== undefined ? v.price : opt.price;
                      const key = `${opt.id}::${v.id}`;
                      return (
                        <div key={v.id} className="flex items-center justify-between px-3 py-2 border-b last:border-b-0">
                          <div>
                            <div className="text-sm">{v.name}</div>
                            <div className="text-xs text-gray-500">
                              {fmtPrice(unit)}
                              {unit < basePrice && basePrice > 0 && <span className="ml-1 text-green-600">(early bird, was {fmtPrice(basePrice)})</span>}
                            </div>
                          </div>
                          <div className="flex items-center gap-2">
                            <label className="text-xs text-gray-500">Qty</label>
                            <input
                              type="number" min={0}
                              className="w-16 border rounded px-2 py-1 text-sm"
                              value={quantities[key] || 0}
                              onChange={e => setQuantities(q => ({ ...q, [key]: Math.max(0, parseInt(e.target.value || '0')) }))}
                            />
                          </div>
                        </div>
                      );
                    })}
                  </div>
                );
              }
              const unit = effectiveOptionUnit(opt);
              return (
                <div key={opt.id} className="border rounded p-3">
                  <div className="font-medium text-sm">{opt.name}</div>
                  <div className="text-xs text-gray-500">
                    {fmtPrice(unit)}
                    {unit < opt.price && opt.price > 0 && <span className="ml-1 text-green-600">(early bird, was {fmtPrice(opt.price)})</span>}
                    {opt.isMainTicket ? " • Main" : ""}
                  </div>
                  <div className="flex items-center gap-2 mt-2">
                    <label className="text-xs text-gray-600">Qty</label>
                    <input
                      type="number" min={0}
                      className="w-20 border rounded px-2 py-1 text-sm"
                      value={quantities[opt.id] || 0}
                      onChange={e => setQuantities(q => ({ ...q, [opt.id]: Math.max(0, parseInt(e.target.value || '0')) }))}
                    />
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      <div className="flex items-center justify-between mt-6">
        <div className="text-sm">Total due: <span className="font-semibold">R {totalDue.toFixed(2)}</span></div>
        <button disabled={submitting} onClick={submit} className="px-4 py-2 text-sm rounded bg-brand-600 text-white hover:bg-brand-700 disabled:opacity-50 shadow-sm">{submitting ? 'Creating…' : 'Create registration'}</button>
      </div>
      </>
      )}

      {tab === 'payment' && (
      <div className="max-w-xl">
        {payMessage && <div className="p-3 mb-3 border rounded bg-emerald-50 text-emerald-800 text-sm">{payMessage}</div>}
        {payError && <div className="p-3 mb-3 border rounded bg-red-50 text-red-700 text-sm">{payError}</div>}

        <div className="border rounded-xl p-4 bg-white shadow-sm">
          <div className="text-lg font-semibold mb-3">Record a payment</div>
          <div className="grid gap-3">
            <div>
              <label className="block text-xs text-gray-600 mb-1">Amount</label>
              <input className="w-full border rounded px-3 py-2 text-sm" type="number" step="0.01" value={payAmount} onChange={e => setPayAmount(e.target.value)} />
            </div>
            <div>
              <label className="block text-xs text-gray-600 mb-1">Method</label>
              <select className="w-full border rounded px-3 py-2 text-sm" value={payMethod} onChange={e => setPayMethod(e.target.value)}>
                <option value="cash">Cash</option>
                <option value="card">Card</option>
                <option value="eft">EFT</option>
                <option value="voucher">Voucher</option>
              </select>
            </div>
            <div ref={paySearchRef} className="relative">
              <label className="block text-xs text-gray-600 mb-1">User</label>
              <input
                className="w-full border rounded px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
                placeholder="Search by name, email or phone…"
                value={payUserQuery}
                autoComplete="off"
                onChange={e => { setPayUserQuery(e.target.value); setPayDropdownOpen(true); if (!e.target.value) { setPayUserId(""); setPayRegistrationId(""); } }}
                onFocus={() => { if (payUserQuery.length >= 2) setPayDropdownOpen(true); }}
              />
              {payDropdownOpen && payUserQuery.trim().length >= 2 && (
                <div className="absolute z-30 top-full left-0 right-0 mt-1 bg-white border border-gray-200 rounded-xl shadow-lg overflow-hidden">
                  {payMatchedUsers.length > 0 ? (
                    <>
                      <div className="px-3 py-1.5 text-[11px] text-gray-400 bg-gray-50 border-b">
                        {payMatchedUsers.length} match{payMatchedUsers.length !== 1 ? "es" : ""}
                      </div>
                      {payMatchedUsers.map(u => (
                        <button
                          key={u.id}
                          type="button"
                          className="w-full text-left px-3 py-2.5 hover:bg-brand-50 border-b border-gray-100 last:border-b-0 transition-colors"
                          onClick={() => selectPayUser(u)}
                        >
                          <div className="text-sm font-medium text-gray-900">{u.name}</div>
                          <div className="text-xs text-gray-500 mt-0.5 flex gap-2 flex-wrap">
                            {u.email && <span>{u.email}</span>}
                            {u.phoneNumber && <span>· {u.phoneNumber}</span>}
                          </div>
                        </button>
                      ))}
                    </>
                  ) : (
                    <div className="px-3 py-3 text-sm text-gray-500 italic">No matching users found.</div>
                  )}
                </div>
              )}
            </div>
            <div>
              <label className="block text-xs text-gray-600 mb-1">Registration</label>
              <select className="w-full max-w-full border rounded px-3 py-2 text-sm truncate" value={payRegistrationId} onChange={e => setPayRegistrationId(e.target.value)} disabled={!payUserId}>
                <option value="">Select registration…</option>
                {regsForPayUser.map((r: any) => {
                  const out = regOutstanding[r.id]?.outstanding ?? 0;
                  const label = `${r.event?.title || r.eventId || 'Event'} — Outstanding: R ${out.toFixed(2)} — #${String(r.id).slice(0,8)}`;
                  return <option key={r.id} value={r.id} title={label}>{label}</option>;
                })}
              </select>
              {!payUserId && <div className="text-xs text-gray-500 mt-1">Search for a user above to see their registrations.</div>}
            </div>
            <div>
              <label className="block text-xs text-gray-600 mb-1">Paid at (optional)</label>
              <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={payPaidAtLocal} onChange={e => setPayPaidAtLocal(e.target.value)} max={new Date().toISOString().slice(0,16)} />
              <div className="text-[10px] text-gray-500 mt-1">Leave blank to use current time</div>
            </div>
          </div>
          <div className="mt-3">
            <button disabled={paySubmitting} onClick={createManualPayment} className="w-full px-3 py-1.5 text-sm rounded bg-brand-600 text-white hover:bg-brand-700 disabled:opacity-50 shadow-sm">{paySubmitting ? 'Recording…' : 'Record payment'}</button>
          </div>
        </div>
      </div>
      )}
    </div>
  );
}
