import { useState, useEffect, useMemo } from "react";
import { useSearchParams } from "react-router-dom";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import { useToast } from "@/hooks/use-toast";
import { useGoogleDrive } from "@/hooks/useGoogleDrive";
import { Calendar as CalIcon, Plus, ChevronLeft, ChevronRight, Lock, Clock, MoreHorizontal, Edit, Trash2, Download, Loader2, Shield, Eye, EyeOff, Users, Building2, RefreshCw, HardDrive, ListChecks, Search } from "lucide-react";
import { Switch } from "@/components/ui/switch";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Checkbox } from "@/components/ui/checkbox";
import { fetchAndParseCalendar, validateCalendarUrl } from "@/lib/calendarImportUtils";
import {
  startOfMonth, endOfMonth, startOfWeek, endOfWeek, eachDayOfInterval,
  format, isSameMonth, isSameDay, isToday, addDays, addWeeks, addMonths, subMonths,
  differenceInDays, parseISO
} from "date-fns";
import { formatInTimeZone, toDate } from "date-fns-tz";

const APP_TZ = "America/New_York";

// Convert a UTC ISO timestamp from DB to a "YYYY-MM-DDTHH:mm" string in EST/EDT
// suitable for <input type="datetime-local"> values.
const utcToLocalInput = (iso?: string | null) => {
  if (!iso) return "";
  try {
    return formatInTimeZone(new Date(iso), APP_TZ, "yyyy-MM-dd'T'HH:mm");
  } catch {
    return iso?.slice(0, 16) || "";
  }
};

// Convert a local datetime-local string ("YYYY-MM-DDTHH:mm") entered by the user
// (interpreted as EST/EDT) into a UTC ISO string for storage.
const localInputToUtc = (val?: string | null) => {
  if (!val) return null;
  // Date-only (YYYY-MM-DD) → keep as-is for all_day events
  if (/^\d{4}-\d{2}-\d{2}$/.test(val)) return val;
  try {
    return toDate(val, { timeZone: APP_TZ }).toISOString();
  } catch {
    return val;
  }
};

// Safely encode a public storage URL so spaces/special chars in old paths still resolve.
const safeFileUrl = (url?: string | null) => {
  if (!url) return "";
  try {
    return encodeURI(decodeURI(url));
  } catch {
    return url;
  }
};

const eventTypeStyles: Record<string, { bg: string; text: string; label: string }> = {
  meeting: { bg: "bg-primary/10", text: "text-primary", label: "MEETING" },
  rental: { bg: "bg-secondary", text: "text-secondary-foreground", label: "RENTAL" },
  deadline: { bg: "bg-destructive/10", text: "text-destructive", label: "BLOCKED" },
  event: { bg: "bg-accent", text: "text-accent-foreground", label: "CONFIRMED" },
  maintenance: { bg: "bg-muted", text: "text-muted-foreground", label: "PENDING" },
  google_sync: { bg: "bg-muted", text: "text-muted-foreground", label: "GOOGLE" },
};

const weekdayOptions = [
  { value: 0, label: "Sunday" },
  { value: 1, label: "Monday" },
  { value: 2, label: "Tuesday" },
  { value: 3, label: "Wednesday" },
  { value: 4, label: "Thursday" },
  { value: 5, label: "Friday" },
  { value: 6, label: "Saturday" },
];

const ordinalOptions = [
  { value: "1", label: "First" },
  { value: "2", label: "Second" },
  { value: "3", label: "Third" },
  { value: "4", label: "Fourth" },
  { value: "last", label: "Last" },
];

type RecurrenceForm = {
  enabled: boolean;
  frequency: "daily" | "weekly" | "monthly" | "monthly_by_week";
  interval: number;
  endType: "count" | "date";
  occurrences: number;
  endDate: string;
  weekPosition: string;
  dayOfWeek: number;
};

const defaultRecurrence: RecurrenceForm = {
  enabled: false,
  frequency: "monthly_by_week",
  interval: 1,
  endType: "count",
  occurrences: 12,
  endDate: "",
  weekPosition: "2",
  dayOfWeek: 2,
};

const getNthWeekdayOfMonth = (year: number, month: number, dayOfWeek: number, weekPosition: string) => {
  const lastDay = new Date(year, month + 1, 0).getDate();
  if (weekPosition === "last") {
    for (let day = lastDay; day >= lastDay - 6; day--) {
      const candidate = new Date(year, month, day, 12, 0, 0);
      if (candidate.getDay() === dayOfWeek) return candidate;
    }
  }
  const occurrence = Number(weekPosition);
  for (let day = 1, seen = 0; day <= lastDay; day++) {
    const candidate = new Date(year, month, day, 12, 0, 0);
    if (candidate.getDay() === dayOfWeek && ++seen === occurrence) return candidate;
  }
  return null;
};

const generateCalendarOccurrences = (start: Date, end: Date, recurrence: RecurrenceForm) => {
  const durationMs = Math.max(0, end.getTime() - start.getTime());
  const interval = Math.max(1, recurrence.interval || 1);
  const maxCount = recurrence.endType === "count" ? Math.min(Math.max(1, recurrence.occurrences || 1), 120) : 120;
  const until = recurrence.endType === "date" && recurrence.endDate ? new Date(`${recurrence.endDate}T23:59:59`) : null;
  const occurrences: { start: Date; end: Date }[] = [];
  let current = new Date(start);

  for (let i = 0; occurrences.length < maxCount && i < 160; i++) {
    if (until && current > until) break;
    occurrences.push({ start: new Date(current), end: new Date(current.getTime() + durationMs) });

    if (recurrence.frequency === "daily") current = addDays(current, interval);
    else if (recurrence.frequency === "weekly") current = addWeeks(current, interval);
    else if (recurrence.frequency === "monthly") current = addMonths(current, interval);
    else {
      const base = addMonths(current, interval);
      const next = getNthWeekdayOfMonth(base.getFullYear(), base.getMonth(), recurrence.dayOfWeek, recurrence.weekPosition);
      if (!next) break;
      next.setHours(current.getHours(), current.getMinutes(), 0, 0);
      current = next;
    }
  }

  return occurrences;
};

type CalendarMode = "events" | "rentals" | "meetings";

const calendarModeLabels: Record<CalendarMode, string> = {
  events: "Admin Calendar",
  rentals: "Rental Calendar",
  meetings: "Meeting Calendar",
};

