"use client";

import React, { Suspense, useEffect, useMemo, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter, useSearchParams } from "next/navigation";
import { apiFetch, fetchAllUsers } from "@/lib/api";
import { useDismissingState } from "@/hooks/useDismissingState";
import { MessageCircle } from "lucide-react";

// Attendee with preference info
type Attendee = { id: string; name: string; phone: string; pref: string };
type UserEntry = { id: string; name: string; phone: string; pref: string };

function toLocalInputValue(d: Date) {
  const pad = (n: number) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

export default function WhatsAppAttendeesPage() {
  return (
    <Suspense fallback={<div className="p-6">Loading...</div>}>
      <WhatsAppAttendeesPageInner />
    </Suspense>
  );
}

// ─── Attendees dropdown with preference indicators ────────────────────────────
function AttendeesCheckboxDropdown({
  attendees,
  loading,
  selectedIds,
  onChange,
  channel = "whatsapp",
}: {
  attendees: (Attendee | UserEntry)[];
  loading: boolean;
  selectedIds: string[];
  onChange: (ids: string[]) => void;
  channel?: "whatsapp" | "email";
}) {
  const [open, setOpen] = useState(false);
  const allIds = useMemo(() => attendees.map((a) => a.id), [attendees]);
  const allSelected = selectedIds.length > 0 && selectedIds.length === allIds.length;

  const toggleAll = (checked: boolean) => onChange(checked ? allIds : []);
  const toggleId = (id: string) => {
    if (selectedIds.includes(id)) onChange(selectedIds.filter((x) => x !== id));
    else onChange([...selectedIds, id]);
  };

  const prefMatch = (pref: string) =>
    channel === "whatsapp" ? pref === "whatsapp" || pref === "both" : pref === "email" || pref === "both";
  const prefLabel = (pref: string) => {
    if (pref === "both") return "both";
    if (pref === "whatsapp") return "WA";
    if (pref === "email") return "email";
    return pref || "email";
  };
  const prefColor = (pref: string, match: boolean) =>
    match ? "text-green-700 bg-green-50" : "text-amber-700 bg-amber-50";

  const summary = loading
    ? "Loading…"
    : attendees.length === 0
    ? "No attendees"
    : allSelected
    ? `All (${attendees.length})`
    : selectedIds.length === 0
    ? "None selected"
    : `${selectedIds.length} selected`;

  const mismatched = selectedIds.filter((id) => {
    const a = attendees.find((x) => x.id === id);
    return a && !prefMatch(a.pref);
  });

  return (
    <div className="relative block w-full max-w-xs">
      <button
        type="button"
        className="w-full border rounded px-3 py-2 text-sm bg-white hover:bg-gray-50 text-left"
        onClick={() => setOpen((o) => !o)}
      >
        {summary}
        {mismatched.length > 0 && (
          <span className="ml-2 text-xs text-amber-600">({mismatched.length} pref mismatch)</span>
        )}
      </button>
      {open && (
        <div className="absolute z-10 mt-1 left-0 right-0 max-h-72 overflow-auto bg-white border rounded shadow">
          <div className="px-3 py-2 border-b sticky top-0 bg-white space-y-1">
            <label className="text-sm flex items-center gap-2">
              <input type="checkbox" checked={allSelected} onChange={(e) => toggleAll(e.target.checked)} />
              <span className="font-medium">Select all</span>
            </label>
            <div className="flex gap-1 flex-wrap">
              <button
                type="button"
                className="text-xs px-2 py-0.5 rounded border border-green-300 text-green-700 hover:bg-green-50"
                onClick={() => onChange(attendees.filter((a) => prefMatch(a.pref)).map((a) => a.id))}
              >
                Select {channel === "whatsapp" ? "WhatsApp/both" : "Email/both"}
              </button>
              <button
                type="button"
                className="text-xs px-2 py-0.5 rounded border border-gray-300 text-gray-600 hover:bg-gray-50"
                onClick={() => onChange([])}
              >
                Clear
              </button>
            </div>
          </div>
          {loading ? (
            <div className="px-3 py-2 text-sm text-gray-500">Loading…</div>
          ) : attendees.length === 0 ? (
            <div className="px-3 py-2 text-sm text-gray-500">No attendees with phone numbers</div>
          ) : (
            <ul className="py-1">
              {attendees.map((a) => {
                const checked = selectedIds.includes(a.id);
                const match = prefMatch(a.pref);
                return (
                  <li key={a.id} className={`px-3 py-1 hover:bg-gray-50 ${!match ? "opacity-75" : ""}`}>
                    <label className="flex items-center gap-2 text-sm min-w-0">
                      <input type="checkbox" checked={checked} onChange={() => toggleId(a.id)} />
                      <span className="truncate flex-1">
                        {a.name ? `${a.name} (${a.phone})` : a.phone}
                      </span>
                      <span className={`text-[10px] px-1 rounded shrink-0 ${prefColor(a.pref, match)}`}>
                        {prefLabel(a.pref)}
                      </span>
                    </label>
                  </li>
                );
              })}
            </ul>
          )}
          <div className="px-3 py-2 border-t bg-gray-50 text-right">
            <button
              type="button"
              className="px-2 py-1 text-xs rounded border bg-white hover:bg-gray-100"
              onClick={() => setOpen(false)}
            >
              Done
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

// ─── Preference warning banner ────────────────────────────────────────────────
function PrefWarning({ attendees, selectedIds, channel }: { attendees: (Attendee|UserEntry)[]; selectedIds: string[]; channel: "whatsapp" | "email" }) {
  const prefMatch = (pref: string) =>
    channel === "whatsapp" ? pref === "whatsapp" || pref === "both" : pref === "email" || pref === "both";

  const mismatched = useMemo(
    () => selectedIds.filter((id) => {
      const a = attendees.find((x) => x.id === id);
      return a && !prefMatch(a.pref);
    }),
    [attendees, selectedIds, channel]
  );

  if (mismatched.length === 0) return null;
  return (
    <div className="p-3 border rounded bg-amber-50 text-amber-800 text-xs">
      <strong>{mismatched.length} selected attendee(s)</strong> have a notification preference that doesn&apos;t include{" "}
      {channel === "whatsapp" ? "WhatsApp" : "email"}. They will still receive the message, but it may not be their preferred channel.
      {" "}<button
        type="button"
        className="underline ml-1"
        onClick={() => {/* handled by dropdown */}}
      >
        Use the dropdown to filter by preference.
      </button>
    </div>
  );
}

// ─── WhatsApp Automations Panel ───────────────────────────────────────────────
function WAAutomationsPanel({ events, token, onInfo, onError }: { events: any[]; token?: string | null; onInfo: (s: string) => void; onError: (s: string) => void }) {
  const [autoEventId, setAutoEventId] = React.useState<string>("");
  const currentEvent = React.useMemo(() => (events || []).find((e: any) => e.id === autoEventId), [events, autoEventId]);

  const preWeekDefault = `Hi {{name}}\n\nJust a friendly reminder that {{event.title}} is one week away!\n\nEvent details: {{event.link}}`;
  const finalDefault = `Hi {{name}}\n\nFinal reminder for {{event.title}}.\nPlease have your QR code/ticket ready at entry.\n\nEvent details: {{event.link}}`;
  const thanksDefault = `Hi {{name}}\n\nThank you for joining us at {{event.title}}!\nWe hope you had a great time. See you next time!`;
  const promoDefault = `Hi {{name}}\n\nWe'd love to see you at our next event: {{promo.title}}.\nFind out more and register here: {{promo.link}}`;

  const [enablePre, setEnablePre] = React.useState(true);
  const [enableFinal, setEnableFinal] = React.useState(true);
  const [enableThanks, setEnableThanks] = React.useState(true);
  const [enablePromo, setEnablePromo] = React.useState(false);
  const [preBody, setPreBody] = React.useState(preWeekDefault);
  const [finalBody, setFinalBody] = React.useState(finalDefault);
  const [thanksBody, setThanksBody] = React.useState(thanksDefault);
  const [promoBody, setPromoBody] = React.useState(promoDefault);
  const [finalHours, setFinalHours] = React.useState<"24" | "48">("24");
  const [preWhen, setPreWhen] = React.useState<string>("");
  const [finalWhen, setFinalWhen] = React.useState<string>("");
  const [thanksWhen, setThanksWhen] = React.useState<string>("");
  const [promoWhen, setPromoWhen] = React.useState<string>("");
  const [promoEventId, setPromoEventId] = React.useState<string>("");

  React.useEffect(() => {
    if (!currentEvent) { setPreWhen(""); setFinalWhen(""); setThanksWhen(""); setPromoWhen(""); return; }
    try {
      const start = new Date(currentEvent.startDate);
      const end = new Date(currentEvent.endDate || currentEvent.startDate);
      const pre = new Date(start); pre.setDate(pre.getDate() - 7); pre.setHours(9, 0, 0, 0);
      setPreWhen(toLocalInputValue(pre));
      const fin = new Date(start); fin.setHours(fin.getHours() - (finalHours === "48" ? 48 : 24));
      setFinalWhen(toLocalInputValue(fin));
      const ty = new Date(end); ty.setDate(ty.getDate() + 1); ty.setHours(9, 0, 0, 0);
      setThanksWhen(toLocalInputValue(ty));
      const pr = new Date(end); pr.setDate(pr.getDate() + 3); pr.setHours(9, 0, 0, 0);
      setPromoWhen(toLocalInputValue(pr));
    } catch {}
  }, [currentEvent, finalHours]);

  const onSchedule = async () => {
    try {
      onError(null as any); onInfo(null as any);
      if (!token) { onError("Not authenticated"); return; }
      if (!autoEventId) { onError("Please select an event"); return; }
      const jobs: any[] = [];
      if (enablePre && preBody.trim() && preWhen) jobs.push({ message: preBody, scheduledAt: new Date(preWhen).toISOString() });
      if (enableFinal && finalBody.trim() && finalWhen) jobs.push({ message: finalBody, scheduledAt: new Date(finalWhen).toISOString() });
      if (enableThanks && thanksBody.trim() && thanksWhen) jobs.push({ message: thanksBody, scheduledAt: new Date(thanksWhen).toISOString() });
      if (enablePromo && promoBody.trim() && promoWhen) jobs.push({ message: promoBody, scheduledAt: new Date(promoWhen).toISOString(), promoEventId: promoEventId || undefined });
      if (jobs.length === 0) { onError("Please enable at least one automation and fill in details"); return; }
      let scheduled = 0;
      for (const job of jobs) {
        await apiFetch(`/api/events/${encodeURIComponent(autoEventId)}/whatsapp-attendees/schedule`, {
          method: "POST", authToken: token,
          body: { message: job.message, scheduledAt: job.scheduledAt, filter: { status: "paid" } },
        });
        scheduled++;
      }
      onInfo(`Scheduled ${scheduled} WhatsApp automation(s).`);
    } catch (e: any) {
      onError(e?.message || "Failed to schedule automations");
    }
  };

  return (
    <div className="grid gap-4">
      <div>
        <label className="block text-xs text-gray-600 mb-1">Event</label>
        <select className="w-full border rounded px-3 py-2 text-sm" value={autoEventId} onChange={(e) => setAutoEventId(e.target.value)}>
          <option value="">Select an event…</option>
          {(events || []).map((ev: any) => (
            <option key={ev.id} value={ev.id}>{ev.title}</option>
          ))}
        </select>
      </div>

      <div className="grid gap-4">
        <fieldset className="border rounded p-3">
          <legend className="text-sm font-medium">Pre-Event Reminder (1 week before)</legend>
          <label className="inline-flex items-center gap-2 text-sm mb-2">
            <input type="checkbox" checked={enablePre} onChange={(e) => setEnablePre(e.target.checked)} /> Enable
          </label>
          <div>
            <label className="block text-xs text-gray-600 mb-1">Send at</label>
            <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={preWhen} onChange={(e) => setPreWhen(e.target.value)} />
          </div>
          <label className="block text-xs text-gray-600 mb-1 mt-2">Message</label>
          <textarea className="w-full border rounded px-3 py-2 text-sm" rows={4} value={preBody} onChange={(e) => setPreBody(e.target.value)} />
        </fieldset>

        <fieldset className="border rounded p-3">
          <legend className="text-sm font-medium">Final Reminder (24–48 hrs before)</legend>
          <div className="flex items-center gap-4 mb-2">
            <label className="inline-flex items-center gap-2 text-sm">
              <input type="checkbox" checked={enableFinal} onChange={(e) => setEnableFinal(e.target.checked)} /> Enable
            </label>
            <label className="text-xs text-gray-600">Hours before:</label>
            <select className="border rounded px-2 py-1 text-sm" value={finalHours} onChange={(e) => setFinalHours(e.target.value as any)}>
              <option value="24">24</option>
              <option value="48">48</option>
            </select>
          </div>
          <div>
            <label className="block text-xs text-gray-600 mb-1">Send at</label>
            <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={finalWhen} onChange={(e) => setFinalWhen(e.target.value)} />
          </div>
          <label className="block text-xs text-gray-600 mb-1 mt-2">Message</label>
          <textarea className="w-full border rounded px-3 py-2 text-sm" rows={4} value={finalBody} onChange={(e) => setFinalBody(e.target.value)} />
        </fieldset>

        <fieldset className="border rounded p-3">
          <legend className="text-sm font-medium">Thank You / Wrap Up</legend>
          <label className="inline-flex items-center gap-2 text-sm mb-2">
            <input type="checkbox" checked={enableThanks} onChange={(e) => setEnableThanks(e.target.checked)} /> Enable
          </label>
          <div>
            <label className="block text-xs text-gray-600 mb-1">Send at</label>
            <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={thanksWhen} onChange={(e) => setThanksWhen(e.target.value)} />
          </div>
          <label className="block text-xs text-gray-600 mb-1 mt-2">Message</label>
          <textarea className="w-full border rounded px-3 py-2 text-sm" rows={4} value={thanksBody} onChange={(e) => setThanksBody(e.target.value)} />
        </fieldset>

        <fieldset className="border rounded p-3">
          <legend className="text-sm font-medium">Next Event Promo</legend>
          <div className="flex items-center gap-4 mb-2">
            <label className="inline-flex items-center gap-2 text-sm">
              <input type="checkbox" checked={enablePromo} onChange={(e) => setEnablePromo(e.target.checked)} /> Enable
            </label>
          </div>
          <div className="grid sm:grid-cols-2 gap-3 mb-2">
            <div>
              <label className="block text-xs text-gray-600 mb-1">Promo Event</label>
              <select className="w-full border rounded px-3 py-2 text-sm" value={promoEventId} onChange={(e) => setPromoEventId(e.target.value)}>
                <option value="">Select event to promote…</option>
                {(events || []).map((ev: any) => (
                  <option key={ev.id} value={ev.id}>{ev.title}</option>
                ))}
              </select>
            </div>
            <div>
              <label className="block text-xs text-gray-600 mb-1">Send at</label>
              <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={promoWhen} onChange={(e) => setPromoWhen(e.target.value)} />
            </div>
          </div>
          <label className="block text-xs text-gray-600 mb-1">Message</label>
          <textarea className="w-full border rounded px-3 py-2 text-sm" rows={4} value={promoBody} onChange={(e) => setPromoBody(e.target.value)} />
        </fieldset>
      </div>

      <div className="flex items-center gap-2">
        <button type="button" className="px-3 py-1.5 text-sm rounded bg-emerald-600 text-white hover:bg-emerald-700" onClick={onSchedule}>
          Schedule selected
        </button>
        <div className="text-[11px] text-gray-500">
          Placeholders: {"{{name}}"}, {"{{event.title}}"}, {"{{event.start}}"}, {"{{event.link}}"}, {"{{promo.title}}"}, {"{{promo.link}}"}
        </div>
      </div>
    </div>
  );
}

// ─── Main Page ────────────────────────────────────────────────────────────────
function WhatsAppAttendeesPageInner() {
  const { user, loading, token } = useAuth();
  const router = useRouter();
  const search = useSearchParams();
  const preselectEventId = search?.get("eventId") || "";

  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 [error, setError] = useDismissingState<string | null>(null);
  const [info, setInfo] = useDismissingState<string | null>(null);
  const [tab, setTab] = useState<"attendees" | "automations" | "broadcasts" | "scheduled">("attendees");
  const [loadingEvents, setLoadingEvents] = useState(false);
  const [allEvents, setAllEvents] = useState<any[]>([]);
  const [evIncludePast, setEvIncludePast] = useState(false);

  const events = useMemo(() => {
    const now = Date.now();
    if (evIncludePast) return allEvents;
    return allEvents.filter((ev) => !isNaN(new Date(ev.endDate).getTime()) && new Date(ev.endDate).getTime() > now);
  }, [allEvents, evIncludePast]);

  useEffect(() => {
    const loadEvents = async () => {
      try {
        setLoadingEvents(true);
        const evs = await apiFetch<any[]>("/api/events/all?includePast=true", { authToken: token || undefined });
        setAllEvents((evs || []).sort((a: any, b: any) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime()));
      } catch (e: any) {
        setError(e?.message || "Failed to load events");
      } finally {
        setLoadingEvents(false);
      }
    };
    loadEvents();
  }, [user, token]);

  // ── Attendees tab ──────────────────────────────────────────────────────────
  const [eventId, setEventId] = useState<string>(preselectEventId);
  useEffect(() => { if (preselectEventId) setEventId(preselectEventId); }, [preselectEventId]);
  const [templateKey, setTemplateKey] = useState<"custom" | "payment_reminder" | "event_reminder" | "tickets">("custom");
  const [message, setMessage] = useState("");
  const [messageDirty, setMessageDirty] = useState(false);
  const [status, setStatus] = useState<"any" | "paid" | "unpaid" | "partial_paid" | "cancelled">("any");
  const [attendees, setAttendees] = useState<Attendee[]>([]);
  const [selectedAttendeeIds, setSelectedAttendeeIds] = useState<string[]>([]);
  const [loadingAttendees, setLoadingAttendees] = useState(false);
  const [previewCount, setPreviewCount] = useState<number | null>(null);
  const [previewSample, setPreviewSample] = useState<{ phone: string; name?: string }[] | null>(null);
  const [sending, setSending] = useState(false);
  const [scheduledAtLocal, setScheduledAtLocal] = useState<string>("");
  const [showInfo, setShowInfo] = useState(false);

  const currentEvent = useMemo(() => (events || []).find((e) => e.id === eventId), [events, eventId]);

  useEffect(() => {
    const title = currentEvent?.title || "the event";
    if (templateKey === "payment_reminder") {
      if (!messageDirty) setMessage(`Hi {{name}}\n\nFriendly reminder: you have an outstanding balance for ${title}.\n\nPlease settle your balance to secure your tickets. Thank you!`);
    } else if (templateKey === "event_reminder") {
      if (!messageDirty) setMessage(`Hi {{name}}\n\nA quick reminder about ${title}.\nStart: {{event.start}}\n\nWe look forward to seeing you!`);
    } else if (templateKey === "tickets") {
      setMessageDirty(false); setMessage("");
    }
  }, [templateKey, currentEvent]);

  useEffect(() => {
    const run = async () => {
      try {
        setLoadingAttendees(true); setAttendees([]); setSelectedAttendeeIds([]);
        if (!eventId || !token) return;
        const regs = await apiFetch<any[]>(`/api/registrations/event/${encodeURIComponent(eventId)}`, { authToken: token });
        const uniq = new Map<string, Attendee>();
        (regs || []).forEach((r: any) => {
          const u = r?.user;
          if (u?.id && u?.phoneNumber && !u.email?.endsWith("@guest.local") && u.isActive !== false) {
            uniq.set(u.id, { id: u.id, name: u.name || "", phone: u.phoneNumber, pref: u.notificationPreference || "email" });
          }
        });
        const list = Array.from(uniq.values()).sort((a, b) => (a.name || "").localeCompare(b.name || "", undefined, { sensitivity: "base" }));
        setAttendees(list);
        // Default: select those with whatsapp/both preference
        const matching = list.filter((a) => a.pref === "whatsapp" || a.pref === "both").map((a) => a.id);
        setSelectedAttendeeIds(matching.length > 0 ? matching : list.map((a) => a.id));
      } catch { } finally { setLoadingAttendees(false); }
    };
    run();
  }, [eventId, token]);

  const buildPayload = (dryRun?: boolean) => {
    const payload: any = {
      filter: { status: status !== "any" ? status : undefined, attendeeIds: selectedAttendeeIds.length ? selectedAttendeeIds : undefined },
      template: templateKey,
      dryRun: dryRun || undefined,
    };
    if (templateKey !== "tickets") payload.message = message;
    return payload;
  };

  const onPreview = async () => {
    try {
      setError(null); setInfo(null); setPreviewCount(null); setPreviewSample(null);
      if (!token) { setError("Not authenticated"); return; }
      if (!eventId) { setError("Please select an event"); return; }
      if (templateKey !== "tickets" && !message.trim()) { setError("Message is required"); return; }
      const res = await apiFetch(`/api/events/${encodeURIComponent(eventId)}/whatsapp-attendees`, { method: "POST", authToken: token, body: buildPayload(true) });
      setPreviewCount(res?.matched ?? 0);
      setPreviewSample(Array.isArray(res?.recipients) ? res.recipients : null);
      setInfo(`Matched ${res?.matched ?? 0} recipient(s) with a phone number.`);
    } catch (e: any) { setError(e?.message || "Failed to preview"); }
  };

  const resetAttendeesForm = () => {
    setTemplateKey("custom"); setMessage(""); setMessageDirty(false);
    setStatus("any"); setScheduledAtLocal(""); setPreviewCount(null); setPreviewSample(null);
    setSelectedAttendeeIds(attendees.map((a) => a.id));
  };

  const onSend = async () => {
    try {
      setError(null); setInfo(null);
      if (!token) { setError("Not authenticated"); return; }
      if (!eventId) { setError("Please select an event"); return; }
      if (templateKey !== "tickets" && !message.trim()) { setError("Message is required"); return; }
      setSending(true);
      const res = await apiFetch(`/api/events/${encodeURIComponent(eventId)}/whatsapp-attendees`, { method: "POST", authToken: token, body: buildPayload() });
      setInfo(`Queued ${res?.queued ?? res?.matched ?? 0} recipient(s) for sending.`);
      resetAttendeesForm();
    } catch (e: any) { setError(e?.message || "Failed to send"); } finally { setSending(false); }
  };

  const onScheduleSend = async () => {
    try {
      setError(null); setInfo(null);
      if (!token) { setError("Not authenticated"); return; }
      if (!eventId) { setError("Please select an event"); return; }
      if (templateKey !== "tickets" && !message.trim()) { setError("Message is required"); return; }
      if (!scheduledAtLocal) { setError("Scheduled time is required"); return; }
      const whenIso = new Date(scheduledAtLocal).toISOString();
      const payload: any = {
        message: message || undefined,
        filter: { status: status !== "any" ? status : undefined, attendeeIds: selectedAttendeeIds.length ? selectedAttendeeIds : undefined },
        template: templateKey, scheduledAt: whenIso,
      };
      const res = await apiFetch(`/api/events/${encodeURIComponent(eventId)}/whatsapp-attendees/schedule`, { method: "POST", authToken: token, body: payload });
      setInfo(res?.job?.id ? "WhatsApp scheduled. It will be sent around the specified time." : "Scheduled.");
      resetAttendeesForm();
    } catch (e: any) { setError(e?.message || "Failed to schedule"); }
  };

  // ── Broadcasts tab ─────────────────────────────────────────────────────────
  const [users, setUsers] = useState<UserEntry[]>([]);
  const [loadingUsers, setLoadingUsers] = useState(false);
  const [selectedUserIds, setSelectedUserIds] = useState<string[]>([]);
  const [broadcastEventId, setBroadcastEventId] = useState<string>("");
  const [broadcastMessage, setBroadcastMessage] = useState("");
  const [broadcastPhones, setBroadcastPhones] = useState("");
  const [broadcastPreviewCount, setBroadcastPreviewCount] = useState<number | null>(null);
  const [broadcastPreviewSample, setBroadcastPreviewSample] = useState<{ phone: string; name?: string }[] | null>(null);
  const [broadcastScheduledAtLocal, setBroadcastScheduledAtLocal] = useState<string>("");

  useEffect(() => {
    const run = async () => {
      try {
        if (!token) return;
        setLoadingUsers(true);
        const allUsers = await fetchAllUsers(token);
        const mapped = allUsers
          .filter((u: any) => u.isActive !== false && !u.email?.endsWith("@guest.local") && u.phoneNumber)
          .map((u: any) => ({ id: u.id, name: u.name || "", phone: u.phoneNumber, pref: u.notificationPreference || "email" }))
          .sort((a: any, b: any) => (a.name || "").localeCompare(b.name || "", undefined, { sensitivity: "base" }));
        setUsers(mapped);
      } catch { } finally { setLoadingUsers(false); }
    };
    run();
  }, [token]);

  const resetBroadcastForm = () => {
    setSelectedUserIds([]); setBroadcastEventId(""); setBroadcastMessage("");
    setBroadcastPhones(""); setBroadcastPreviewCount(null); setBroadcastPreviewSample(null);
    setBroadcastScheduledAtLocal("");
  };

  // ── Scheduled tab ──────────────────────────────────────────────────────────
  type ScheduledJob = { id: string; kind: string; eventId?: string | null; broadcast?: boolean; channel?: string; recipient?: string | null; scheduledAt: string; createdAt: string; status: string; attempts: number; sentAt?: string | null; lastError?: string | null; subject?: string; payload?: any };
  const [scheduled, setScheduled] = useState<ScheduledJob[]>([]);
  const [loadingScheduled, setLoadingScheduled] = useState(false);
  const [editing, setEditing] = useState<ScheduledJob | null>(null);
  const [editMessage, setEditMessage] = useState<string>("");
  const [editWhen, setEditWhen] = useState<string>("");
  const [savingEdit, setSavingEdit] = useState(false);

  const loadScheduled = async () => {
    try {
      if (!token) return;
      setLoadingScheduled(true);
      const res = await apiFetch<{ jobs: ScheduledJob[] }>(`/api/scheduled-emails?channel=whatsapp`, { authToken: token });
      setScheduled(Array.isArray(res?.jobs) ? res.jobs : []);
    } catch { } finally { setLoadingScheduled(false); }
  };

  useEffect(() => { if (tab === "scheduled") loadScheduled(); }, [tab, token]);

  const saveEdit = async () => {
    if (!editing) return;
    try {
      setSavingEdit(true);
      if (!token) { setError("Not authenticated"); return; }
      const body: any = {};
      if (editWhen) body.scheduledAt = new Date(editWhen).toISOString();
      if (editMessage.trim()) body.text = editMessage;
      await apiFetch(`/api/scheduled-emails/${encodeURIComponent(editing.id)}`, { method: "PATCH", authToken: token, body });
      setInfo("Scheduled message updated.");
      setEditing(null);
      loadScheduled();
    } catch (e: any) { setError(e?.message || "Failed to update"); } finally { setSavingEdit(false); }
  };

  const removeJob = async (job: ScheduledJob) => {
    try {
      if (!token) { setError("Not authenticated"); return; }
      await apiFetch(`/api/scheduled-emails/${encodeURIComponent(job.id)}`, { method: "DELETE", authToken: token });
      setInfo("Scheduled message removed.");
      loadScheduled();
    } catch (e: any) { setError(e?.message || "Failed to remove"); }
  };

  // ── Render ─────────────────────────────────────────────────────────────────
  const mismatchedAttendees = useMemo(
    () => selectedAttendeeIds.filter((id) => {
      const a = attendees.find((x) => x.id === id);
      return a && a.pref !== "whatsapp" && a.pref !== "both";
    }),
    [attendees, selectedAttendeeIds]
  );

  return (
    <div className="max-w-3xl 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">
            <MessageCircle className="w-5 h-5 text-brand-600" />
          </div>
          <h1 className="text-2xl font-semibold text-gray-900">WhatsApp Attendees</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>
      )}

      {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>}

      {/* Tabs */}
      <div className="mb-4 flex items-center gap-2 flex-wrap">
        {(["attendees", "automations", "broadcasts", "scheduled"] as const).map((t) => (
          <label key={t} className={`px-3 py-1.5 text-sm rounded border cursor-pointer ${tab === t ? "bg-green-600 text-white border-green-600" : "bg-white text-gray-800 border-gray-200"}`}>
            <input type="radio" name="waTab" value={t} className="hidden" checked={tab === t} onChange={() => setTab(t)} />
            {t.charAt(0).toUpperCase() + t.slice(1)}
          </label>
        ))}
      </div>

      {/* ── Attendees Tab ── */}
      {tab === "attendees" && (
        <div className="border rounded-xl p-4 bg-white shadow-sm">
          <div className="grid gap-3">
            <div>
              <label className="block text-xs text-gray-600 mb-1">Event</label>
              <div className="flex gap-2 items-center">
                <select className="border rounded px-3 py-2 text-sm flex-1 min-w-0" value={eventId} onChange={(e) => setEventId(e.target.value)}>
                  <option value="">Select an event…</option>
                  {events.map((ev) => (
                    <option key={ev.id} value={ev.id}>{ev.title}{ev.endDate && new Date(ev.endDate) < new Date() ? " (past)" : ""}</option>
                  ))}
                </select>
                {loadingEvents && <span className="text-xs text-gray-500">Loading…</span>}
              </div>
              <label className="flex items-center gap-1.5 text-xs text-gray-500 mt-1 cursor-pointer">
                <input type="checkbox" checked={evIncludePast} onChange={(e) => setEvIncludePast(e.target.checked)} />
                Include past events
              </label>
            </div>

            <div className="grid sm:grid-cols-3 gap-3">
              <div>
                <div className="flex items-center justify-between">
                  <label className="block text-xs text-gray-600 mb-1">Template</label>
                  <button type="button" className="text-[11px] text-gray-600 hover:text-gray-900 inline-flex items-center gap-1" onClick={() => setShowInfo(true)}>
                    <span className="inline-flex items-center justify-center w-4 h-4 rounded-full border border-gray-300 text-[10px]">i</span>
                    Info
                  </button>
                </div>
                <select className="w-full border rounded px-3 py-2 text-sm" value={templateKey} onChange={(e) => setTemplateKey(e.target.value as any)}>
                  <option value="custom">Custom message</option>
                  <option value="payment_reminder">Payment reminder</option>
                  <option value="event_reminder">Event reminder</option>
                  <option value="tickets">Send ticket PDFs</option>
                </select>
              </div>
              <div className="sm:col-span-2">
                <div className="text-[11px] text-gray-500 mt-6">
                  Placeholders: {"{{name}}"}, {"{{event.title}}"}, {"{{event.start}}"}, {"{{balance}}"}, {"{{payment.link}}"}
                </div>
              </div>
            </div>

            {showInfo && (
              <div className="fixed inset-0 z-20">
                <div className="absolute inset-0 bg-black/30" onClick={() => setShowInfo(false)} />
                <div className="absolute inset-0 flex items-center justify-center p-4">
                  <div className="w-full max-w-lg bg-white rounded-lg shadow-lg border p-4">
                    <div className="flex items-center justify-between mb-2">
                      <h3 className="text-sm font-semibold">Dynamic parameters</h3>
                      <button type="button" className="text-xs px-2 py-1 rounded bg-gray-100 hover:bg-gray-200" onClick={() => setShowInfo(false)}>Close</button>
                    </div>
                    <div className="text-[12px] text-gray-700 break-words">
                      <p className="mb-2">Personalize your message per recipient using these placeholders.</p>
                      <ul className="list-disc pl-5 space-y-1 mb-2">
                        <li><code>{"{{name}}"}</code> — attendee&apos;s name.</li>
                        <li><code>{"{{event.title}}"}</code> — the event title.</li>
                        <li><code>{"{{event.start}}"}</code> — the event start date/time.</li>
                        <li><code>{"{{balance}}"}</code> — outstanding balance for the event.</li>
                        <li><code>{"{{payment.link}}"}</code> — a direct Yoco payment link for the attendee's outstanding balance (generated per recipient when sending).</li>
                      </ul>
                      <p className="text-[11px] text-gray-500 mt-2">
                        Preference indicators: <span className="text-green-700 bg-green-50 px-1 rounded">WA</span> = WhatsApp only,{" "}
                        <span className="text-green-700 bg-green-50 px-1 rounded">both</span> = WhatsApp + Email,{" "}
                        <span className="text-amber-700 bg-amber-50 px-1 rounded">email</span> = Email only (will still receive message).
                      </p>
                    </div>
                  </div>
                </div>
              </div>
            )}

            <div className="grid sm:grid-cols-2 gap-3">
              <div>
                <label className="block text-xs text-gray-600 mb-1">Payment status filter</label>
                <select className="w-full border rounded px-3 py-2 text-sm" value={status} onChange={(e) => setStatus(e.target.value as any)}>
                  <option value="any">Any</option>
                  <option value="paid">Paid</option>
                  <option value="unpaid">Unpaid (pending or partial)</option>
                  <option value="partial_paid">Partial paid</option>
                  <option value="cancelled">Cancelled</option>
                </select>
              </div>
            </div>

            {templateKey !== "tickets" ? (
              <div>
                <label className="block text-xs text-gray-600 mb-1">Message</label>
                <textarea className="w-full border rounded px-3 py-2 text-sm" rows={8} value={message}
                  onChange={(e) => { setMessage(e.target.value); setMessageDirty(true); }}
                  placeholder="Write your WhatsApp message to attendees..." />
              </div>
            ) : (
              <div className="p-3 border rounded bg-gray-50 text-sm text-gray-700">
                This will send each selected attendee their ticket PDF(s) for this event via WhatsApp.
              </div>
            )}

            <div className="grid sm:grid-cols-2 gap-3">
              <div>
                <label className="block text-xs text-gray-600 mb-1">Attendees</label>
                <AttendeesCheckboxDropdown attendees={attendees} loading={loadingAttendees} selectedIds={selectedAttendeeIds} onChange={setSelectedAttendeeIds} channel="whatsapp" />
                <div className="text-[11px] text-gray-500 mt-1">Attendees with WhatsApp/both preference are pre-selected.</div>
              </div>
              <div>
                <label className="block text-xs text-gray-600 mb-1">Send at (optional)</label>
                <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={scheduledAtLocal} onChange={(e) => setScheduledAtLocal(e.target.value)} />
                <div className="text-[10px] text-gray-500 mt-1">Leave empty to send immediately.</div>
              </div>
            </div>

            {mismatchedAttendees.length > 0 && (
              <div className="p-3 border rounded bg-amber-50 text-amber-800 text-xs">
                <strong>{mismatchedAttendees.length} selected attendee(s)</strong> prefer email only — they will still receive this message but it&apos;s not their preferred channel.
              </div>
            )}

            <div className="flex items-center flex-wrap gap-2">
              <button type="button" disabled={sending} className="px-3 py-1.5 text-sm rounded border bg-white hover:bg-gray-50" onClick={onPreview}>
                Preview recipients
              </button>
              <button type="button" disabled={sending} className="px-3 py-1.5 text-sm rounded bg-green-600 text-white hover:bg-green-700 disabled:opacity-50" onClick={onSend}>
                {sending ? "Sending…" : "Send now"}
              </button>
              <button type="button" disabled={sending || !scheduledAtLocal} className="px-3 py-1.5 text-sm rounded bg-emerald-600 text-white hover:bg-emerald-700 disabled:opacity-50" onClick={onScheduleSend}>
                Schedule send
              </button>
              {previewCount != null && <span className="text-xs text-gray-600">Preview: {previewCount} recipient(s)</span>}
            </div>

            {previewSample && previewSample.length > 0 && (
              <div className="mt-2">
                <div className="text-xs text-gray-600 mb-1">First {previewSample.length} recipient(s):</div>
                <ul className="text-xs text-gray-800 list-disc pl-5 space-y-0.5">
                  {previewSample.map((r, idx) => (
                    <li key={idx}>{r.name ? `${r.name} (${r.phone})` : r.phone}</li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        </div>
      )}

      {/* ── Automations Tab ── */}
      {tab === "automations" && (
        <div className="border rounded-xl p-4 bg-white shadow-sm">
          <WAAutomationsPanel events={events} token={token} onInfo={setInfo} onError={setError} />
        </div>
      )}

      {/* ── Broadcasts Tab ── */}
      {tab === "broadcasts" && (
        <div className="border rounded-xl p-4 bg-white shadow-sm">
          <div className="grid gap-3">
            <div className="grid sm:grid-cols-2 gap-3">
              <div>
                <label className="block text-xs text-gray-600 mb-1">Users (optional)</label>
                <AttendeesCheckboxDropdown attendees={users} loading={loadingUsers} selectedIds={selectedUserIds} onChange={setSelectedUserIds} channel="whatsapp" />
                <div className="text-[11px] text-gray-500 mb-1">Only users with phone numbers shown. Green = WhatsApp/both preference.</div>
              </div>
              <div>
                <label className="block text-xs text-gray-600 mb-1">Event (optional for placeholders)</label>
                <select className="w-full border rounded px-3 py-2 text-sm" value={broadcastEventId} onChange={(e) => setBroadcastEventId(e.target.value)}>
                  <option value="">No event</option>
                  {events.map((ev) => (
                    <option key={ev.id} value={ev.id}>{ev.title}</option>
                  ))}
                </select>
              </div>
            </div>

            {selectedUserIds.length > 0 && (
              <PrefWarning attendees={users} selectedIds={selectedUserIds} channel="whatsapp" />
            )}

            <div>
              <label className="block text-xs text-gray-600 mb-1">Message</label>
              <textarea className="w-full border rounded px-3 py-2 text-sm" rows={8} value={broadcastMessage}
                onChange={(e) => setBroadcastMessage(e.target.value)}
                placeholder="Write your message... Use {{name}}, {{event.title}}, {{event.start}}, {{event.link}}" />
            </div>

            <div>
              <label className="block text-xs text-gray-600 mb-1">Additional phone numbers (one per line)</label>
              <textarea className="w-full border rounded px-3 py-2 text-sm" rows={4} value={broadcastPhones}
                onChange={(e) => setBroadcastPhones(e.target.value)}
                placeholder={`0821234567\nJane Doe <0721234567>\n27831234567`} />
              <div className="text-[11px] text-gray-500 mt-1">Formats: 0821234567 or Name &lt;0821234567&gt;</div>
            </div>

            <div>
              <label className="block text-xs text-gray-600 mb-1">Send at (optional)</label>
              <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={broadcastScheduledAtLocal} onChange={(e) => setBroadcastScheduledAtLocal(e.target.value)} />
              <div className="text-[10px] text-gray-500 mt-1">Leave empty to send immediately.</div>
            </div>

            <div className="flex items-center flex-wrap gap-2">
              <button type="button" className="px-3 py-1.5 text-sm rounded border bg-white hover:bg-gray-50" onClick={async () => {
                try {
                  setError(null); setInfo(null); setBroadcastPreviewCount(null); setBroadcastPreviewSample(null);
                  if (!token) { setError("Not authenticated"); return; }
                  const res = await apiFetch(`/api/whatsapp-broadcasts/preview`, { method: "POST", authToken: token, body: { userIds: selectedUserIds, phones: broadcastPhones, eventId: broadcastEventId || undefined } });
                  setBroadcastPreviewCount(res?.matched ?? 0);
                  setBroadcastPreviewSample(Array.isArray(res?.recipients) ? res.recipients : null);
                  setInfo(`Matched ${res?.matched ?? 0} recipient(s).`);
                } catch (e: any) { setError(e?.message || "Failed to preview"); }
              }}>Preview recipients</button>

              <button type="button" className="px-3 py-1.5 text-sm rounded bg-green-600 text-white hover:bg-green-700 disabled:opacity-50" onClick={async () => {
                try {
                  setError(null); setInfo(null);
                  if (!token) { setError("Not authenticated"); return; }
                  if (!broadcastMessage.trim()) { setError("Message is required"); return; }
                  const res = await apiFetch(`/api/whatsapp-broadcasts/send`, { method: "POST", authToken: token, body: { message: broadcastMessage, userIds: selectedUserIds, phones: broadcastPhones, eventId: broadcastEventId || undefined } });
                  setInfo(`Sent ${res?.sent ?? 0} out of ${res?.matched ?? 0} recipient(s).`);
                  resetBroadcastForm();
                } catch (e: any) { setError(e?.message || "Failed to send"); }
              }}>Send now</button>

              <button type="button" disabled={!broadcastScheduledAtLocal} className="px-3 py-1.5 text-sm rounded bg-emerald-600 text-white hover:bg-emerald-700 disabled:opacity-50" onClick={async () => {
                try {
                  setError(null); setInfo(null);
                  if (!token) { setError("Not authenticated"); return; }
                  if (!broadcastMessage.trim()) { setError("Message is required"); return; }
                  const whenIso = new Date(broadcastScheduledAtLocal).toISOString();
                  const res = await apiFetch(`/api/whatsapp-broadcasts/schedule`, { method: "POST", authToken: token, body: { scheduledAt: whenIso, message: broadcastMessage, userIds: selectedUserIds, phones: broadcastPhones, eventId: broadcastEventId || undefined } });
                  if (res?.job?.id) setInfo("WhatsApp broadcast scheduled."); else setInfo("Scheduled.");
                  resetBroadcastForm();
                } catch (e: any) { setError(e?.message || "Failed to schedule broadcast"); }
              }}>Schedule send</button>

              {broadcastPreviewCount != null && <span className="text-xs text-gray-600">Preview: {broadcastPreviewCount} recipient(s)</span>}
            </div>

            {broadcastPreviewSample && broadcastPreviewSample.length > 0 && (
              <div className="mt-2">
                <div className="text-xs text-gray-600 mb-1">First {broadcastPreviewSample.length} recipient(s):</div>
                <ul className="text-xs text-gray-800 list-disc pl-5 space-y-0.5">
                  {broadcastPreviewSample.map((r, idx) => (
                    <li key={idx}>{r.name ? `${r.name} (${r.phone})` : r.phone}</li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        </div>
      )}

      {/* ── Scheduled Tab ── */}
      {tab === "scheduled" && (
        <div className="border rounded-xl p-4 bg-white shadow-sm">
          <div className="flex items-center justify-between mb-3">
            <h2 className="text-lg font-medium">Scheduled WhatsApp Messages</h2>
            <button type="button" className="text-sm px-2 py-1 rounded border bg-white hover:bg-gray-50" onClick={loadScheduled}>Refresh</button>
          </div>
          {loadingScheduled ? (
            <div className="text-sm text-gray-600">Loading…</div>
          ) : scheduled.length === 0 ? (
            <div className="text-sm text-gray-600">No scheduled WhatsApp messages. Sent items are cleared 24 hours after sending.</div>
          ) : (
            <ul className="divide-y border rounded">
              {scheduled.map((job) => (
                <li key={job.id} className="p-3 flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <div className="text-sm font-medium text-gray-900 flex items-center gap-2">
                      <span className="inline-block px-2 py-0.5 text-xs rounded border bg-green-50 text-green-700">{job.broadcast ? "broadcast" : "attendees"}</span>
                      <span className="truncate text-gray-700">{job.payload?.message ? String(job.payload.message).slice(0, 60) + (String(job.payload.message).length > 60 ? "…" : "") : "(no message)"}</span>
                    </div>
                    <div className="text-xs text-gray-600 mt-1">
                      <span className="mr-2">To: {job.recipient || "Unknown recipients"}</span>
                    </div>
                    <div className="text-xs text-gray-600 mt-1">
                      <span className="mr-2">Status: {job.status}</span>
                      <span className="mr-2">Scheduled: {(() => { try { return new Date(job.scheduledAt).toLocaleString(); } catch { return job.scheduledAt; } })()}</span>
                      {job.sentAt && <span>Sent: {(() => { try { return new Date(job.sentAt!).toLocaleString(); } catch { return job.sentAt; } })()}</span>}
                      {job.lastError && <span className="ml-2 text-red-600">Error: {job.lastError}</span>}
                    </div>
                  </div>
                  <div className="flex items-center gap-2 shrink-0">
                    <button type="button" disabled={job.status !== "queued"} className="px-2 py-1 text-xs rounded border bg-white hover:bg-gray-50 disabled:opacity-50"
                      onClick={() => { setEditing(job); setEditMessage(job.payload?.message || ""); try { setEditWhen(toLocalInputValue(new Date(job.scheduledAt))); } catch { setEditWhen(""); } }}>
                      Edit
                    </button>
                    <button type="button" disabled={job.status !== "queued"} className="px-2 py-1 text-xs rounded border bg-white hover:bg-gray-50 disabled:opacity-50" onClick={() => removeJob(job)}>
                      Remove
                    </button>
                  </div>
                </li>
              ))}
            </ul>
          )}

          {editing && (
            <div className="fixed inset-0 z-20">
              <div className="absolute inset-0 bg-black/30" onClick={() => setEditing(null)} />
              <div className="absolute inset-0 flex items-center justify-center p-4">
                <div className="w-full max-w-lg bg-white rounded-lg shadow-lg border p-4">
                  <div className="flex items-center justify-between mb-2">
                    <h3 className="text-sm font-semibold">Edit scheduled WhatsApp message</h3>
                    <button type="button" className="text-xs px-2 py-1 rounded bg-gray-100 hover:bg-gray-200" onClick={() => setEditing(null)}>Close</button>
                  </div>
                  <div className="grid gap-3">
                    <div>
                      <label className="block text-xs text-gray-600 mb-1">Message</label>
                      <textarea className="w-full border rounded px-3 py-2 text-sm" rows={6} value={editMessage} onChange={(e) => setEditMessage(e.target.value)} />
                    </div>
                    <div>
                      <label className="block text-xs text-gray-600 mb-1">Send at</label>
                      <input className="w-full border rounded px-3 py-2 text-sm" type="datetime-local" value={editWhen} onChange={(e) => setEditWhen(e.target.value)} />
                    </div>
                    <div className="flex items-center gap-2">
                      <button type="button" disabled={savingEdit} className="px-3 py-1.5 text-sm rounded bg-green-600 text-white hover:bg-green-700 disabled:opacity-50" onClick={saveEdit}>
                        {savingEdit ? "Saving…" : "Save changes"}
                      </button>
                      <button type="button" className="px-3 py-1.5 text-sm rounded border bg-white hover:bg-gray-50" onClick={() => setEditing(null)}>Cancel</button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}