"use client";

import React, { useEffect, useMemo, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import { apiFetch } from "@/lib/api";
import { useDismissingState } from "@/hooks/useDismissingState";

const STATUS_OPTIONS = ["pending", "confirmed", "partial_paid", "paid", "cancelled"] as const;

function fuzzyMatch(query: string, target: string): boolean {
  const q = query.toLowerCase();
  const t = target.toLowerCase();
  if (t.includes(q)) return true;
  const tokens = q.split(/\s+/).filter(Boolean);
  return tokens.every(tok => t.includes(tok));
}

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

  const isAdmin = useMemo(() => user?.role === "admin", [user]);

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

  const [registrations, setRegistrations] = useState<any[]>([]);
  const [events, setEvents] = useState<any[]>([]);
  const [loadingRegs, setLoadingRegs] = useState(false);
  const [error, setError] = useDismissingState<string | null>(null);
  const [info, setInfo] = useDismissingState<string | null>(null);

  // Filters
  const [query, setQuery] = useState("");
  const [eventFilter, setEventFilter] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [includePastEvents, setIncludePastEvents] = useState(false);
  const [includeInactiveEvents, setIncludeInactiveEvents] = useState(false);

  // Expanded rows + form responses cache
  const [expanded, setExpanded] = useState<Set<string>>(new Set());
  const [formResponses, setFormResponses] = useState<Record<string, any[]>>({});
  const [loadingForms, setLoadingForms] = useState<Set<string>>(new Set());

  const loadRegistrations = async () => {
    if (!token) return;
    try {
      setLoadingRegs(true);
      const regs = await apiFetch<any[]>("/api/registrations", { authToken: token });
      const list = Array.isArray(regs) ? regs.sort((a, b) => {
        const eventCompare = (a.event?.startDate || a.eventId).localeCompare(b.event?.startDate || b.eventId);
        if (eventCompare !== 0) return eventCompare;
        return (a.user?.name || a.userId).localeCompare(b.user?.name || b.userId);
      }) : [];
      setRegistrations(list);
    } catch (e: any) {
      setError(e?.message || "Failed to load registrations");
    } finally {
      setLoadingRegs(false);
    }
  };

  const loadEvents = async () => {
    if (!token) return;
    try {
      const params = new URLSearchParams();
      if (includePastEvents) params.set("includePast", "true");
      if (includeInactiveEvents) params.set("includeInactive", "true");
      const qs = params.toString() ? `?${params.toString()}` : "";
      const evs = await apiFetch<any[]>(`/api/events/all${qs}`, { authToken: token });
      setEvents(Array.isArray(evs) ? evs.sort((a: any, b: any) => new Date(b.startDate).getTime() - new Date(a.startDate).getTime()) : []);
    } catch {}
  };

  useEffect(() => {
    loadRegistrations();
  }, [token]);

  useEffect(() => {
    loadEvents();
  }, [token, includePastEvents, includeInactiveEvents]);

  const toggleExpand = async (reg: any) => {
    const id = reg.id;
    const next = new Set(expanded);
    if (next.has(id)) {
      next.delete(id);
      setExpanded(next);
      return;
    }
    next.add(id);
    setExpanded(next);
    // Load form responses if not cached
    if (!formResponses[id] && !loadingForms.has(id)) {
      setLoadingForms(prev => new Set(prev).add(id));
      try {
        const res = await apiFetch<any>(`/api/forms/responses?registrationId=${encodeURIComponent(id)}`, { authToken: token! });
        const items = Array.isArray(res?.items) ? res.items : (Array.isArray(res) ? res : []);
        setFormResponses(prev => ({ ...prev, [id]: items }));
      } catch {
        setFormResponses(prev => ({ ...prev, [id]: [] }));
      } finally {
        setLoadingForms(prev => { const s = new Set(prev); s.delete(id); return s; });
      }
    }
  };

  const cancelRegistration = async (reg: any) => {
    if (!token) return;
    setError(null); setInfo(null);
    if (!confirm(`Cancel registration #${String(reg.id).slice(0, 8)} for ${reg.user?.name || reg.userId}?`)) return;
    try {
      await apiFetch(`/api/registrations/${encodeURIComponent(reg.id)}`, { method: "DELETE", authToken: token });
      setInfo("Registration cancelled");
      await loadRegistrations();
    } catch (e: any) {
      setError(e?.message || "Failed to cancel registration");
    }
  };

  const updateStatus = async (reg: any, status: string) => {
    if (!token) return;
    setError(null); setInfo(null);
    try {
      await apiFetch(`/api/registrations/${encodeURIComponent(reg.id)}`, { method: "PUT", authToken: token, body: { status } });
      setInfo("Status updated");
      await loadRegistrations();
    } catch (e: any) {
      setError(e?.message || "Failed to update status");
    }
  };

  const eventIds = useMemo(() => new Set(events.map((ev: any) => ev.id)), [events]);

  const filtered = useMemo(() => {
    return registrations.filter((r: any) => {
      if (!eventIds.has(r.eventId)) return false;
      if (eventFilter && r.eventId !== eventFilter) return false;
      if (statusFilter && r.status !== statusFilter) return false;
      if (!query.trim()) return true;
      const haystack = [
        r.id, r.user?.name, r.user?.email, r.user?.phoneNumber,
        r.userId, r.event?.title, r.eventId, r.status,
      ].map((x: any) => String(x || "")).join(" ");
      return fuzzyMatch(query.trim(), haystack);
    });
  }, [registrations, query, eventFilter, statusFilter]);

  const statusColor = (s: string) => {
    if (s === "paid") return "text-green-700 bg-green-50";
    if (s === "confirmed") return "text-blue-700 bg-blue-50";
    if (s === "partial_paid") return "text-amber-700 bg-amber-50";
    if (s === "cancelled") return "text-red-700 bg-red-50";
    return "text-gray-700 bg-gray-50";
  };

  return (
    <div className="max-w-6xl mx-auto w-full p-6">
      <div className="flex items-center justify-between mb-4">
        <h1 className="text-2xl font-semibold">Manage Registrations</h1>
        <button className="px-3 py-1.5 text-sm rounded bg-gray-100 hover:bg-gray-200" onClick={() => router.push('/dashboard')}>Back</button>
      </div>

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

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

      {/* Filters */}
      <div className="border rounded-xl p-4 bg-white shadow-sm mb-4">
        <div className="flex flex-wrap gap-3 items-end">
          <div className="flex-1 min-w-48">
            <label className="block text-xs text-gray-600 mb-1">Search (name, email, phone, event, ID…)</label>
            <input
              className="w-full border rounded px-3 py-1.5 text-sm"
              placeholder="Type to search…"
              value={query}
              onChange={e => setQuery(e.target.value)}
            />
          </div>
          <div>
            <label className="block text-xs text-gray-600 mb-1">Event</label>
            <select className="border rounded px-2 py-1.5 text-sm max-w-48" value={eventFilter} onChange={e => setEventFilter(e.target.value)}>
              <option value="">All events</option>
              {events.map(ev => (
                <option key={ev.id} value={ev.id}>{ev.title}</option>
              ))}
            </select>
            <div className="flex items-center gap-3 mt-1.5 text-xs text-gray-500">
              <label className="flex items-center gap-1 cursor-pointer">
                <input type="checkbox" checked={includePastEvents} onChange={e => setIncludePastEvents(e.target.checked)} />
                Past
              </label>
              <label className="flex items-center gap-1 cursor-pointer">
                <input type="checkbox" checked={includeInactiveEvents} onChange={e => setIncludeInactiveEvents(e.target.checked)} />
                Inactive
              </label>
            </div>
          </div>
          <div>
            <label className="block text-xs text-gray-600 mb-1">Status</label>
            <select className="border rounded px-2 py-1.5 text-sm" value={statusFilter} onChange={e => setStatusFilter(e.target.value)}>
              <option value="">All statuses</option>
              {STATUS_OPTIONS.map(s => <option key={s} value={s}>{s}</option>)}
            </select>
          </div>
          <button className="text-sm px-2 py-1.5 rounded bg-gray-100 hover:bg-gray-200" onClick={loadRegistrations} disabled={loadingRegs}>
            {loadingRegs ? "Loading…" : "Refresh"}
          </button>
        </div>
        <div className="mt-2 text-xs text-gray-500">{filtered.length} of {registrations.length} registrations</div>
      </div>

      <div className="border rounded-xl bg-white shadow-sm">
        <ul className="divide-y text-sm">
          {filtered.map((r: any) => {
            const totalDue = (r.registrationOptions || []).reduce((sum: number, opt: any) => {
              const unit = (opt.priceSnapshot !== null && opt.priceSnapshot !== undefined)
                ? Number(opt.priceSnapshot)
                : (opt.eventOption?.price || 0);
              return sum + unit * (opt.quantity || 0);
            }, 0);
            const isExpanded = expanded.has(r.id);
            const responses = formResponses[r.id];
            const loadingResponse = loadingForms.has(r.id);

            return (
              <li key={r.id} className="hover:bg-gray-50">
                <div className="p-3 cursor-pointer" onClick={() => toggleExpand(r)}>
                  <div className="flex items-start justify-between gap-2">
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2 flex-wrap">
                        <span className="font-medium">{r.user?.name || r.userId}</span>
                        <span className="text-gray-400">—</span>
                        <span className="text-gray-700">{r.event?.title || r.eventId}</span>
                        <span className={`text-xs px-1.5 py-0.5 rounded font-medium ${statusColor(r.status)}`}>{r.status}</span>
                      </div>
                      <div className="text-xs text-gray-500 mt-0.5">
                        {r.user?.email && <span className="mr-2">{r.user.email}</span>}
                        {r.user?.phoneNumber && <span className="mr-2">{r.user.phoneNumber}</span>}
                        <span>R {totalDue.toFixed(2)}</span>
                        <span className="ml-2 text-gray-400">#{String(r.id).slice(0, 8)}</span>
                      </div>
                    </div>
                    <div className="flex items-center gap-2 shrink-0">
                      <span className="text-xs text-gray-400">{new Date(r.createdAt).toLocaleDateString()}</span>
                      <span className="text-gray-400 text-xs">{isExpanded ? "▲" : "▼"}</span>
                    </div>
                  </div>
                </div>

                {isExpanded && (
                  <div className="px-3 pb-3 bg-gray-50 border-t" onClick={e => e.stopPropagation()}>
                    {/* Actions */}
                    <div className="flex items-center gap-2 py-2 border-b border-gray-200 mb-3">
                      <select
                        className="px-2 py-1 text-xs rounded-lg border border-gray-300 bg-white shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 disabled:opacity-60"
                        value={r.status}
                        onChange={e => updateStatus(r, e.target.value)}
                        disabled={r.status === 'cancelled'}
                      >
                        {STATUS_OPTIONS.map(s => <option key={s} value={s}>{s}</option>)}
                      </select>
                      <button
                        className="px-2 py-1 text-xs rounded bg-red-600 text-white hover:bg-red-700 disabled:opacity-50"
                        onClick={() => cancelRegistration(r)}
                        disabled={r.status === 'cancelled'}
                      >
                        Cancel registration
                      </button>
                    </div>

                    {/* Ticket options */}
                    {(r.registrationOptions || []).length > 0 && (
                      <div className="mb-3">
                        <div className="text-xs font-semibold text-gray-600 mb-1 uppercase tracking-wide">Ticket options</div>
                        <div className="grid sm:grid-cols-2 gap-2">
                          {r.registrationOptions.map((opt: any) => (
                            <div key={opt.id} className="bg-white border rounded p-2 text-xs">
                              <div className="font-medium">
                                {opt.eventOption?.name || opt.eventOptionId}
                                {opt.variant?.name && <span className="text-gray-500"> ({opt.variant.name})</span>}
                              </div>
                              <div className="text-gray-500">
                                {(() => {
                                  const unit = (opt.priceSnapshot !== null && opt.priceSnapshot !== undefined)
                                    ? Number(opt.priceSnapshot)
                                    : (opt.variant?.price ?? opt.eventOption?.price ?? 0);
                                  return `Qty: ${opt.quantity} × R ${unit.toFixed(2)} = R ${(unit * (opt.quantity || 0)).toFixed(2)}`;
                                })()}
                              </div>
                              {opt.appliedTierId && (
                                <div className="text-green-700 text-[10px] mt-0.5">Early-bird price applied</div>
                              )}
                            </div>
                          ))}
                        </div>
                        <div className="text-xs text-gray-700 mt-1 font-medium">Total: R {totalDue.toFixed(2)}</div>
                      </div>
                    )}

                    {/* Form responses */}
                    <div>
                      <div className="text-xs font-semibold text-gray-600 mb-1 uppercase tracking-wide">Form responses</div>
                      {loadingResponse ? (
                        <div className="text-xs text-gray-400">Loading…</div>
                      ) : !responses || responses.length === 0 ? (
                        <div className="text-xs text-gray-400">No form responses submitted.</div>
                      ) : (
                        <div className="space-y-2">
                          {responses.map((resp: any, idx: number) => (
                            <div key={resp.id || idx} className="bg-white border rounded p-2">
                              <div className="text-xs font-medium text-gray-600 mb-1">Response #{idx + 1}</div>
                              <div className="grid sm:grid-cols-2 gap-1.5">
                                {(resp.answers || []).map((a: any) => (
                                  <div key={a.id} className="bg-gray-50 border rounded p-1.5 text-xs">
                                    <div className="text-[10px] text-gray-500">{a.field?.label || a.fieldId}</div>
                                    <div className="font-medium">{a.value}</div>
                                  </div>
                                ))}
                              </div>
                            </div>
                          ))}
                        </div>
                      )}
                    </div>

                    {/* Metadata */}
                    <div className="mt-2 text-[10px] text-gray-400">
                      Registration ID: {r.id} · Created: {new Date(r.createdAt).toLocaleString()}
                    </div>
                  </div>
                )}
              </li>
            );
          })}
          {filtered.length === 0 && (
            <li className="p-4 text-gray-500 text-sm">{loadingRegs ? "Loading…" : "No registrations found."}</li>
          )}
        </ul>
      </div>
    </div>
  );
}