export default function CalendarPage({ boardAssociationIds }: { boardAssociationIds?: string[] } = {}) {
  const { toast } = useToast();
  const { user } = useAuth();
  const [searchParams] = useSearchParams();
  const drive = useGoogleDrive();
  const [events, setEvents] = useState<any[]>([]);
  const [blockedDates, setBlockedDates] = useState<any[]>([]);
  const [amenityBookings, setAmenityBookings] = useState<any[]>([]);
  const [crossAssocBlocks, setCrossAssocBlocks] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [currentMonth, setCurrentMonth] = useState(new Date());
  const [calendarMode, setCalendarMode] = useState<CalendarMode>("events");
  const [dialogOpen, setDialogOpen] = useState(false);
  const [bookingDialogOpen, setBookingDialogOpen] = useState(false);
  const [blockDialogOpen, setBlockDialogOpen] = useState(false);
  const [editing, setEditing] = useState<any>(null);
  const [form, setForm] = useState({ title: "", description: "", start_date: "", end_date: "", all_day: false, event_type: "meeting", location: "", association_id: "", is_blocked: false, visibility: ["admin"] as string[], attachment_url: "" as string | null, attachment_name: "" as string | null });
  const [bookingForm, setBookingForm] = useState({ title: "", guest_name: "", guest_email: "", guest_phone: "", booking_date: "", start_time: "09:00", end_time: "10:00", location: "", notes: "", association_id: "", amenity_id: "", is_public_event: false, event_title: "", event_description: "", payment_amount: "", recurrence_type: "none", recurrence_interval: "1", recurrence_end_date: "", recurrence_count: "", recurrence_day_of_week: "2", recurrence_week_position: "1" });
  const [bookingEditing, setBookingEditing] = useState<any>(null);
  const [viewDialogOpen, setViewDialogOpen] = useState(false);
  const [viewing, setViewing] = useState<any>(null);
  const [uploadingAttachment, setUploadingAttachment] = useState(false);
  const [blockForm, setBlockForm] = useState({ title: "", start_date: "", end_date: "", reason: "" });
  const [gcalDialogOpen, setGcalDialogOpen] = useState(false);
  const [gcalUrl, setGcalUrl] = useState("");
  const [gcalImporting, setGcalImporting] = useState(false);
  const [gcalPreview, setGcalPreview] = useState<any[]>([]);
  const [associations, setAssociations] = useState<{ id: string; name: string }[]>([]);
  const [dialogTab, setDialogTab] = useState<"details" | "recurrence">("details");
  const [dateRequestDialogOpen, setDateRequestDialogOpen] = useState(false);
  const [dateRequestForm, setDateRequestForm] = useState({ date: "", description: "" });
  const [dateRequestLoading, setDateRequestLoading] = useState(false);
  const [gcalSyncing, setGcalSyncing] = useState(false);
  const [manageDialogOpen, setManageDialogOpen] = useState(false);
  const [manageSearch, setManageSearch] = useState("");
  const [manageSourceFilter, setManageSourceFilter] = useState<string>("all");
  const [manageAssocFilter, setManageAssocFilter] = useState<string>("all");
  const [manageFromDate, setManageFromDate] = useState<string>("");
  const [manageToDate, setManageToDate] = useState<string>("");
  const [manageSelected, setManageSelected] = useState<Set<string>>(new Set());
  const [bulkDeleting, setBulkDeleting] = useState(false);
  const [bookingAmenities, setBookingAmenities] = useState<any[]>([]);
  const [recurrence, setRecurrence] = useState<RecurrenceForm>(defaultRecurrence);

  const isBoardView = !!boardAssociationIds?.length;

  const fetchData = async () => {
    setLoading(true);
    let evtQuery = supabase.from("calendar_events").select("*, associations(name)").order("start_date");
    let blkQuery = supabase.from("blocked_dates").select("*").order("start_date");
    let bookingQuery = (supabase as any).from("amenity_bookings").select("*, amenities(name)").order("booking_date");
    if (isBoardView) {
      evtQuery = evtQuery.in("association_id", boardAssociationIds!);
      blkQuery = blkQuery.in("association_id", boardAssociationIds!);
      bookingQuery = bookingQuery.in("association_id", boardAssociationIds!);
    }
    const [evtRes, blkRes, bookingRes] = await Promise.all([evtQuery, blkQuery, bookingQuery]);
    setEvents(evtRes.data || []);
    setBlockedDates(blkRes.data || []);
    setAmenityBookings(bookingRes.data || []);

    // Board members: fetch dates booked by other associations (date/time only)
    if (isBoardView) {
      const { data: crossData } = await (supabase as any).rpc("get_cross_association_blocked_dates", {
        _association_ids: boardAssociationIds,
      });
      setCrossAssocBlocks(crossData || []);
    } else {
      setCrossAssocBlocks([]);
    }
    setLoading(false);
  };

  const fetchAssociations = async () => {
    let q = supabase.from("associations").select("id, name").eq("status", "active").order("name");
    if (isBoardView) q = q.in("id", boardAssociationIds!);
    const { data } = await q;
    setAssociations(data || []);
  };

  const fetchBookingAmenities = async () => {
    let q = (supabase as any).from("amenities").select("id, name, association_id, amenity_type").eq("is_active", true).in("amenity_type", ["booking", "rental_calendar", "meeting_calendar"]).order("name");
    if (isBoardView) q = q.in("association_id", boardAssociationIds!);
    const { data } = await q;
    setBookingAmenities(data || []);
  };

  useEffect(() => { fetchData(); fetchAssociations(); fetchBookingAmenities(); }, []);

  useEffect(() => {
    const code = searchParams.get("code");
    const state = searchParams.get("state");
    if (code && state === "drive_connect") {
      drive.handleOAuthCallback(code);
    }
  }, [searchParams]);

  const calendarDays = useMemo(() => {
    const monthStart = startOfMonth(currentMonth);
    const monthEnd = endOfMonth(currentMonth);
    const start = startOfWeek(monthStart);
    const end = endOfWeek(monthEnd);
    return eachDayOfInterval({ start, end });
  }, [currentMonth]);

  /** Parse a date string anchored to noon UTC to avoid day-shift from timezone offset */
  const parseCalDate = (dateStr: string) => {
    if (!dateStr) return null;
    // For date-only strings (YYYY-MM-DD), anchor to noon to prevent day shift
    if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
      return new Date(`${dateStr}T12:00:00`);
    }
    // For datetime strings, parse as-is (local time)
    return parseISO(dateStr);
  };

  const getEventsForDay = (day: Date) => {
    return events.filter(e => {
      const eventDate = parseCalDate(e.start_date?.slice(0, 10));
      return eventDate ? isSameDay(eventDate, day) : false;
    });
  };

  const getBookingsForDay = (day: Date) => {
    const type = calendarMode === "meetings" ? "meeting" : "rental";
    return amenityBookings.filter(b => {
      if (b.booking_type !== type) return false;
      const bookingDate = parseCalDate(b.booking_date?.slice(0, 10));
      return bookingDate ? isSameDay(bookingDate, day) : false;
    });
  };

  const getBlockedForDay = (day: Date) => {
    return blockedDates.filter(b => {
      const start = parseCalDate(b.start_date?.slice(0, 10));
      const end = parseCalDate(b.end_date?.slice(0, 10));
      if (!start || !end) return false;
      const dayNoon = new Date(format(day, 'yyyy-MM-dd') + 'T12:00:00');
      return dayNoon >= start && dayNoon <= end;
    });
  };

  const getCrossBlocksForDay = (day: Date) => {
    return crossAssocBlocks.filter(b => {
      const d = parseCalDate(b.start_date?.slice(0, 10));
      return d ? isSameDay(d, day) : false;
    });
  };

  const upcomingEvents = useMemo(() => {
    const now = new Date();
    const allItems = [
      ...events.filter(e => {
        const d = parseCalDate(e.start_date?.slice(0, 10));
        return d && d >= now;
      }).map(e => {
        const d = parseCalDate(e.start_date) || new Date();
        return { ...e, type: "event", eventDate: d, daysAway: differenceInDays(d, now) };
      }),
      ...blockedDates.filter(b => {
        const d = parseCalDate(b.start_date?.slice(0, 10));
        return d && d >= now;
      }).map(b => {
        const d = parseCalDate(b.start_date) || new Date();
        return { ...b, type: "blocked", event_type: "deadline", eventDate: d, daysAway: differenceInDays(d, now) };
      }),
    ];
    return allItems.sort((a, b) => a.eventDate.getTime() - b.eventDate.getTime()).slice(0, 6);
  }, [events, blockedDates]);

  const defaultForm = { title: "", description: "", start_date: "", end_date: "", all_day: false, event_type: "meeting", location: "", association_id: "", is_blocked: false, visibility: ["admin"] as string[], attachment_url: null as string | null, attachment_name: null as string | null };
  const openNew = (initialDate?: string) => { setEditing(null); setRecurrence(defaultRecurrence); setForm({ ...defaultForm, start_date: initialDate || "" }); setDialogTab("details"); setDialogOpen(true); };
  const openEdit = (e: any) => { setEditing(e); setRecurrence(defaultRecurrence); setForm({ title: e.title, description: e.description || "", start_date: e.all_day ? (e.start_date?.slice(0, 10) || "") : utcToLocalInput(e.start_date), end_date: e.all_day ? (e.end_date?.slice(0, 10) || "") : utcToLocalInput(e.end_date), all_day: e.all_day || false, event_type: e.event_type || "meeting", location: e.location || "", association_id: e.association_id || "", is_blocked: e.is_blocked || false, visibility: e.visibility || ["admin"], attachment_url: e.attachment_url || null, attachment_name: e.attachment_name || null }); setDialogTab("details"); setDialogOpen(true); };
  const openView = (e: any) => { setViewing(e); setViewDialogOpen(true); };

  const defaultBookingForm = { title: "", guest_name: "", guest_email: "", guest_phone: "", booking_date: "", start_time: "09:00", end_time: "10:00", location: "", notes: "", association_id: "", amenity_id: "", is_public_event: false, event_title: "", event_description: "", payment_amount: "", recurrence_type: "none", recurrence_interval: "1", recurrence_end_date: "", recurrence_count: "", recurrence_day_of_week: "2", recurrence_week_position: "1" };
  const openBookingNew = (initialDate?: string) => { setBookingEditing(null); setBookingForm({ ...defaultBookingForm, booking_date: initialDate || "" }); setBookingDialogOpen(true); };
  const openBookingEdit = (booking: any) => {
    setBookingEditing(booking);
    setBookingForm({
      title: booking.title || "",
      guest_name: booking.guest_name || "",
      guest_email: booking.guest_email || "",
      guest_phone: booking.guest_phone || "",
      booking_date: booking.booking_date || "",
      start_time: booking.start_time?.slice(0, 5) || "09:00",
      end_time: booking.end_time?.slice(0, 5) || "10:00",
      location: booking.location || "",
      notes: booking.notes || "",
      association_id: booking.association_id || "",
      amenity_id: booking.amenity_id || "",
      is_public_event: !!booking.is_public_event,
      event_title: booking.event_title || "",
      event_description: booking.event_description || "",
      payment_amount: booking.payment_amount_cents ? (booking.payment_amount_cents / 100).toFixed(2) : "",
      recurrence_type: "none",
      recurrence_interval: "1",
      recurrence_end_date: "",
      recurrence_count: "",
      recurrence_day_of_week: "2",
      recurrence_week_position: "1",
    });
    setBookingDialogOpen(true);
  };

  const handleSave = async () => {
    if (!form.title.trim()) { toast({ title: "Error", description: "Title is required", variant: "destructive" }); return; }
    if (!form.start_date) { toast({ title: "Error", description: "Date is required", variant: "destructive" }); return; }
    
    let finalAssocId = form.association_id;
    if (!finalAssocId || finalAssocId === "__public__") {
      const { data: a } = await supabase.from("associations").select("id").eq("status", "active").limit(1);
      if (!a?.length) { toast({ title: "Error", description: "Create an association first", variant: "destructive" }); return; }
      finalAssocId = a[0].id;
    }
    const startVal = form.all_day ? form.start_date : localInputToUtc(form.start_date);
    const endVal = form.all_day ? (form.end_date || form.start_date) : localInputToUtc(form.end_date || form.start_date);
    const payload: any = { title: form.title, description: form.description || null, start_date: startVal, end_date: endVal, all_day: form.all_day, event_type: form.event_type, location: form.location || null, association_id: finalAssocId, is_blocked: form.is_blocked, visibility: form.visibility, attachment_url: form.attachment_url || null, attachment_name: form.attachment_name || null, created_by: user?.id || null };
    if (editing) {
      const { error } = await supabase.from("calendar_events").update(payload).eq("id", editing.id);
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      toast({ title: "Updated" });
    } else {
      let insertPayload: any = payload;
      if (recurrence.enabled) {
        const baseStart = form.all_day ? new Date(`${form.start_date}T12:00:00`) : new Date(startVal as string);
        const baseEnd = form.all_day ? new Date(`${form.end_date || form.start_date}T12:00:00`) : new Date(endVal as string);
        insertPayload = generateCalendarOccurrences(baseStart, baseEnd, recurrence).map(({ start, end }) => ({
          ...payload,
          start_date: form.all_day ? format(start, "yyyy-MM-dd") : start.toISOString(),
          end_date: form.all_day ? format(end, "yyyy-MM-dd") : end.toISOString(),
        }));
      }
      const { error } = await supabase.from("calendar_events").insert(insertPayload);
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      toast({ title: recurrence.enabled ? "Recurring events created" : "Event created" });
    }
    setDialogOpen(false); fetchData();
  };

  const handleBookingSave = async () => {
    if (!bookingForm.title.trim() || !bookingForm.booking_date) { toast({ title: "Error", description: "Title and date are required", variant: "destructive" }); return; }
    let finalAssocId = bookingForm.association_id;
    if (!finalAssocId) finalAssocId = associations[0]?.id || "";
    if (!finalAssocId) { toast({ title: "Error", description: "Select an association", variant: "destructive" }); return; }
    const matchingAmenity = bookingAmenities.find(a => a.id === bookingForm.amenity_id) || bookingAmenities.find(a => a.association_id === finalAssocId);
    if (!matchingAmenity) { toast({ title: "Error", description: "Create a booking amenity for this association first", variant: "destructive" }); return; }
    const payload: any = {
      association_id: finalAssocId,
      amenity_id: matchingAmenity.id,
      booking_type: calendarMode === "meetings" ? "meeting" : "rental",
      title: bookingForm.title.trim(),
      guest_name: bookingForm.guest_name || bookingForm.title.trim(),
      guest_email: bookingForm.guest_email || null,
      guest_phone: bookingForm.guest_phone || null,
      booking_date: bookingForm.booking_date,
      start_time: bookingForm.start_time || null,
      end_time: bookingForm.end_time || null,
      location: bookingForm.location || null,
      notes: bookingForm.notes || null,
      status: "confirmed",
      created_by: user?.id || null,
      is_public_event: !!bookingForm.is_public_event,
      event_title: bookingForm.is_public_event ? (bookingForm.event_title || bookingForm.title.trim()) : null,
      event_description: bookingForm.is_public_event ? (bookingForm.event_description || null) : null,
      payment_amount_cents: bookingForm.payment_amount ? Math.round(parseFloat(bookingForm.payment_amount) * 100) : 0,
    };

    // Build list of dates for recurrence (only for new bookings)
    const buildDates = (): string[] => {
      const start = bookingForm.booking_date;
      if (bookingEditing || bookingForm.recurrence_type === "none") return [start];
      const interval = Math.max(1, parseInt(bookingForm.recurrence_interval || "1", 10));
      const maxCount = bookingForm.recurrence_count ? Math.max(1, parseInt(bookingForm.recurrence_count, 10)) : 0;
      const endDate = bookingForm.recurrence_end_date || "";
      const dates: string[] = [];
      const [y, m, d] = start.split("-").map(Number);
      const cursor = new Date(y, (m || 1) - 1, d || 1, 12, 0, 0);
      const limitDate = endDate ? new Date(...endDate.split("-").map(Number).map((v, i) => i === 1 ? v - 1 : v) as [number, number, number]) : null;
      const hardCap = 365;
      const fmt = (dt: Date) => `${dt.getFullYear()}-${String(dt.getMonth() + 1).padStart(2, "0")}-${String(dt.getDate()).padStart(2, "0")}`;
      const type = bookingForm.recurrence_type;
      const dayOfWeek = parseInt(bookingForm.recurrence_day_of_week || "0", 10);
      const weekPos = bookingForm.recurrence_week_position || "1";

      // Nth-weekday-of-month series (e.g. "first Tuesday of every month")
      if (type === "monthly_by_week" || type === "monthly_last_day") {
        let monthCursor = new Date(y, (m || 1) - 1, 1, 12, 0, 0);
        while (dates.length < hardCap) {
          let candidate: Date | null = null;
          if (type === "monthly_last_day") {
            candidate = new Date(monthCursor.getFullYear(), monthCursor.getMonth() + 1, 0, 12, 0, 0);
          } else {
            candidate = getNthWeekdayOfMonth(monthCursor.getFullYear(), monthCursor.getMonth(), dayOfWeek, weekPos);
          }
          if (!candidate) break;
          if (candidate >= cursor) {
            if (limitDate && candidate > limitDate) break;
            dates.push(fmt(candidate));
            if (maxCount && dates.length >= maxCount) break;
          }
          monthCursor.setMonth(monthCursor.getMonth() + interval);
          if (!maxCount && !endDate && dates.length >= 1) break;
        }
        return dates;
      }

      while (dates.length < hardCap) {
        dates.push(fmt(cursor));
        if (maxCount && dates.length >= maxCount) break;
        if (type === "daily") cursor.setDate(cursor.getDate() + interval);
        else if (type === "weekly") cursor.setDate(cursor.getDate() + 7 * interval);
        else if (type === "biweekly") cursor.setDate(cursor.getDate() + 14);
        else if (type === "monthly") cursor.setMonth(cursor.getMonth() + interval);
        else break;
        if (limitDate && cursor > limitDate) break;
        if (!maxCount && !endDate) break;
      }
      return dates;
    };

    if (bookingEditing) {
      const { error } = await (supabase as any).from("amenity_bookings").update(payload).eq("id", bookingEditing.id);
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      toast({ title: "Booking updated" });
    } else {
      const dates = buildDates();
      const rows = dates.map(d => ({ ...payload, booking_date: d }));
      const { error } = await (supabase as any).from("amenity_bookings").insert(rows);
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      toast({ title: rows.length > 1 ? `${rows.length} recurring bookings created` : "Booking created" });
    }
    setBookingDialogOpen(false); fetchData();
  };

  const handleBookingDelete = async (id: string) => {
    await (supabase as any).from("amenity_bookings").delete().eq("id", id);
    toast({ title: "Booking deleted" }); fetchData();
  };

  const handleSendPaymentLink = async () => {
    if (!bookingEditing?.id) { toast({ title: "Save the booking first", variant: "destructive" }); return; }
    const amt = parseFloat(bookingForm.payment_amount || "0");
    if (!amt || amt <= 0) { toast({ title: "Enter a payment amount", variant: "destructive" }); return; }
    if (!bookingForm.guest_email) { toast({ title: "Contact email required to send link", variant: "destructive" }); return; }
    const { data, error } = await supabase.functions.invoke("send-booking-payment-link", {
      body: { booking_id: bookingEditing.id, amount_cents: Math.round(amt * 100) },
    });
    if (error || (data as any)?.error) { toast({ title: "Failed to send", description: error?.message || (data as any)?.error, variant: "destructive" }); return; }
    toast({ title: "Payment link sent", description: `Emailed to ${bookingForm.guest_email}` });
    fetchData();
  };

  const handleBlockSave = async () => {
    const { data: a } = await supabase.from("associations").select("id").eq("status", "active").limit(1);
    if (!a?.length) return;
    await supabase.from("blocked_dates").insert({ ...blockForm, association_id: a[0].id, created_by: user?.id || null });
    toast({ title: "Date blocked" });
    setBlockDialogOpen(false); fetchData();
  };

  const handleDelete = async (id: string) => {
    await supabase.from("calendar_events").delete().eq("id", id);
    toast({ title: "Deleted" }); fetchData();
  };

  const handleAttachmentUpload = async (file: File) => {
    if (!file) return;
    setUploadingAttachment(true);
    try {
      const rawExt = (file.name.split('.').pop() || 'bin').toLowerCase().replace(/[^a-z0-9]/g, '');
      const ext = rawExt || 'bin';
      const path = `${user?.id || 'anon'}/${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
      const { error: upErr } = await supabase.storage.from('calendar-attachments').upload(path, file, { upsert: false, contentType: file.type || undefined });
      if (upErr) throw upErr;
      const { data: pub } = supabase.storage.from('calendar-attachments').getPublicUrl(path);
      // Encode any unsafe chars in the URL (spaces, etc.) for reliable public access
      const safeUrl = encodeURI(pub.publicUrl);
      setForm(prev => ({ ...prev, attachment_url: safeUrl, attachment_name: file.name }));
      toast({ title: "Uploaded", description: file.name });
    } catch (err: any) {
      toast({ variant: "destructive", title: "Upload failed", description: err.message });
    } finally {
      setUploadingAttachment(false);
    }
  };

  const handleRemoveAttachment = () => {
    setForm(prev => ({ ...prev, attachment_url: null, attachment_name: null }));
  };

  const handleBulkDelete = async () => {
    if (manageSelected.size === 0) return;
    setBulkDeleting(true);
    try {
      const ids = Array.from(manageSelected);
      const { error } = await supabase.from("calendar_events").delete().in("id", ids);
      if (error) throw error;
      toast({ title: "Deleted", description: `${ids.length} event${ids.length === 1 ? "" : "s"} removed.` });
      setManageSelected(new Set());
      fetchData();
    } catch (err: any) {
      toast({ variant: "destructive", title: "Delete failed", description: err.message });
    } finally {
      setBulkDeleting(false);
    }
  };

  const handleDeleteAllGoogle = async () => {
    if (!confirm("Delete ALL Google-synced events? This cannot be undone.")) return;
    setBulkDeleting(true);
    try {
      const { error, count } = await supabase
        .from("calendar_events")
        .delete({ count: "exact" })
        .eq("event_type", "google_sync");
      if (error) throw error;
      toast({ title: "Google events deleted", description: `${count ?? 0} event${count === 1 ? "" : "s"} removed.` });
      setManageSelected(new Set());
      fetchData();
    } catch (err: any) {
      toast({ variant: "destructive", title: "Delete failed", description: err.message });
    } finally {
      setBulkDeleting(false);
    }
  };

  const handleGcalFetch = async () => {
    if (!validateCalendarUrl(gcalUrl)) {
      toast({ title: "Invalid URL", description: "Please enter a valid Google Calendar ICS URL.", variant: "destructive" });
      return;
    }
    setGcalImporting(true);
    try {
      const parsed = await fetchAndParseCalendar(gcalUrl);
      setGcalPreview(parsed);
      if (parsed.length === 0) toast({ title: "No events", description: "No events found in this calendar." });
    } catch (err: any) {
      toast({ title: "Import failed", description: err.message, variant: "destructive" });
    } finally {
      setGcalImporting(false);
    }
  };

  const handleGcalImport = async () => {
    if (gcalPreview.length === 0) return;
    setGcalImporting(true);
    try {
      const { data: a } = await supabase.from("associations").select("id").eq("status", "active").limit(1);
      if (!a?.length) { toast({ title: "Error", description: "Create an association first.", variant: "destructive" }); return; }
      const rows = gcalPreview.map(e => ({
        title: e.summary || "Untitled",
        description: e.description || null,
        start_date: e.startDate.toISOString(),
        end_date: e.endDate.toISOString(),
        location: e.location || null,
        event_type: "event",
        association_id: a[0].id,
      }));
      const { error } = await supabase.from("calendar_events").insert(rows);
      if (error) throw error;
      toast({ title: "Imported", description: `${rows.length} events added from Google Calendar.` });
      setGcalDialogOpen(false);
      setGcalUrl("");
      setGcalPreview([]);
      fetchData();
    } catch (err: any) {
      toast({ title: "Import failed", description: err.message, variant: "destructive" });
    } finally {
      setGcalImporting(false);
    }
  };

  const dayNames = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];

  return (
    <div className="space-y-6">
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold text-foreground">{calendarModeLabels[calendarMode]}</h1>
          <p className="text-sm text-muted-foreground mt-1">Manage schedules, rentals and amenity meetings</p>
        </div>
        {isBoardView ? (
          <Button className="gap-2" onClick={() => setDateRequestDialogOpen(true)}>
            <CalIcon className="h-4 w-4" /> Request Date
          </Button>
        ) : (
          <div className="flex gap-2">
            <Select value={calendarMode} onValueChange={(v) => setCalendarMode(v as CalendarMode)}>
              <SelectTrigger className="w-[180px]"><SelectValue /></SelectTrigger>
              <SelectContent>
                <SelectItem value="events">Admin Calendar</SelectItem>
                <SelectItem value="rentals">Rental Calendar</SelectItem>
                <SelectItem value="meetings">Meeting Calendar</SelectItem>
              </SelectContent>
            </Select>
            <Button variant="outline" className="gap-2" onClick={async () => {
              setGcalSyncing(true);
              try {
                const { data: { session } } = await supabase.auth.getSession();
                if (!session?.access_token) throw new Error("Not logged in");
                const { data, error } = await supabase.functions.invoke("sync-google-calendar", {
                  body: { action: "sync" },
                  headers: { Authorization: `Bearer ${session.access_token}` },
                });
                if (error) throw error;
                if (data?.error) throw new Error(data.error);
                toast({ title: "Sync Complete", description: `Synced ${data?.count || 0} events from Google Calendar.` });
                fetchData();
              } catch (err: any) {
                toast({ variant: "destructive", title: "Sync Failed", description: err.message });
              } finally {
                setGcalSyncing(false);
              }
            }} disabled={gcalSyncing}>
              {gcalSyncing ? <Loader2 className="h-4 w-4 animate-spin" /> : <RefreshCw className="h-4 w-4" />} Sync Google Calendar
            </Button>
            {drive.isConnected ? (
              <Button variant="ghost" className="gap-2" onClick={drive.disconnect}>
                <HardDrive className="h-4 w-4" /> Disconnect Google
              </Button>
            ) : !drive.loading ? (
              <Button variant="outline" className="gap-2" onClick={drive.connect}>
                <HardDrive className="h-4 w-4" /> Connect Google
              </Button>
            ) : null}
            <Button variant="outline" className="gap-2" onClick={() => { setGcalUrl(""); setGcalPreview([]); setGcalDialogOpen(true); }}>
              <Download className="h-4 w-4" /> Import ICS
            </Button>
            <Button variant="outline" className="gap-2" onClick={() => { setBlockForm({ title: "", start_date: "", end_date: "", reason: "" }); setBlockDialogOpen(true); }}>
              <Lock className="h-4 w-4" /> Block Date
            </Button>
            <Button variant="outline" className="gap-2" onClick={() => { setManageSelected(new Set()); setManageDialogOpen(true); }}>
              <ListChecks className="h-4 w-4" /> Manage Events
            </Button>
            <Button className="gap-2" onClick={() => calendarMode === "events" ? openNew() : openBookingNew()}><Plus className="h-4 w-4" /> {calendarMode === "events" ? "New Event" : "New Booking"}</Button>
          </div>
        )}
      </div>

      <div className="flex gap-6">
        {/* Calendar Grid */}
        <div className="flex-1">
          <div className="flex items-center gap-4 mb-4">
            <h2 className="text-xl font-bold">{format(currentMonth, "MMMM yyyy")}</h2>
            <div className="flex items-center gap-1">
              <Button variant="outline" size="icon" className="h-8 w-8" onClick={() => setCurrentMonth(subMonths(currentMonth, 1))}>
                <ChevronLeft className="h-4 w-4" />
              </Button>
              <Button variant="outline" size="sm" onClick={() => setCurrentMonth(new Date())}>Today</Button>
              <Button variant="outline" size="icon" className="h-8 w-8" onClick={() => setCurrentMonth(addMonths(currentMonth, 1))}>
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>
            <div className="ml-auto flex items-center gap-4 text-xs text-muted-foreground">
              <span className="flex items-center gap-1"><span className="w-2 h-2 rounded-full bg-red-400" /> Unavailable</span>
              <span className="flex items-center gap-1"><span className="w-2 h-2 rounded-full bg-amber-400" /> Pending</span>
              <span className="flex items-center gap-1"><span className="w-2 h-2 rounded-full bg-blue-400" /> Confirmed</span>
              <span className="flex items-center gap-1">↻ Recurring</span>
            </div>
          </div>

          <div className="border rounded-lg overflow-hidden">
            <div className="grid grid-cols-7 bg-muted/50">
              {dayNames.map(d => (
                <div key={d} className="text-center text-xs font-semibold text-muted-foreground py-2 border-b">{d}</div>
              ))}
            </div>
            <div className="grid grid-cols-7">
              {calendarDays.map((day, i) => {
                const dayEvents = calendarMode === "events" ? getEventsForDay(day) : [];
                const dayBookings = calendarMode === "events" ? [] : getBookingsForDay(day);
                const dayBlocked = getBlockedForDay(day);
                const dayCrossBlocks = getCrossBlocksForDay(day);
                const inMonth = isSameMonth(day, currentMonth);
                const today = isToday(day);
                const isBlocked = dayBlocked.length > 0;
                const hasCrossBlock = dayCrossBlocks.length > 0;
                return (
                  <div
                    key={i}
                    className={`min-h-[100px] border-b border-r p-1 relative ${
                      isBlocked && inMonth
                        ? "bg-destructive/10"
                        : hasCrossBlock && inMonth
                          ? "bg-muted"
                          : !inMonth
                            ? "bg-muted/30 text-muted-foreground/50"
                            : ""
                    }`}
                  >
                    {isBlocked && inMonth && (
                      <div className="absolute inset-0 pointer-events-none" style={{
                        backgroundImage: "repeating-linear-gradient(135deg, transparent, transparent 6px, hsl(var(--destructive) / 0.07) 6px, hsl(var(--destructive) / 0.07) 12px)",
                      }} />
                    )}
                    {!isBlocked && hasCrossBlock && inMonth && (
                      <div className="absolute inset-0 pointer-events-none" style={{
                        backgroundImage: "repeating-linear-gradient(135deg, transparent, transparent 6px, hsl(var(--muted-foreground) / 0.12) 6px, hsl(var(--muted-foreground) / 0.12) 12px)",
                      }} />
                    )}
                    <div className="relative flex items-center justify-between">
                      <span className={`text-sm font-medium w-7 h-7 flex items-center justify-center rounded-full ${today ? "bg-primary text-primary-foreground" : ""}`}>
                        {format(day, "d")}
                      </span>
                      {inMonth && dayEvents.length === 0 && !isBlocked && !isBoardView && (
                        <button
                          className="text-primary opacity-0 group-hover:opacity-100 hover:opacity-100 text-lg leading-none"
                          onClick={() => openNew(format(day, "yyyy-MM-dd'T'09:00"))}
                        >+</button>
                      )}
                    </div>
                    <div className="relative mt-1 space-y-0.5">
                      {dayBlocked.map(b => (
                        <div key={b.id} className="flex items-center gap-1 bg-destructive/15 text-destructive rounded px-1 py-0.5">
                          <Lock className="h-3 w-3 shrink-0" />
                          <span className="text-[10px] font-semibold truncate">{b.title || "BLOCKED"}</span>
                        </div>
                      ))}
                      {hasCrossBlock && !isBlocked && (
                        <div
                          className="flex items-center gap-1 bg-muted-foreground/15 text-muted-foreground rounded px-1 py-0.5"
                          title={`${dayCrossBlocks.length} booking${dayCrossBlocks.length === 1 ? "" : "s"} by another association`}
                        >
                          <Lock className="h-3 w-3 shrink-0" />
                          <span className="text-[10px] font-semibold truncate">
                            BOOKED{dayCrossBlocks.length > 1 ? ` (${dayCrossBlocks.length})` : ""}
                          </span>
                        </div>
                      )}
                      {dayBookings.slice(0, isBlocked ? 1 : 2).map(b => {
                        const style = eventTypeStyles[b.booking_type] || eventTypeStyles.rental;
                        return (
                          <div
                            key={b.id}
                            className={`${style.bg} ${style.text} text-[10px] font-semibold px-1 py-0.5 rounded truncate cursor-pointer hover:opacity-80`}
                            onClick={() => openBookingEdit(b)}
                            title={b.title || b.guest_name}
                          >
                            {(b.title || b.guest_name || "BOOKING").toUpperCase()}
                            {b.start_time && <div className="text-[9px] font-normal">{b.start_time.slice(0, 5)}</div>}
                          </div>
                        );
                      })}
                      {dayEvents.slice(0, isBlocked ? 1 : 2).map(e => {
                        const style = eventTypeStyles[e.event_type] || eventTypeStyles.event;
                        return (
                          <div
                            key={e.id}
                            className={`${style.bg} ${style.text} text-[10px] font-semibold px-1 py-0.5 rounded truncate cursor-pointer hover:opacity-80`}
                            onClick={() => isBoardView ? openView(e) : openEdit(e)}
                            title={e.title}
                          >
                            {e.event_type === "deadline" ? "UNAVAILABLE" : e.title?.toUpperCase()}
                            {e.start_date && !e.all_day && e.start_date.includes('T') && <div className="text-[9px] font-normal">{format(parseISO(e.start_date), "h:mm a")}</div>}
                          </div>
                        );
                      })}
                      {dayBookings.length > (isBlocked ? 1 : 2) && (
                        <span className="text-[10px] text-muted-foreground">+{dayBookings.length - (isBlocked ? 1 : 2)} more</span>
                      )}
                      {dayEvents.length > (isBlocked ? 1 : 2) && (
                        <span className="text-[10px] text-muted-foreground">+{dayEvents.length - (isBlocked ? 1 : 2)} more</span>
                      )}
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        {/* Upcoming Events Sidebar */}
        <div className="w-[280px] hidden lg:block">
          <Card>
            <CardHeader className="pb-2">
              <CardTitle className="text-sm flex items-center gap-2">
                <CalIcon className="h-4 w-4" /> Upcoming Events
              </CardTitle>
              <p className="text-xs text-muted-foreground">Next scheduled meetings & deadlines</p>
            </CardHeader>
            <CardContent className="space-y-4">
              {upcomingEvents.length === 0 ? (
                <p className="text-sm text-muted-foreground text-center py-4">No upcoming events</p>
              ) : upcomingEvents.map((item, i) => {
                const style = eventTypeStyles[item.event_type] || eventTypeStyles.event;
                return (
                  <div
                    key={i}
                    className={`flex items-start gap-3 ${item.type === 'event' ? 'cursor-pointer hover:bg-muted/50 -mx-2 px-2 py-1 rounded' : ''}`}
                    onClick={() => item.type === 'event' && openView(item)}
                  >
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-medium truncate">{item.title}</p>
                      <p className="text-xs text-muted-foreground">
                        {format(item.eventDate, "MMM d, yyyy")}
                        {item.start_date && !item.all_day && <span> @ {format(item.eventDate, "h:mm a")}</span>}
                      </p>
                    </div>
                    <div className="flex flex-col items-end gap-1">
                      <Badge variant="outline" className={`text-[10px] ${style.text}`}>
                        {item.type === "blocked" ? "BLOCKED" : style.label}
                      </Badge>
                      <span className="text-[10px] text-muted-foreground flex items-center gap-0.5">
                        <Clock className="h-3 w-3" /> {item.daysAway} days
                      </span>
                    </div>
                  </div>
                );
              })}
            </CardContent>
          </Card>
        </div>
      </div>

      {/* New/Edit Event Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader><DialogTitle>{editing ? "Edit" : "New"} Event</DialogTitle></DialogHeader>

          {/* Tabs */}
          <div className="flex border-b">
            <button onClick={() => setDialogTab("details")} className={`flex-1 py-2 text-sm font-medium text-center border-b-2 transition-colors ${dialogTab === "details" ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`}>Event Details</button>
            <button onClick={() => setDialogTab("recurrence")} className={`flex-1 py-2 text-sm font-medium text-center border-b-2 transition-colors ${dialogTab === "recurrence" ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`}>Recurrence</button>
          </div>

          {dialogTab === "details" ? (
            <div className="space-y-4">
              {/* Assign to Association */}
              <div>
                <Label className="flex items-center gap-1.5"><Building2 className="h-3.5 w-3.5" /> Assign to Association</Label>
                <Select value={form.association_id} onValueChange={(v) => setForm({ ...form, association_id: v })}>
                  <SelectTrigger><SelectValue placeholder="Select association..." /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="__public__">Public Event (No Owner)</SelectItem>
                    {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                  </SelectContent>
                </Select>
              </div>

              {/* Visibility */}
              <div>
                <Label className="flex items-center gap-1.5 mb-2"><Eye className="h-3.5 w-3.5" /> Visible To</Label>
                <div className="space-y-2">
                  {[
                    { key: "admin", label: "Admin / Staff", desc: "Internal team members" },
                    { key: "board_member", label: "Associations / Board Members", desc: "Board and committee members" },
                    { key: "homeowner", label: "Homeowners", desc: "All homeowners in assigned association" },
                    { key: "public", label: "Public / Community Page", desc: "Visible on the public community calendar" },
                  ].map(opt => (
                    <label key={opt.key} className="flex items-center gap-3 rounded-md border px-3 py-2 cursor-pointer hover:bg-muted/50 transition-colors">
                      <Checkbox
                        checked={form.visibility.includes(opt.key)}
                        onCheckedChange={(checked) => {
                          setForm(prev => ({
                            ...prev,
                            visibility: checked
                              ? [...prev.visibility, opt.key]
                              : prev.visibility.filter(v => v !== opt.key),
                          }));
                        }}
                      />
                      <div>
                        <span className="text-sm font-medium">{opt.label}</span>
                        <p className="text-xs text-muted-foreground">{opt.desc}</p>
                      </div>
                    </label>
                  ))}
                </div>
              </div>

              {/* Mark as Blocked */}
              <div className="flex items-center justify-between rounded-md border border-destructive/30 px-3 py-2.5">
                <div className="flex items-center gap-2">
                  <Shield className="h-4 w-4 text-destructive" />
                  <div>
                    <span className="text-sm font-medium text-destructive">Mark as Blocked</span>
                    <p className="text-xs text-muted-foreground">Users will see "Unavailable" instead of details.</p>
                  </div>
                </div>
                <Switch checked={form.is_blocked} onCheckedChange={(c) => setForm({ ...form, is_blocked: c })} />
              </div>

              {/* Event Title */}
              <div><Label>Event Title</Label><Input value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} placeholder="e.g. Annual Meeting" /></div>

              {/* Date & Type */}
              <div className="grid grid-cols-2 gap-4">
                <div><Label>Date</Label><Input type="date" value={form.start_date?.slice(0, 10) || ""} onChange={(e) => setForm({ ...form, start_date: e.target.value + (form.start_date?.slice(10) || "T09:00") })} /></div>
                <div><Label>Type</Label>
                  <Select value={form.event_type} onValueChange={(v) => setForm({ ...form, event_type: v })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="meeting">Meeting</SelectItem>
                      <SelectItem value="deadline">Deadline</SelectItem>
                      <SelectItem value="event">Event</SelectItem>
                      <SelectItem value="maintenance">Maintenance</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>

              {/* All Day Toggle */}
              <div className="flex items-center gap-2">
                <Switch checked={form.all_day} onCheckedChange={(c) => setForm({ ...form, all_day: c })} />
                <Label className="flex items-center gap-1"><Clock className="h-3.5 w-3.5" /> All Day Event</Label>
              </div>

              {/* Start/End Time (if not all day) */}
              {!form.all_day && (
                <div className="grid grid-cols-2 gap-4">
                  <div><Label>Start Time</Label><Input type="time" value={form.start_date?.slice(11, 16) || "09:00"} onChange={(e) => setForm({ ...form, start_date: (form.start_date?.slice(0, 10) || "") + "T" + e.target.value })} /></div>
                  <div><Label>End Time</Label><Input type="time" value={form.end_date?.slice(11, 16) || "10:00"} onChange={(e) => setForm({ ...form, end_date: (form.end_date?.slice(0, 10) || form.start_date?.slice(0, 10) || "") + "T" + e.target.value })} /></div>
                </div>
              )}

              {/* Location */}
              <div><Label>Location</Label><Input value={form.location} onChange={(e) => setForm({ ...form, location: e.target.value })} placeholder="Optional" /></div>

              {/* Description */}
              <div><Label>Description</Label><Textarea value={form.description} onChange={(e) => setForm({ ...form, description: e.target.value })} placeholder="Add details..." /></div>

              {/* Meeting Notice / Attachment */}
              <div>
                <Label>Meeting Notice / Attachment</Label>
                {form.attachment_url ? (
                  <div className="flex items-center justify-between border rounded-md px-3 py-2 mt-1">
                    <a href={safeFileUrl(form.attachment_url)} target="_blank" rel="noopener noreferrer" className="text-sm text-primary hover:underline truncate flex-1">
                      📎 {form.attachment_name || "View attachment"}
                    </a>
                    <Button type="button" variant="ghost" size="sm" onClick={handleRemoveAttachment}>
                      <Trash2 className="h-3.5 w-3.5" />
                    </Button>
                  </div>
                ) : (
                  <div className="mt-1">
                    <Input
                      type="file"
                      accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.txt"
                      disabled={uploadingAttachment}
                      onChange={(e) => {
                        const f = e.target.files?.[0];
                        if (f) handleAttachmentUpload(f);
                        e.target.value = "";
                      }}
                    />
                    {uploadingAttachment && (
                      <p className="text-xs text-muted-foreground mt-1 flex items-center gap-1">
                        <Loader2 className="h-3 w-3 animate-spin" /> Uploading...
                      </p>
                    )}
                    <p className="text-xs text-muted-foreground mt-1">PDF, Word doc, or image. Max 10 MB.</p>
                  </div>
                )}
              </div>
            </div>
          ) : (
            <div className="space-y-4 py-2">
              <div className="flex items-center justify-between rounded-md border border-border px-3 py-2.5">
                <div>
                  <Label>Repeat event</Label>
                  <p className="text-xs text-muted-foreground">Create multiple calendar entries from this event.</p>
                </div>
                <Switch checked={recurrence.enabled} onCheckedChange={(enabled) => setRecurrence({ ...recurrence, enabled })} disabled={!!editing} />
              </div>
              {editing && <p className="text-xs text-muted-foreground">Recurring series can be created from new events.</p>}
              {recurrence.enabled && !editing && (
                <div className="space-y-4">
                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <Label>Repeat</Label>
                      <Select value={recurrence.frequency} onValueChange={(frequency: RecurrenceForm["frequency"]) => setRecurrence({ ...recurrence, frequency })}>
                        <SelectTrigger><SelectValue /></SelectTrigger>
                        <SelectContent>
                          <SelectItem value="daily">Daily</SelectItem>
                          <SelectItem value="weekly">Weekly</SelectItem>
                          <SelectItem value="monthly">Monthly by date</SelectItem>
                          <SelectItem value="monthly_by_week">Monthly by weekday</SelectItem>
                        </SelectContent>
                      </Select>
                    </div>
                    <div><Label>Every</Label><Input type="number" min={1} max={24} value={recurrence.interval} onChange={(e) => setRecurrence({ ...recurrence, interval: Number(e.target.value) || 1 })} /></div>
                  </div>
                  {recurrence.frequency === "monthly_by_week" && (
                    <div className="grid grid-cols-2 gap-4">
                      <div><Label>Week</Label><Select value={recurrence.weekPosition} onValueChange={(weekPosition) => setRecurrence({ ...recurrence, weekPosition })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent>{ordinalOptions.map(o => <SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>)}</SelectContent></Select></div>
                      <div><Label>Day</Label><Select value={String(recurrence.dayOfWeek)} onValueChange={(dayOfWeek) => setRecurrence({ ...recurrence, dayOfWeek: Number(dayOfWeek) })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent>{weekdayOptions.map(o => <SelectItem key={o.value} value={String(o.value)}>{o.label}</SelectItem>)}</SelectContent></Select></div>
                    </div>
                  )}
                  <div className="grid grid-cols-2 gap-4">
                    <div><Label>Ends</Label><Select value={recurrence.endType} onValueChange={(endType: RecurrenceForm["endType"]) => setRecurrence({ ...recurrence, endType })}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent><SelectItem value="count">After occurrences</SelectItem><SelectItem value="date">On date</SelectItem></SelectContent></Select></div>
                    {recurrence.endType === "count" ? <div><Label>Occurrences</Label><Input type="number" min={1} max={120} value={recurrence.occurrences} onChange={(e) => setRecurrence({ ...recurrence, occurrences: Number(e.target.value) || 1 })} /></div> : <div><Label>End date</Label><Input type="date" value={recurrence.endDate} onChange={(e) => setRecurrence({ ...recurrence, endDate: e.target.value })} /></div>}
                  </div>
                  {recurrence.frequency === "monthly_by_week" && <p className="text-sm text-muted-foreground">Example: {ordinalOptions.find(o => o.value === recurrence.weekPosition)?.label.toLowerCase()} {weekdayOptions.find(o => o.value === recurrence.dayOfWeek)?.label.toLowerCase()} of every month.</p>}
                </div>
              )}
            </div>
          )}

          <DialogFooter className="flex justify-between sm:justify-between">
            {editing ? (
              <Button variant="destructive" size="sm" onClick={() => { if (confirm("Delete this event?")) { handleDelete(editing.id); setDialogOpen(false); } }}>
                <Trash2 className="h-4 w-4 mr-1" /> Delete
              </Button>
            ) : <div />}
            <div className="flex gap-2">
              <Button variant="outline" onClick={() => setDialogOpen(false)}>Close</Button>
              <Button onClick={handleSave}>{editing ? "Update Event" : "Create Event"}</Button>
            </div>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* New/Edit Amenity Booking Dialog */}
      <Dialog open={bookingDialogOpen} onOpenChange={setBookingDialogOpen}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader><DialogTitle>{bookingEditing ? "Edit" : "New"} {calendarMode === "meetings" ? "Meeting" : "Rental"} Booking</DialogTitle></DialogHeader>
          <div className="space-y-4">
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-1.5">
                <Label>Association</Label>
                <Select value={bookingForm.association_id} onValueChange={(v) => setBookingForm({ ...bookingForm, association_id: v, amenity_id: "" })}>
                  <SelectTrigger><SelectValue placeholder="Select association" /></SelectTrigger>
                  <SelectContent>{associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}</SelectContent>
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label>Amenity</Label>
                <Select value={bookingForm.amenity_id} onValueChange={(v) => setBookingForm({ ...bookingForm, amenity_id: v })}>
                  <SelectTrigger><SelectValue placeholder="Select amenity" /></SelectTrigger>
                  <SelectContent>{bookingAmenities.filter(a => !bookingForm.association_id || a.association_id === bookingForm.association_id).map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}</SelectContent>
                </Select>
              </div>
            </div>
            <div><Label>Title</Label><Input value={bookingForm.title} onChange={(e) => setBookingForm({ ...bookingForm, title: e.target.value })} placeholder={calendarMode === "meetings" ? "Board workshop" : "Clubhouse rental"} /></div>
            <div className="grid grid-cols-2 gap-4">
              <div><Label>Contact Name</Label><Input value={bookingForm.guest_name} onChange={(e) => setBookingForm({ ...bookingForm, guest_name: e.target.value })} /></div>
              <div><Label>Contact Phone</Label><Input value={bookingForm.guest_phone} onChange={(e) => setBookingForm({ ...bookingForm, guest_phone: e.target.value })} /></div>
            </div>
            <div><Label>Contact Email</Label><Input type="email" value={bookingForm.guest_email} onChange={(e) => setBookingForm({ ...bookingForm, guest_email: e.target.value })} /></div>
            <div className="grid grid-cols-3 gap-4">
              <div><Label>Date</Label><Input type="date" value={bookingForm.booking_date} onChange={(e) => setBookingForm({ ...bookingForm, booking_date: e.target.value })} /></div>
              <div><Label>Start</Label><Input type="time" value={bookingForm.start_time} onChange={(e) => setBookingForm({ ...bookingForm, start_time: e.target.value })} /></div>
              <div><Label>End</Label><Input type="time" value={bookingForm.end_time} onChange={(e) => setBookingForm({ ...bookingForm, end_time: e.target.value })} /></div>
            </div>
            <div><Label>Location</Label><Input value={bookingForm.location} onChange={(e) => setBookingForm({ ...bookingForm, location: e.target.value })} /></div>
            <div><Label>Notes</Label><Textarea value={bookingForm.notes} onChange={(e) => setBookingForm({ ...bookingForm, notes: e.target.value })} /></div>

            {/* Recurrence (new bookings only) */}
            {!bookingEditing && (
              <div className="border-t pt-3 space-y-2">
                <Label className="text-sm font-medium">Repeat</Label>
                <div className="grid grid-cols-2 gap-3">
                  <Select value={bookingForm.recurrence_type} onValueChange={(v) => setBookingForm({ ...bookingForm, recurrence_type: v })}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="none">Does not repeat</SelectItem>
                      <SelectItem value="daily">Daily</SelectItem>
                      <SelectItem value="weekly">Weekly</SelectItem>
                      <SelectItem value="biweekly">Every 2 weeks</SelectItem>
                      <SelectItem value="monthly">Monthly (same date)</SelectItem>
                      <SelectItem value="monthly_by_week">Monthly (e.g. first Tuesday)</SelectItem>
                      <SelectItem value="monthly_last_day">Monthly (last day of month)</SelectItem>
                    </SelectContent>
                  </Select>
                  {(bookingForm.recurrence_type === "daily" || bookingForm.recurrence_type === "weekly" || bookingForm.recurrence_type === "monthly" || bookingForm.recurrence_type === "monthly_by_week" || bookingForm.recurrence_type === "monthly_last_day") && (
                    <div className="flex items-center gap-2">
                      <Label className="text-xs whitespace-nowrap">Every</Label>
                      <Input type="number" min="1" value={bookingForm.recurrence_interval} onChange={(e) => setBookingForm({ ...bookingForm, recurrence_interval: e.target.value })} />
                      <span className="text-xs text-muted-foreground">{bookingForm.recurrence_type === "daily" ? "day(s)" : bookingForm.recurrence_type === "weekly" ? "week(s)" : "month(s)"}</span>
                    </div>
                  )}
                </div>
                {bookingForm.recurrence_type === "monthly_by_week" && (
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <Label className="text-xs">Week of month</Label>
                      <Select value={bookingForm.recurrence_week_position} onValueChange={(v) => setBookingForm({ ...bookingForm, recurrence_week_position: v })}>
                        <SelectTrigger><SelectValue /></SelectTrigger>
                        <SelectContent>{ordinalOptions.map(o => <SelectItem key={o.value} value={o.value}>{o.label}</SelectItem>)}</SelectContent>
                      </Select>
                    </div>
                    <div>
                      <Label className="text-xs">Day of week</Label>
                      <Select value={bookingForm.recurrence_day_of_week} onValueChange={(v) => setBookingForm({ ...bookingForm, recurrence_day_of_week: v })}>
                        <SelectTrigger><SelectValue /></SelectTrigger>
                        <SelectContent>{weekdayOptions.map(o => <SelectItem key={o.value} value={String(o.value)}>{o.label}</SelectItem>)}</SelectContent>
                      </Select>
                    </div>
                    <p className="col-span-2 text-xs text-muted-foreground">
                      Repeats on the {ordinalOptions.find(o => o.value === bookingForm.recurrence_week_position)?.label.toLowerCase()} {weekdayOptions.find(o => String(o.value) === bookingForm.recurrence_day_of_week)?.label.toLowerCase()} of every month.
                    </p>
                  </div>
                )}
                {bookingForm.recurrence_type !== "none" && (
                  <div className="grid grid-cols-2 gap-3">
                    <div><Label className="text-xs">End date (optional)</Label><Input type="date" value={bookingForm.recurrence_end_date} onChange={(e) => setBookingForm({ ...bookingForm, recurrence_end_date: e.target.value, recurrence_count: "" })} /></div>
                    <div><Label className="text-xs">Or # of occurrences</Label><Input type="number" min="1" max="365" value={bookingForm.recurrence_count} onChange={(e) => setBookingForm({ ...bookingForm, recurrence_count: e.target.value, recurrence_end_date: "" })} placeholder="e.g. 10" /></div>
                  </div>
                )}
              </div>
            )}

            {/* Public event display */}
            <div className="border-t pt-3 space-y-3">
              <label className="flex items-center gap-2 text-sm font-medium cursor-pointer">
                <input type="checkbox" className="h-4 w-4" checked={bookingForm.is_public_event} onChange={(e) => setBookingForm({ ...bookingForm, is_public_event: e.target.checked })} />
                Display as a public event on the amenity calendar
              </label>
              {bookingForm.is_public_event && (
                <div className="space-y-2 pl-6">
                  <div><Label>Event title (shown publicly)</Label><Input value={bookingForm.event_title} placeholder={bookingForm.title || "Community event"} onChange={(e) => setBookingForm({ ...bookingForm, event_title: e.target.value })} /></div>
                  <div><Label>Event description (optional)</Label><Textarea value={bookingForm.event_description} onChange={(e) => setBookingForm({ ...bookingForm, event_description: e.target.value })} /></div>
                </div>
              )}
            </div>

            {/* Stripe payment */}
            <div className="border-t pt-3 space-y-2">
              <Label className="text-sm font-medium">Payment (Stripe)</Label>
              <div className="grid grid-cols-2 gap-3 items-end">
                <div><Label className="text-xs">Amount (USD)</Label><Input type="number" min="0" step="0.01" value={bookingForm.payment_amount} onChange={(e) => setBookingForm({ ...bookingForm, payment_amount: e.target.value })} placeholder="0.00" /></div>
                <Button type="button" variant="outline" size="sm" onClick={handleSendPaymentLink} disabled={!bookingEditing}>
                  Send payment link
                </Button>
              </div>
              {!bookingEditing && <p className="text-xs text-muted-foreground">Save the booking first, then you can email a Stripe payment link to the contact.</p>}
              {bookingEditing?.payment_status === "paid" && <p className="text-xs text-green-600 font-medium">✓ Paid</p>}
              {bookingEditing?.payment_link_url && bookingEditing?.payment_status !== "paid" && (
                <p className="text-xs text-muted-foreground">Last link: <a className="text-primary hover:underline" href={bookingEditing.payment_link_url} target="_blank" rel="noopener noreferrer">open</a></p>
              )}
            </div>
          </div>
          <DialogFooter className="flex justify-between sm:justify-between">
            {bookingEditing ? <Button variant="destructive" size="sm" onClick={() => { handleBookingDelete(bookingEditing.id); setBookingDialogOpen(false); }}><Trash2 className="h-4 w-4 mr-1" /> Delete</Button> : <div />}
            <div className="flex gap-2"><Button variant="outline" onClick={() => setBookingDialogOpen(false)}>Close</Button><Button onClick={handleBookingSave}>{bookingEditing ? "Update" : "Create"} Booking</Button></div>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* View Event Details Dialog (read-only for board / homeowners) */}
      <Dialog open={viewDialogOpen} onOpenChange={setViewDialogOpen}>
        <DialogContent className="sm:max-w-lg">
          {viewing && (
            <>
              <DialogHeader>
                <DialogTitle className="flex items-center gap-2">
                  {viewing.is_blocked ? <Lock className="h-4 w-4 text-destructive" /> : <CalIcon className="h-4 w-4" />}
                  {viewing.is_blocked ? "Unavailable" : viewing.title}
                </DialogTitle>
                {viewing.associations?.name && (
                  <DialogDescription className="flex items-center gap-1.5">
                    <Building2 className="h-3.5 w-3.5" /> {viewing.associations.name}
                  </DialogDescription>
                )}
              </DialogHeader>

              {viewing.is_blocked ? (
                <div className="py-6 text-center text-sm text-muted-foreground">
                  This date is reserved. Details are not available.
                </div>
              ) : (
                <div className="space-y-4">
                  <div className="flex items-center gap-2 text-sm">
                    <Badge variant="outline" className={eventTypeStyles[viewing.event_type]?.text}>
                      {eventTypeStyles[viewing.event_type]?.label || viewing.event_type?.toUpperCase()}
                    </Badge>
                  </div>

                  <div className="grid grid-cols-2 gap-3 text-sm">
                    <div>
                      <p className="text-xs font-medium text-muted-foreground uppercase">Date</p>
                      <p>{viewing.start_date ? format(parseISO(viewing.start_date), "MMM d, yyyy") : "—"}</p>
                    </div>
                    {!viewing.all_day && viewing.start_date?.includes('T') && (
                      <div>
                        <p className="text-xs font-medium text-muted-foreground uppercase">Time</p>
                        <p>
                          {format(parseISO(viewing.start_date), "h:mm a")}
                          {viewing.end_date && ` – ${format(parseISO(viewing.end_date), "h:mm a")}`}
                        </p>
                      </div>
                    )}
                  </div>

                  {viewing.location && (
                    <div>
                      <p className="text-xs font-medium text-muted-foreground uppercase">Location</p>
                      <p className="text-sm whitespace-pre-wrap break-words">{viewing.location}</p>
                    </div>
                  )}

                  {viewing.description && (
                    <div>
                      <p className="text-xs font-medium text-muted-foreground uppercase">Details</p>
                      <p className="text-sm whitespace-pre-wrap break-words">{viewing.description}</p>
                    </div>
                  )}

                  {viewing.attachment_url && (
                    <div>
                      <p className="text-xs font-medium text-muted-foreground uppercase mb-1">Meeting Notice</p>
                      <a
                        href={safeFileUrl(viewing.attachment_url)}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="inline-flex items-center gap-2 text-sm text-primary hover:underline border rounded-md px-3 py-2"
                      >
                        <Download className="h-4 w-4" />
                        {viewing.attachment_name || "Download attachment"}
                      </a>
                    </div>
                  )}
                </div>
              )}

              <DialogFooter>
                {!isBoardView && !viewing.is_blocked && (
                  <Button variant="outline" onClick={() => { setViewDialogOpen(false); openEdit(viewing); }}>
                    <Edit className="h-4 w-4 mr-1" /> Edit
                  </Button>
                )}
                <Button onClick={() => setViewDialogOpen(false)}>Close</Button>
              </DialogFooter>
            </>
          )}
        </DialogContent>
      </Dialog>

      {/* Block Date Dialog */}
      <Dialog open={blockDialogOpen} onOpenChange={setBlockDialogOpen}>
        <DialogContent>
          <DialogHeader><DialogTitle>Block Date</DialogTitle></DialogHeader>
          <div className="space-y-4">
            <div><Label>Title</Label><Input value={blockForm.title} onChange={(e) => setBlockForm({ ...blockForm, title: e.target.value })} placeholder="e.g., Holiday" /></div>
            <div className="grid grid-cols-2 gap-4">
              <div><Label>Start Date</Label><Input type="date" value={blockForm.start_date} onChange={(e) => setBlockForm({ ...blockForm, start_date: e.target.value })} /></div>
              <div><Label>End Date</Label><Input type="date" value={blockForm.end_date} onChange={(e) => setBlockForm({ ...blockForm, end_date: e.target.value })} /></div>
            </div>
            <div><Label>Reason</Label><Textarea value={blockForm.reason} onChange={(e) => setBlockForm({ ...blockForm, reason: e.target.value })} /></div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBlockDialogOpen(false)}>Cancel</Button>
            <Button onClick={handleBlockSave}>Block</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Google Calendar Import Dialog */}
      <Dialog open={gcalDialogOpen} onOpenChange={setGcalDialogOpen}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <DialogTitle>Import from Google Calendar</DialogTitle>
            <DialogDescription>
              Paste your Google Calendar public ICS URL to import events. In Google Calendar, go to <strong>Settings → Calendar → Integrate calendar</strong> and copy the "Public address in iCal format" link.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label>Calendar ICS URL</Label>
              <Input
                placeholder="https://calendar.google.com/calendar/ical/...basic.ics"
                value={gcalUrl}
                onChange={(e) => setGcalUrl(e.target.value)}
              />
            </div>
            {gcalPreview.length === 0 ? (
              <Button onClick={handleGcalFetch} disabled={gcalImporting || !gcalUrl} className="w-full gap-2">
                {gcalImporting && <Loader2 className="h-4 w-4 animate-spin" />}
                Fetch Events
              </Button>
            ) : (
              <div className="space-y-3">
                <div className="rounded-md border p-3 bg-muted/50">
                  <p className="text-sm font-medium">{gcalPreview.length} events found</p>
                  <div className="mt-2 max-h-48 overflow-y-auto space-y-1">
                    {gcalPreview.slice(0, 20).map((ev, i) => (
                      <div key={i} className="text-xs flex justify-between">
                        <span className="truncate font-medium">{ev.summary || "Untitled"}</span>
                        <span className="text-muted-foreground shrink-0 ml-2">{ev.startDate.toLocaleDateString()}</span>
                      </div>
                    ))}
                    {gcalPreview.length > 20 && <p className="text-xs text-muted-foreground">+{gcalPreview.length - 20} more...</p>}
                  </div>
                </div>
              </div>
            )}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setGcalDialogOpen(false)}>Cancel</Button>
            {gcalPreview.length > 0 && (
              <Button onClick={handleGcalImport} disabled={gcalImporting} className="gap-2">
                {gcalImporting && <Loader2 className="h-4 w-4 animate-spin" />}
                Import {gcalPreview.length} Events
              </Button>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Date Request Dialog for Board Members */}
      <Dialog open={dateRequestDialogOpen} onOpenChange={setDateRequestDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Request a Date</DialogTitle>
            <DialogDescription>Submit a date request for admin approval.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Requested Date</Label>
              <Input type="date" value={dateRequestForm.date} onChange={(e) => setDateRequestForm(f => ({ ...f, date: e.target.value }))} />
            </div>
            <div className="space-y-2">
              <Label>Description / Reason</Label>
              <Textarea placeholder="Describe the purpose of this date request..." value={dateRequestForm.description} onChange={(e) => setDateRequestForm(f => ({ ...f, description: e.target.value }))} />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDateRequestDialogOpen(false)}>Cancel</Button>
            <Button disabled={dateRequestLoading || !dateRequestForm.date} onClick={async () => {
              setDateRequestLoading(true);
              try {
                const { data: userData } = await supabase.auth.getUser();
                if (!userData?.user) throw new Error("Not authenticated");
                const assocId = associations[0]?.id;
                if (!assocId) throw new Error("No association found");
                await supabase.from("client_requests").insert({
                  association_id: assocId,
                  title: `Date Request: ${dateRequestForm.date}`,
                  description: dateRequestForm.description,
                  status: "open",
                  priority: "medium",
                  requester_email: userData.user.email,
                  requester_name: userData.user.user_metadata?.full_name || userData.user.email,
                });
                toast({ title: "Request Submitted", description: "Your date request has been sent for admin approval." });
                setDateRequestDialogOpen(false);
                setDateRequestForm({ date: "", description: "" });
              } catch (err: any) {
                toast({ title: "Error", description: err.message, variant: "destructive" });
              } finally {
                setDateRequestLoading(false);
              }
            }}>
              {dateRequestLoading ? <><Loader2 className="h-4 w-4 mr-2 animate-spin" /> Submitting...</> : "Submit Request"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Manage / Bulk Delete Events Dialog */}
      <Dialog open={manageDialogOpen} onOpenChange={setManageDialogOpen}>
        <DialogContent className="sm:max-w-3xl max-h-[85vh] flex flex-col">
          <DialogHeader>
            <DialogTitle>Manage Events</DialogTitle>
            <DialogDescription>Filter, select and bulk-delete events. Useful for clearing imported series or Google-synced entries.</DialogDescription>
          </DialogHeader>

          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-2">
            <div className="relative col-span-1 sm:col-span-2">
              <Search className="h-4 w-4 absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground" />
              <Input placeholder="Search by title..." className="pl-8" value={manageSearch} onChange={(e) => setManageSearch(e.target.value)} />
            </div>
            <Select value={manageSourceFilter} onValueChange={setManageSourceFilter}>
              <SelectTrigger><SelectValue placeholder="Source" /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All sources</SelectItem>
                <SelectItem value="google_sync">Google Sync</SelectItem>
                <SelectItem value="meeting">Meetings</SelectItem>
                <SelectItem value="event">Events</SelectItem>
                <SelectItem value="deadline">Deadlines</SelectItem>
                <SelectItem value="maintenance">Maintenance</SelectItem>
              </SelectContent>
            </Select>
            <Select value={manageAssocFilter} onValueChange={setManageAssocFilter}>
              <SelectTrigger><SelectValue placeholder="Association" /></SelectTrigger>
              <SelectContent>
                <SelectItem value="all">All associations</SelectItem>
                {associations.map(a => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
              </SelectContent>
            </Select>
            <div>
              <Label className="text-xs">From</Label>
              <Input type="date" value={manageFromDate} onChange={(e) => setManageFromDate(e.target.value)} />
            </div>
            <div>
              <Label className="text-xs">To</Label>
              <Input type="date" value={manageToDate} onChange={(e) => setManageToDate(e.target.value)} />
            </div>
          </div>

          {(() => {
            const filtered = events.filter(e => {
              if (manageSearch && !(e.title || "").toLowerCase().includes(manageSearch.toLowerCase())) return false;
              if (manageSourceFilter !== "all" && e.event_type !== manageSourceFilter) return false;
              if (manageAssocFilter !== "all" && e.association_id !== manageAssocFilter) return false;
              if (manageFromDate && e.start_date && e.start_date.slice(0, 10) < manageFromDate) return false;
              if (manageToDate && e.start_date && e.start_date.slice(0, 10) > manageToDate) return false;
              return true;
            });
            const allSelected = filtered.length > 0 && filtered.every(e => manageSelected.has(e.id));
            const toggleAll = () => {
              const next = new Set(manageSelected);
              if (allSelected) filtered.forEach(e => next.delete(e.id));
              else filtered.forEach(e => next.add(e.id));
              setManageSelected(next);
            };
            return (
              <>
                <div className="flex items-center justify-between border-y py-2 text-sm">
                  <div className="flex items-center gap-3">
                    <Checkbox checked={allSelected} onCheckedChange={toggleAll} />
                    <span className="text-muted-foreground">
                      {filtered.length} match{filtered.length === 1 ? "" : "es"} · {manageSelected.size} selected
                    </span>
                  </div>
                  <Button variant="outline" size="sm" className="gap-2 text-destructive border-destructive/30 hover:bg-destructive/10" onClick={handleDeleteAllGoogle} disabled={bulkDeleting}>
                    <Trash2 className="h-3.5 w-3.5" /> Delete All Google-Synced
                  </Button>
                </div>

                <div className="flex-1 overflow-y-auto -mx-1 px-1">
                  {filtered.length === 0 ? (
                    <p className="text-center text-sm text-muted-foreground py-8">No events match these filters.</p>
                  ) : (
                    <div className="divide-y">
                      {filtered.map(e => {
                        const checked = manageSelected.has(e.id);
                        const style = eventTypeStyles[e.event_type] || eventTypeStyles.event;
                        return (
                          <label key={e.id} className="flex items-center gap-3 py-2 cursor-pointer hover:bg-muted/30 px-2 rounded">
                            <Checkbox
                              checked={checked}
                              onCheckedChange={(c) => {
                                const next = new Set(manageSelected);
                                if (c) next.add(e.id); else next.delete(e.id);
                                setManageSelected(next);
                              }}
                            />
                            <div className="flex-1 min-w-0">
                              <div className="flex items-center gap-2">
                                <p className="text-sm font-medium truncate">{e.title || "Untitled"}</p>
                                <Badge variant="outline" className={`text-[10px] ${style.text}`}>{style.label}</Badge>
                              </div>
                              <p className="text-xs text-muted-foreground">
                                {e.start_date ? format(parseISO(e.start_date), "MMM d, yyyy h:mm a") : "—"}
                                {e.associations?.name && ` · ${e.associations.name}`}
                              </p>
                            </div>
                          </label>
                        );
                      })}
                    </div>
                  )}
                </div>
              </>
            );
          })()}

          <DialogFooter className="border-t pt-3">
            <Button variant="outline" onClick={() => setManageDialogOpen(false)}>Close</Button>
            <Button
              variant="destructive"
              className="gap-2"
              disabled={manageSelected.size === 0 || bulkDeleting}
              onClick={handleBulkDelete}
            >
              {bulkDeleting ? <Loader2 className="h-4 w-4 animate-spin" /> : <Trash2 className="h-4 w-4" />}
              Delete Selected ({manageSelected.size})
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
