import { useState, useEffect, useCallback, useMemo } from "react";
import { ScrollArea } from "@/components/ui/scroll-area";
import { supabase } from "@/integrations/supabase/client";
import { useToast } from "@/hooks/use-toast";
import { formatDistanceToNow } from "date-fns";
import {
  UserCog, Search, Plus, Trash2, Shield, ShieldOff, KeyRound, Edit2,
  Mail, Phone, Link2, AlertTriangle, Ban, CheckCircle2, Users, Info, RefreshCw, Loader2,
  LogIn, Settings2, Send, MailPlus, MessageSquare, Clock
} from "lucide-react";
import RecordImportButton from "@/components/RecordImportButton";
import { Switch } from "@/components/ui/switch";
import { Checkbox } from "@/components/ui/checkbox";

import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription,
} from "@/components/ui/dialog";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

interface ManagedUser {
  user_id: string;
  full_name: string | null;
  email: string;
  phone: string | null;
  is_blocked: boolean;
  created_at: string;
  roles: string[];
  linked_unit_ids?: string[];
  board_member_association_ids?: string[];
  legal_association_ids?: string[];
  master_board_association_ids?: string[];
  is_bill_approver?: boolean;
  last_sign_in_at?: string | null;
  auth_email?: string;
  primary_owner_id?: string | null;
  primary_association_id?: string | null;
}

const ROLES = [
  { value: "admin", label: "Admin", color: "bg-red-100 text-red-700" },
  { value: "manager", label: "Manager", color: "bg-blue-100 text-blue-700" },
  { value: "staff", label: "Staff", color: "bg-purple-100 text-purple-700" },
  { value: "employee", label: "Employee", color: "bg-indigo-100 text-indigo-700" },
  { value: "legal", label: "Legal", color: "bg-muted text-foreground" },
  { value: "master_board_member", label: "Master Board Member", color: "bg-violet-100 text-violet-700" },
  { value: "board_member", label: "Client / Association", color: "bg-amber-100 text-amber-700" },
  { value: "arc_member", label: "ARC Member", color: "bg-muted text-foreground" },
  { value: "fining_member", label: "Fining Member", color: "bg-muted text-foreground" },
  { value: "homeowner", label: "Homeowner", color: "bg-emerald-100 text-emerald-700" },
  { value: "rv_boat_lot", label: "RV/Boat Lot", color: "bg-cyan-100 text-cyan-700" },
  { value: "association_management", label: "Association Management", color: "bg-teal-100 text-teal-700" },
];

const roleColor = (role: string) =>
  ROLES.find((r) => r.value === role)?.color || "bg-muted text-muted-foreground";

async function invokeAdmin(action: string, payload: any = {}) {
  const { data, error } = await supabase.functions.invoke("admin-user-management", {
    body: { action, ...payload },
  });
  if (error) {
    // Newer SDK: non-2xx responses come back as FunctionsHttpError with the body
    // available on error.context. Try to parse the JSON {error: "..."} message.
    let detail = error.message || "Edge function error";
    try {
      const ctx: any = (error as any).context;
      if (ctx?.json) {
        const j = await ctx.json();
        if (j?.error) detail = j.error;
      } else if (ctx?.text) {
        const t = await ctx.text();
        try {
          const j = JSON.parse(t);
          if (j?.error) detail = j.error;
        } catch {
          if (t) detail = t;
        }
      }
    } catch {
      // fall through
    }
    throw new Error(detail);
  }
  if (data?.error) throw new Error(data.error);
  return data;
}

export default function UserManagementPage() {
  const { toast } = useToast();
  const [users, setUsers] = useState<ManagedUser[]>([]);
  const [owners, setOwners] = useState<any[]>([]);
  const [units, setUnits] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [associations, setAssociations] = useState<any[]>([]);
  const [saving, setSaving] = useState(false);
  const [syncing, setSyncing] = useState(false);

  // Dialogs
  const [addDialogOpen, setAddDialogOpen] = useState(false);
  const [editUser, setEditUser] = useState<ManagedUser | null>(null);
  const [resetPwUser, setResetPwUser] = useState<ManagedUser | null>(null);
  const [deleteUser, setDeleteUser] = useState<ManagedUser | null>(null);

  // Bulk selection
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [bulkDeleteOpen, setBulkDeleteOpen] = useState(false);
  const [bulkDeleting, setBulkDeleting] = useState(false);
  const [bulkUpdateOpen, setBulkUpdateOpen] = useState(false);
  const [bulkUpdating, setBulkUpdating] = useState(false);
  const [bulkForm, setBulkForm] = useState({ role: "", association_id: "", blocked: "" });
  const [inviteDialogOpen, setInviteDialogOpen] = useState(false);
  const [inviteEmail, setInviteEmail] = useState("");
  const [inviting, setInviting] = useState(false);
  const [bulkResetSending, setBulkResetSending] = useState(false);
  const [resetLinkUser, setResetLinkUser] = useState<ManagedUser | null>(null);
  const [resetLinkMessage, setResetLinkMessage] = useState("");
  const [resetLinkSending, setResetLinkSending] = useState(false);

  // Form state
  const [form, setForm] = useState({
    email: "", password: "", full_name: "", phone: "", role: "homeowner",
    unit_ids: [] as string[], association_ids: [] as string[], is_board_member: false, is_arc_member: false, is_fining_committee: false, is_bill_approver: false,
    primary_owner_id: "" as string, primary_association_id: "" as string,
  });
  const [newPassword, setNewPassword] = useState("");
  const [unitSearch, setUnitSearch] = useState("");

  const fetchUsers = useCallback(async () => {
    setLoading(true);
    try {
      const [profilesRes, rolesRes, ownersRes, boardMembersRes, legalAssignmentsRes, masterBoardAssignmentsRes] = await Promise.all([
        supabase.from("profiles").select("*").order("created_at", { ascending: false }),
        supabase.from("user_roles").select("*"),
        supabase.from("owners").select("id, first_name, last_name, user_id, unit_id, association_id").eq("status", "active").not("user_id", "is", null),
        supabase.from("board_members").select("user_id, association_id, approval_authority").not("user_id", "is", null),
        (supabase as any).from("legal_association_assignments").select("user_id, association_id"),
        (supabase as any).from("master_board_assignments").select("user_id, association_id"),
      ]);

      // Fetch auth users for last_sign_in_at and as a fallback for auth-only users
      let authUsers: any[] = [];
      let authUserMap = new Map<string, string | null>();
      try {
        const authResult = await invokeAdmin("list_users", { perPage: 1000 });
        authUsers = authResult?.users || [];
        authUsers.forEach((u: any) => {
          authUserMap.set(u.id, u.last_sign_in_at || null);
        });
      } catch (e) {
        console.warn("Could not fetch auth user data for last login:", e);
      }

      const roleMap = new Map<string, string[]>();
      (rolesRes.data || []).forEach((r: any) => {
        if (!roleMap.has(r.user_id)) roleMap.set(r.user_id, []);
        roleMap.get(r.user_id)!.push(r.role);
      });

      const ownerUnitMap = new Map<string, string[]>();
      (ownersRes.data || []).forEach((o: any) => {
        if (o.user_id && o.unit_id) {
          const existing = ownerUnitMap.get(o.user_id) || [];
          if (!existing.includes(o.unit_id)) {
            existing.push(o.unit_id);
          }
          ownerUnitMap.set(o.user_id, existing);
        }
      });

      const boardMemberMap = new Map<string, { association_ids: string[]; approval_authority: boolean }>();
      (boardMembersRes.data || []).forEach((bm: any) => {
        if (bm.user_id) {
          const existing = boardMemberMap.get(bm.user_id);
          if (existing) {
            existing.association_ids.push(bm.association_id);
            if (bm.approval_authority) existing.approval_authority = true;
          } else {
            boardMemberMap.set(bm.user_id, { association_ids: [bm.association_id], approval_authority: bm.approval_authority || false });
          }
        }
      });

      const legalAssignmentMap = new Map<string, string[]>();
      (legalAssignmentsRes.data || []).forEach((assignment: any) => {
        const existing = legalAssignmentMap.get(assignment.user_id) || [];
        if (!existing.includes(assignment.association_id)) existing.push(assignment.association_id);
        legalAssignmentMap.set(assignment.user_id, existing);
      });

      const masterBoardAssignmentMap = new Map<string, string[]>();
      ((masterBoardAssignmentsRes as any)?.data || []).forEach((assignment: any) => {
        const existing = masterBoardAssignmentMap.get(assignment.user_id) || [];
        if (!existing.includes(assignment.association_id)) existing.push(assignment.association_id);
        masterBoardAssignmentMap.set(assignment.user_id, existing);
      });

      const mapped: ManagedUser[] = (profilesRes.data || []).map((p: any) => ({
        user_id: p.user_id,
        full_name: p.full_name,
        email: p.email || "",
        phone: p.phone || "",
        is_blocked: p.is_blocked || false,
        created_at: p.created_at,
        roles: roleMap.get(p.user_id) || [],
        linked_unit_ids: ownerUnitMap.get(p.user_id) || [],
        board_member_association_ids: boardMemberMap.get(p.user_id)?.association_ids || [],
        legal_association_ids: legalAssignmentMap.get(p.user_id) || [],
        master_board_association_ids: masterBoardAssignmentMap.get(p.user_id) || [],
        is_bill_approver: boardMemberMap.get(p.user_id)?.approval_authority || false,
        last_sign_in_at: authUserMap.get(p.user_id) || null,
        primary_owner_id: p.primary_owner_id || null,
        primary_association_id: p.primary_association_id || null,
      }));

      const mappedIds = new Set(mapped.map((u) => u.user_id));
      authUsers.forEach((authUser: any) => {
        if (mappedIds.has(authUser.id)) return;
        mapped.push({
          user_id: authUser.id,
          full_name: authUser.user_metadata?.full_name || authUser.user_metadata?.name || authUser.email?.split("@")[0] || "Unnamed",
          email: authUser.email || "",
          phone: authUser.phone || "",
          is_blocked: false,
          created_at: authUser.created_at,
          roles: roleMap.get(authUser.id) || [],
          linked_unit_ids: ownerUnitMap.get(authUser.id) || [],
          board_member_association_ids: boardMemberMap.get(authUser.id)?.association_ids || [],
          legal_association_ids: legalAssignmentMap.get(authUser.id) || [],
          master_board_association_ids: masterBoardAssignmentMap.get(authUser.id) || [],
          is_bill_approver: boardMemberMap.get(authUser.id)?.approval_authority || false,
          last_sign_in_at: authUser.last_sign_in_at || null,
          auth_email: authUser.email || "",
          primary_owner_id: null,
          primary_association_id: null,
        });
      });

      setUsers(mapped);
    } catch (err: any) {
      toast({ title: "Error loading users", description: err.message, variant: "destructive" });
    } finally {
      setLoading(false);
    }
  }, [toast]);

  const fetchOwners = useCallback(async () => {
    const { data } = await supabase
      .from("owners")
      .select("id, first_name, last_name, unit_id, association_id, user_id, associations(name)")
      .neq("status", "archived")
      .order("last_name");
    setOwners(data || []);
  }, []);

  const fetchUnits = useCallback(async () => {
    const { data } = await supabase
      .from("units")
      .select("id, unit_number, address, association_id, associations(name)")
      .eq("status", "active")
      .order("unit_number");
    setUnits(data || []);
  }, []);

  useEffect(() => {
    fetchUsers();
    fetchOwners();
    fetchUnits();
    supabase.from("associations").select("id, name").eq("status", "active").order("name").then(({ data }) => setAssociations(data || []));
  }, [fetchUsers, fetchOwners, fetchUnits]);

  const unitOwnerMap = useMemo(() => {
    const map = new Map<string, string[]>();
    for (const o of owners) {
      if (o.unit_id) {
        const existing = map.get(o.unit_id) || [];
        existing.push(`${o.first_name || ""} ${o.last_name || ""}`.trim());
        map.set(o.unit_id, existing);
      }
    }
    return map;
  }, [owners]);

  const unitOptions = useMemo(() => {
    const filtered = form.association_ids.length > 0
      ? units.filter((u: any) => form.association_ids.includes(u.association_id))
      : units;
    return filtered.map((u: any) => {
      const ownerNames = unitOwnerMap.get(u.id) || [];
      const ownerStr = ownerNames.length > 0 ? ` — ${ownerNames.join(", ")}` : "";
      return {
        value: u.id,
        label: `${u.unit_number || "—"}${u.address ? ` · ${u.address}` : ""}${u.associations?.name ? ` (${u.associations.name})` : ""}`,
        searchText: `${u.unit_number || ""} ${u.address || ""} ${u.associations?.name || ""} ${ownerNames.join(" ")}`.toLowerCase(),
        ownerStr,
      };
    });
  }, [units, form.association_ids, unitOwnerMap]);

  const filteredUnitOptions = useMemo(() => {
    if (!unitSearch.trim()) return unitOptions;
    const q = unitSearch.toLowerCase();
    return unitOptions.filter((u) => u.searchText.includes(q));
  }, [unitOptions, unitSearch]);

  const resetForm = () => {
    setForm({ email: "", password: "", full_name: "", phone: "", role: "homeowner",
      unit_ids: [], association_ids: [], is_board_member: false, is_arc_member: false, is_fining_committee: false, is_bill_approver: false,
      primary_owner_id: "", primary_association_id: "" });
    setNewPassword("");
    setUnitSearch("");
  };

  const handleSyncAuthUsers = async () => {
    setSyncing(true);
    try {
      const result = await invokeAdmin("sync_auth_users");
      toast({
        title: "Sync Complete",
        description: `${result.synced} new profile(s) created from ${result.total_auth} authenticated users. ${result.already_existed} already had profiles.`,
      });
      fetchUsers();
    } catch (err: any) {
      toast({ title: "Sync failed", description: err.message, variant: "destructive" });
    } finally {
      setSyncing(false);
    }
  };

  const handleCreate = async () => {
    const cleanEmail = (form.email || "").trim().toLowerCase();
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!cleanEmail || !form.password) {
      toast({ title: "Email and password are required", variant: "destructive" });
      return;
    }
    if (!emailRegex.test(cleanEmail)) {
      toast({ title: "Invalid email format", description: `"${cleanEmail}" is not a valid email address.`, variant: "destructive" });
      return;
    }
    if ((form.role === "legal" || form.role === "master_board_member") && form.association_ids.length === 0) {
      toast({ title: "Select at least one community for this role", variant: "destructive" });
      return;
    }
    setSaving(true);
    try {
      await invokeAdmin("create_user", {
        email: cleanEmail,
        password: form.password,
        full_name: form.full_name,
        role: form.role,
        unit_ids: (form.role === "legal" || form.role === "master_board_member") ? [] : form.unit_ids,
        association_ids: form.association_ids,
        is_board_member: form.is_board_member,
        is_arc_member: form.is_arc_member,
        is_fining_committee: form.is_fining_committee,
        is_bill_approver: form.is_bill_approver,
      });
      toast({ title: "User created successfully" });
      setAddDialogOpen(false);
      resetForm();
      fetchUsers();
      fetchOwners();
    } catch (err: any) {
      toast({ title: "Error creating user", description: err.message, variant: "destructive" });
    } finally {
      setSaving(false);
    }
  };

  const handleUpdate = async () => {
    if (!editUser) return;
    if ((form.role === "legal" || form.role === "master_board_member") && form.association_ids.length === 0) {
      toast({ title: "Select at least one community for this role", variant: "destructive" });
      return;
    }
    setSaving(true);
    try {
      await invokeAdmin("update_user", {
        user_id: editUser.user_id,
        email: form.email,
        full_name: form.full_name,
        phone: form.phone,
        role: form.role,
        unit_ids: (form.role === "legal" || form.role === "master_board_member") ? [] : form.unit_ids,
        association_ids: form.association_ids,
        is_board_member: form.is_board_member,
        is_arc_member: form.is_arc_member,
        is_fining_committee: form.is_fining_committee,
        is_bill_approver: form.is_bill_approver,
      });
      // Persist primary owner/association on the user's profile
      await supabase
        .from("profiles")
        .update({
          primary_owner_id: form.primary_owner_id || null,
          primary_association_id: form.primary_association_id || null,
        })
        .eq("user_id", editUser.user_id);
      toast({ title: "User updated successfully" });
      setEditUser(null);
      resetForm();
      fetchUsers();
      fetchOwners();
    } catch (err: any) {
      toast({ title: "Error updating user", description: err.message, variant: "destructive" });
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!deleteUser) return;
    setSaving(true);
    try {
      await invokeAdmin("delete_user", { user_id: deleteUser.user_id });
      toast({ title: "User deleted" });
      setDeleteUser(null);
      fetchUsers();
      fetchOwners();
    } catch (err: any) {
      toast({ title: "Error deleting user", description: err.message, variant: "destructive" });
    } finally {
      setSaving(false);
    }
  };

  const handleResetPassword = async () => {
    if (!resetPwUser || !newPassword) return;
    setSaving(true);
    try {
      await invokeAdmin("reset_password", { user_id: resetPwUser.user_id, new_password: newPassword });
      toast({ title: "Password reset successfully" });
      setResetPwUser(null);
      setNewPassword("");
    } catch (err: any) {
      toast({ title: "Error resetting password", description: err.message, variant: "destructive" });
    } finally {
      setSaving(false);
    }
  };

  const handleToggleBlock = async (user: ManagedUser) => {
    try {
      await invokeAdmin("block_user", { user_id: user.user_id, blocked: !user.is_blocked });
      toast({ title: user.is_blocked ? "User unblocked" : "User blocked" });
      fetchUsers();
    } catch (err: any) {
      toast({ title: "Error", description: err.message, variant: "destructive" });
    }
  };

  const handleBulkDelete = async () => {
    if (selectedIds.size === 0) return;
    setBulkDeleting(true);
    try {
      const result = await invokeAdmin("bulk_delete_users", { user_ids: Array.from(selectedIds) });
      toast({
        title: "Bulk Delete Complete",
        description: `${result.deleted} user(s) deleted.${result.errors?.length ? ` ${result.errors.length} failed.` : ""}`,
        variant: result.errors?.length ? "destructive" : "default",
      });
      setSelectedIds(new Set());
      setBulkDeleteOpen(false);
      fetchUsers();
      fetchOwners();
    } catch (err: any) {
      toast({ title: "Bulk delete failed", description: err.message, variant: "destructive" });
    } finally {
      setBulkDeleting(false);
    }
  };

  const handleSignInAsUser = async (user: ManagedUser) => {
    try {
      const result = await invokeAdmin("sign_in_as_user", { user_id: user.user_id });
      if (result?.token_hash) {
        // Use verifyOtp to exchange the magic link token for a session
        const { error } = await supabase.auth.verifyOtp({
          token_hash: result.token_hash,
          type: "magiclink",
        });
        if (error) throw error;
        toast({ title: `Signed in as ${user.full_name || user.email}` });
        window.location.href = "/";
      } else {
        throw new Error("No token returned");
      }
    } catch (err: any) {
      toast({ title: "Sign-in failed", description: err.message, variant: "destructive" });
    }
  };

  const handleBulkUpdate = async () => {
    if (selectedIds.size === 0) return;
    setBulkUpdating(true);
    try {
      const payload: any = { user_ids: Array.from(selectedIds) };
      if (bulkForm.role) payload.role = bulkForm.role;
      if (bulkForm.association_id) payload.association_id = bulkForm.association_id;
      if (bulkForm.blocked !== "") payload.blocked = bulkForm.blocked === "true";

      const result = await invokeAdmin("bulk_update_users", payload);
      toast({
        title: "Bulk Update Complete",
        description: `${result.updated} user(s) updated.${result.errors?.length ? ` ${result.errors.length} failed.` : ""}`,
        variant: result.errors?.length ? "destructive" : "default",
      });
      setSelectedIds(new Set());
      setBulkUpdateOpen(false);
      setBulkForm({ role: "", association_id: "", blocked: "" });
      fetchUsers();
    } catch (err: any) {
      toast({ title: "Bulk update failed", description: err.message, variant: "destructive" });
    } finally {
      setBulkUpdating(false);
    }
  };

  const handleInviteUser = async () => {
    if (!inviteEmail.trim()) return;
    setInviting(true);
    try {
      const emails = Array.from(new Set(inviteEmail.split(/[\s,;]+/).map((email) => email.trim()).filter(Boolean)));
      const result = emails.length > 1
        ? await invokeAdmin("bulk_invite_users", { emails })
        : await invokeAdmin("invite_user", { email: emails[0] });
      toast({
        title: emails.length > 1 ? "Invitations Sent" : "Invitation Sent",
        description: emails.length > 1
          ? `${result.sent || 0} invitation(s) sent.${result.errors?.length ? ` ${result.errors.length} failed.` : ""}`
          : `An invitation email has been sent to ${emails[0]}`,
        variant: result?.errors?.length ? "destructive" : "default",
      });
      setInviteDialogOpen(false);
      setInviteEmail("");
      fetchUsers();
    } catch (err: any) {
      toast({ title: "Error sending invitation", description: err.message, variant: "destructive" });
    } finally {
      setInviting(false);
    }
  };

  const handleSendResetLink = async () => {
    if (!resetLinkUser) return;
    setResetLinkSending(true);
    try {
      await invokeAdmin("send_reset_email", { email: resetLinkUser.email, custom_message: resetLinkMessage || undefined });
      toast({ title: "Password Reset Link Sent", description: `A reset link has been sent to ${resetLinkUser.email}` });
      setResetLinkUser(null);
      setResetLinkMessage("");
    } catch (err: any) {
      toast({ title: "Error", description: err.message, variant: "destructive" });
    } finally {
      setResetLinkSending(false);
    }
  };

  const handleBulkSendResetLinks = async () => {
    if (selectedIds.size === 0) return;
    setBulkResetSending(true);
    try {
      const result = await invokeAdmin("bulk_send_reset_email", { user_ids: Array.from(selectedIds) });
      toast({
        title: "Bulk Password Reset",
        description: `${result.sent} reset link(s) sent.${result.errors?.length ? ` ${result.errors.length} failed.` : ""}`,
        variant: result.errors?.length ? "destructive" : "default",
      });
      setSelectedIds(new Set());
    } catch (err: any) {
      toast({ title: "Error", description: err.message, variant: "destructive" });
    } finally {
      setBulkResetSending(false);
    }
  };

  const toggleSelect = (userId: string) => {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(userId)) next.delete(userId);
      else next.add(userId);
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selectedIds.size === filtered.length) {
      setSelectedIds(new Set());
    } else {
      setSelectedIds(new Set(filtered.map((u) => u.user_id)));
    }
  };

  const openEdit = (user: ManagedUser) => {
    setEditUser(user);
    const roles = user.roles;
    // Determine primary role (first non-committee role, or first role)
    const committeeRoles = ["board_member", "arc_member", "fining_member"];
    const primaryRole = roles.includes("legal")
      ? "legal"
      : roles.includes("master_board_member")
      ? "master_board_member"
      : roles.find((r) => !committeeRoles.includes(r)) || roles[0] || "homeowner";
    const isAssocOnly = primaryRole === "legal" || primaryRole === "master_board_member";
    const assocIdsForEdit = primaryRole === "legal"
      ? user.legal_association_ids || []
      : primaryRole === "master_board_member"
      ? user.master_board_association_ids || []
      : user.board_member_association_ids || [];
    setForm({
      email: user.email,
      password: "",
      full_name: user.full_name || "",
      phone: user.phone || "",
      role: primaryRole,
      unit_ids: isAssocOnly ? [] : user.linked_unit_ids || [],
      association_ids: assocIdsForEdit,
      is_board_member: roles.includes("board_member"),
      is_arc_member: roles.includes("arc_member"),
      is_fining_committee: roles.includes("fining_member"),
      is_bill_approver: (user as any).is_bill_approver || false,
      primary_owner_id: user.primary_owner_id || "",
      primary_association_id: user.primary_association_id || "",
    });
  };

  const filtered = users.filter(
    (u) =>
      (u.full_name || "").toLowerCase().includes(search.toLowerCase()) ||
      (u.email || "").toLowerCase().includes(search.toLowerCase()) ||
      u.roles.some((r) => r.toLowerCase().includes(search.toLowerCase()))
  );

  // availableOwners moved above ownerOptions

  return (
    <div className="space-y-6 max-w-7xl mx-auto">
      {/* Header */}
      <div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
        <div className="flex items-center gap-3">
          <div className="p-3 bg-primary/10 text-primary rounded-lg border border-primary/20">
            <UserCog className="w-6 h-6" />
          </div>
          <div>
            <h1 className="text-3xl font-bold text-foreground tracking-tight">User Management</h1>
            <p className="text-muted-foreground mt-1">Create, edit, and manage user accounts, roles, and access.</p>
          </div>
        </div>
        <div className="flex gap-2">
          <RecordImportButton
            title="Import Users"
            description="Upload a spreadsheet with user accounts. Each row will create a new user with the specified role."
            expectedColumns={[
              { key: "email", label: "Email", required: true },
              { key: "password", label: "Password", required: true },
              { key: "full_name", label: "Full Name" },
              { key: "role", label: "Role (admin/manager/staff/employee/board_member/homeowner/rv_boat_lot)" },
              { key: "association", label: "Association Name (for board members)" },
            ]}
            onImport={async (rows) => {
              let successCount = 0;
              const errors: string[] = [];
              for (const row of rows) {
                if (!row.email || !row.password) {
                  errors.push(`Skipped row: missing email or password`);
                  continue;
                }
                const role = row.role?.toLowerCase().trim() || "homeowner";
                let assocId = "";
                if (row.association) {
                  const match = associations.find(a => a.name.toLowerCase() === row.association.toLowerCase().trim());
                  if (match) assocId = match.id;
                }
                try {
                  await invokeAdmin("create_user", {
                    email: row.email.trim(),
                    password: row.password,
                    full_name: row.full_name?.trim() || "",
                    role,
                    owner_id: null,
                    association_id: assocId || null,
                    is_board_member: role === "board_member",
                    is_arc_member: false,
                    is_fining_committee: false,
                  });
                  successCount++;
                } catch (err: any) {
                  errors.push(`${row.email}: ${err.message}`);
                }
              }
              if (errors.length) {
                toast({ title: `${successCount} imported, ${errors.length} failed`, description: errors.slice(0, 3).join("\n"), variant: "destructive" });
              } else {
                toast({ title: `${successCount} users imported` });
              }
              fetchUsers();
              fetchOwners();
            }}
          />
          <Button variant="outline" onClick={handleSyncAuthUsers} disabled={syncing} className="gap-2">
            <RefreshCw className={`h-4 w-4 ${syncing ? "animate-spin" : ""}`} /> {syncing ? "Syncing..." : "Sync Auth Users"}
          </Button>
          <Button variant="outline" onClick={() => { setInviteEmail(""); setInviteDialogOpen(true); }} className="gap-2">
            <MailPlus className="h-4 w-4" /> Invite by Email
          </Button>
          <Button onClick={() => { resetForm(); setAddDialogOpen(true); }} className="gap-2">
            <Plus className="h-4 w-4" /> Add User
          </Button>
        </div>
      </div>

      {/* Search + Bulk Actions */}
      <div className="flex items-center gap-3">
        <div className="relative max-w-md flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input placeholder="Search by name, email, or role..." className="pl-10" value={search} onChange={(e) => setSearch(e.target.value)} />
        </div>
        {selectedIds.size > 0 && (
          <div className="flex gap-2">
            <Button variant="outline" size="sm" onClick={() => { setBulkForm({ role: "", association_id: "", blocked: "" }); setBulkUpdateOpen(true); }} className="gap-2">
              <Settings2 className="h-4 w-4" /> Update {selectedIds.size} Selected
            </Button>
            <Button variant="outline" size="sm" onClick={handleBulkSendResetLinks} disabled={bulkResetSending} className="gap-2">
              <Send className={`h-4 w-4 ${bulkResetSending ? "animate-pulse" : ""}`} /> {bulkResetSending ? "Sending..." : `Send Reset Links (${selectedIds.size})`}
            </Button>
            <Button variant="destructive" size="sm" onClick={() => setBulkDeleteOpen(true)} className="gap-2">
              <Trash2 className="h-4 w-4" /> Delete {selectedIds.size} Selected
            </Button>
          </div>
        )}
      </div>

      {/* Users Table */}
      <Card className="border shadow-sm rounded-xl overflow-hidden">
        <div className="rounded-lg overflow-hidden">
          <Table>
            <TableHeader className="bg-muted/50">
              <TableRow>
                <TableHead className="w-10">
                  <Checkbox
                    checked={filtered.length > 0 && selectedIds.size === filtered.length}
                    onCheckedChange={toggleSelectAll}
                  />
                </TableHead>
                <TableHead className="font-semibold uppercase tracking-wider text-xs">User</TableHead>
                <TableHead className="font-semibold uppercase tracking-wider text-xs">Roles</TableHead>
                <TableHead className="font-semibold uppercase tracking-wider text-xs">Assigned Access</TableHead>
                <TableHead className="font-semibold uppercase tracking-wider text-xs">Status</TableHead>
                <TableHead className="font-semibold uppercase tracking-wider text-xs">Last Login</TableHead>
                <TableHead className="font-semibold uppercase tracking-wider text-xs">Joined</TableHead>
                <TableHead className="font-semibold uppercase tracking-wider text-xs text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {loading ? (
                Array.from({ length: 6 }).map((_, i) => (
                  <TableRow key={i}>
                    <TableCell><Skeleton className="h-4 w-4" /></TableCell>
                    <TableCell><Skeleton className="h-10 w-48" /></TableCell>
                    <TableCell><Skeleton className="h-6 w-24" /></TableCell>
                    <TableCell><Skeleton className="h-6 w-32" /></TableCell>
                    <TableCell><Skeleton className="h-6 w-20" /></TableCell>
                    <TableCell><Skeleton className="h-6 w-24" /></TableCell>
                    <TableCell><Skeleton className="h-6 w-24" /></TableCell>
                    <TableCell><Skeleton className="h-6 w-16 ml-auto" /></TableCell>
                  </TableRow>
                ))
              ) : filtered.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={8} className="h-48 text-center text-muted-foreground">
                    <Users className="h-12 w-12 mx-auto mb-3 text-muted-foreground/30" />
                    <p className="font-medium text-foreground">No users found</p>
                  </TableCell>
                </TableRow>
              ) : (
                filtered.map((user) => (
                  <TableRow key={user.user_id} className="group">
                    <TableCell>
                      <Checkbox
                        checked={selectedIds.has(user.user_id)}
                        onCheckedChange={() => toggleSelect(user.user_id)}
                      />
                    </TableCell>
                    <TableCell>
                      <div className="flex flex-col gap-0.5">
                        <span className="font-semibold text-foreground">{user.full_name || "Unnamed"}</span>
                        <span className="text-xs text-muted-foreground flex items-center gap-1">
                          <Mail className="h-3 w-3" /> {user.email || "No email"}
                        </span>
                        {user.phone && (
                          <span className="text-xs text-muted-foreground flex items-center gap-1">
                            <Phone className="h-3 w-3" /> {user.phone}
                          </span>
                        )}
                      </div>
                    </TableCell>
                    <TableCell>
                      <div className="flex gap-1 flex-wrap">
                        {user.roles.length ? user.roles.map((r) => (
                          <Badge key={r} className={`${roleColor(r)} text-xs`}>{r}</Badge>
                        )) : <span className="text-muted-foreground text-xs italic">No role</span>}
                      </div>
                    </TableCell>
                    <TableCell>
                      {user.roles.includes("legal") && user.legal_association_ids && user.legal_association_ids.length > 0 ? (
                        <div className="flex flex-col gap-1 text-xs">
                          {user.legal_association_ids.map((aid) => {
                            const association = associations.find((a: any) => a.id === aid);
                            return <span key={aid} className="font-medium text-foreground">{association?.name || "Unknown community"}</span>;
                          })}
                        </div>
                      ) : user.linked_unit_ids && user.linked_unit_ids.length > 0 ? (
                        <div className="flex flex-col gap-1 text-xs">
                          {user.linked_unit_ids.map((uid) => {
                            const u = units.find((x: any) => x.id === uid);
                            if (!u) return <span key={uid} className="text-muted-foreground italic">Unknown unit</span>;
                            return (
                              <div key={uid} className="flex flex-col">
                                <span className="font-medium text-foreground">
                                  {u.unit_number || "—"}{u.address ? ` · ${u.address}` : ""}
                                </span>
                                {u.associations?.name && (
                                  <span className="text-muted-foreground">{u.associations.name}</span>
                                )}
                              </div>
                            );
                          })}
                        </div>
                      ) : (
                        <span className="text-muted-foreground text-xs italic">Not linked</span>
                      )}
                    </TableCell>
                    <TableCell>
                      {user.is_blocked ? (
                        <Badge variant="destructive" className="gap-1 text-xs"><Ban className="h-3 w-3" /> Blocked</Badge>
                      ) : (
                        <Badge variant="outline" className="bg-emerald-50 text-emerald-700 border-emerald-200 gap-1 text-xs">
                          <CheckCircle2 className="h-3 w-3" /> Active
                        </Badge>
                      )}
                    </TableCell>
                    <TableCell>
                      <div className="flex items-center gap-1 text-sm text-muted-foreground">
                        <Clock className="h-3 w-3" />
                        {user.last_sign_in_at
                          ? formatDistanceToNow(new Date(user.last_sign_in_at), { addSuffix: true })
                          : <span className="italic">Never</span>
                        }
                      </div>
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {new Date(user.created_at).toLocaleDateString()}
                    </TableCell>
                    <TableCell className="text-right">
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <Button variant="ghost" size="sm" className="opacity-0 group-hover:opacity-100 transition-opacity">
                            Actions
                          </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem onClick={() => openEdit(user)}>
                            <Edit2 className="h-4 w-4 mr-2" /> Edit User
                          </DropdownMenuItem>
                          <DropdownMenuItem onClick={() => { setResetPwUser(user); setNewPassword(""); }}>
                            <KeyRound className="h-4 w-4 mr-2" /> Reset Password
                          </DropdownMenuItem>
                          <DropdownMenuItem onClick={() => { setResetLinkUser(user); setResetLinkMessage(""); }}>
                             <Send className="h-4 w-4 mr-2" /> Send Reset Link
                           </DropdownMenuItem>
                          <DropdownMenuItem onClick={() => handleSignInAsUser(user)}>
                            <LogIn className="h-4 w-4 mr-2" /> Sign in as User
                          </DropdownMenuItem>
                          <DropdownMenuSeparator />
                          <DropdownMenuItem onClick={() => handleToggleBlock(user)}>
                            {user.is_blocked ? (
                              <><ShieldOff className="h-4 w-4 mr-2" /> Unblock User</>
                            ) : (
                              <><Shield className="h-4 w-4 mr-2 text-amber-600" /> Block Access</>
                            )}
                          </DropdownMenuItem>
                          <DropdownMenuSeparator />
                          <DropdownMenuItem className="text-destructive" onClick={() => setDeleteUser(user)}>
                            <Trash2 className="h-4 w-4 mr-2" /> Delete User
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>
      </Card>

      {/* ─── Add User Dialog ─── */}
      <Dialog open={addDialogOpen} onOpenChange={setAddDialogOpen}>
        <DialogContent className="max-w-md max-h-[85vh] flex flex-col">
          <DialogHeader>
            <DialogTitle>Create User</DialogTitle>
            <DialogDescription>Add a new user to the system.</DialogDescription>
          </DialogHeader>
          <ScrollArea className="flex-1 -mx-6 px-6">
          <div className="space-y-4 pb-2">
            <div className="space-y-2">
              <Label>Email Address</Label>
              <Input type="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
            </div>
            <div className="space-y-2">
              <Label>Full Name</Label>
              <Input value={form.full_name} onChange={(e) => setForm({ ...form, full_name: e.target.value })} placeholder="e.g. John Doe" />
            </div>
            <div className="space-y-2">
              <Label>Initial Password</Label>
              <Input type="password" value={form.password} onChange={(e) => setForm({ ...form, password: e.target.value })} />
            </div>
            <div className="space-y-2">
              <Label>System Role</Label>
              <Select value={form.role} onValueChange={(v) => setForm({ ...form, role: v })}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  {ROLES.map((r) => <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label className="flex items-center gap-1">
                Linked Associations
                <Info className="h-3.5 w-3.5 text-destructive" />
              </Label>
              <div className="border rounded-md max-h-40 overflow-y-auto p-2 space-y-1">
                {associations.length === 0 ? (
                  <p className="text-xs text-muted-foreground p-1">No associations available.</p>
                ) : associations.map((a: any) => (
                  <label key={a.id} className="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-muted cursor-pointer text-sm">
                    <Checkbox
                      checked={form.association_ids.includes(a.id)}
                      onCheckedChange={(checked) => {
                        const next = checked
                          ? [...form.association_ids, a.id]
                          : form.association_ids.filter((id) => id !== a.id);
                        setForm({ ...form, association_ids: next });
                      }}
                    />
                    {a.name}
                  </label>
                ))}
              </div>
              {form.association_ids.length > 0 && (
                <p className="text-xs text-muted-foreground">{form.association_ids.length} association(s) selected</p>
              )}
              <p className="text-xs text-muted-foreground">
                {form.role === "legal"
                  ? "Legal users are assigned by community only."
                  : form.role === "master_board_member"
                  ? "Master board members get board-level access to each assigned community without unit linkage."
                  : "Required for clients and board members to view community data."}
              </p>
            </div>
            {(form.role !== "legal" && form.role !== "master_board_member") && <div className="space-y-2">
              <Label>Linked Units</Label>
              <Input
                placeholder="Search by unit, address, or owner name..."
                value={unitSearch}
                onChange={(e) => setUnitSearch(e.target.value)}
                className="h-8 text-sm"
              />
              <div className="border rounded-md max-h-40 overflow-y-auto p-2 space-y-1">
                {filteredUnitOptions.length === 0 ? (
                  <p className="text-xs text-muted-foreground p-1">{unitSearch ? "No matching units." : "No units available."}</p>
                ) : filteredUnitOptions.map((u: any) => (
                  <label key={u.value} className="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-muted cursor-pointer text-sm">
                    <Checkbox
                      checked={form.unit_ids.includes(u.value)}
                      onCheckedChange={(checked) => {
                        const next = checked
                          ? [...form.unit_ids, u.value]
                          : form.unit_ids.filter((id) => id !== u.value);
                        setForm({ ...form, unit_ids: next });
                      }}
                    />
                    <span className="truncate">{u.label}{u.ownerStr && <span className="text-muted-foreground">{u.ownerStr}</span>}</span>
                  </label>
                ))}
              </div>
              {form.unit_ids.length > 0 && (
                <p className="text-xs text-muted-foreground">{form.unit_ids.length} unit(s) selected</p>
              )}
              <p className="text-xs text-muted-foreground">Links this user to property units.</p>
            </div>}
            <div className="space-y-3">
              <Label className="text-sm font-semibold">Additional Flags</Label>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Is Board Member?</Label>
                <Switch checked={form.is_board_member} onCheckedChange={(v) => setForm({ ...form, is_board_member: v })} />
              </div>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Is ARC Member?</Label>
                <Switch checked={form.is_arc_member} onCheckedChange={(v) => setForm({ ...form, is_arc_member: v })} />
              </div>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Is Fining Committee?</Label>
                <Switch checked={form.is_fining_committee} onCheckedChange={(v) => setForm({ ...form, is_fining_committee: v })} />
              </div>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Bill Approval Authority?</Label>
                <Switch checked={form.is_bill_approver} onCheckedChange={(v) => setForm({ ...form, is_bill_approver: v })} />
              </div>
            </div>
          </div>
          </ScrollArea>
          <div className="flex justify-end gap-2 pt-4 border-t">
            <Button variant="outline" onClick={() => setAddDialogOpen(false)}>Cancel</Button>
            <Button onClick={handleCreate} disabled={saving}>{saving ? "Creating..." : "Create User"}</Button>
          </div>
        </DialogContent>
      </Dialog>

      {/* ─── Edit User Dialog ─── */}
      <Dialog open={!!editUser} onOpenChange={(open) => { if (!open) { setEditUser(null); resetForm(); } }}>
        <DialogContent className="w-[96vw] max-w-[96vw] h-[92vh] max-h-[92vh] flex flex-col p-0 sm:rounded-lg">
          <DialogHeader>
            <div className="px-6 pt-6">
              <DialogTitle>Edit User</DialogTitle>
              <DialogDescription>Update user details, role, and owner association.</DialogDescription>
            </div>
          </DialogHeader>
          <ScrollArea className="flex-1 min-h-0 px-6">
          <div className="space-y-4 pb-6">
            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label>Full Name</Label>
                <Input value={form.full_name} onChange={(e) => setForm({ ...form, full_name: e.target.value })} />
              </div>
              <div className="space-y-2">
                <Label>Phone</Label>
                <Input value={form.phone} onChange={(e) => setForm({ ...form, phone: e.target.value })} />
              </div>
            </div>
            <div className="space-y-2">
              <Label>Email</Label>
              <Input type="email" value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} />
            </div>
            <div className="space-y-2">
              <Label>Role</Label>
              <Select value={form.role} onValueChange={(v) => setForm({ ...form, role: v })}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  {ROLES.map((r) => <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            {(form.role !== "legal" && form.role !== "master_board_member") && <div className="space-y-2">
              <Label>Linked Units</Label>
              <Input
                placeholder="Search by unit, address, or owner name..."
                value={unitSearch}
                onChange={(e) => setUnitSearch(e.target.value)}
                className="h-8 text-sm"
              />
              <div className="border rounded-md max-h-40 overflow-y-auto p-2 space-y-1">
                {filteredUnitOptions.length === 0 ? (
                  <p className="text-xs text-muted-foreground p-1">{unitSearch ? "No matching units." : "No units available."}</p>
                ) : filteredUnitOptions.map((u: any) => (
                  <label key={u.value} className="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-muted cursor-pointer text-sm">
                    <Checkbox
                      checked={form.unit_ids.includes(u.value)}
                      onCheckedChange={(checked) => {
                        const next = checked
                          ? [...form.unit_ids, u.value]
                          : form.unit_ids.filter((id) => id !== u.value);
                        setForm({ ...form, unit_ids: next });
                      }}
                    />
                    <span className="truncate">{u.label}{u.ownerStr && <span className="text-muted-foreground">{u.ownerStr}</span>}</span>
                  </label>
                ))}
              </div>
              {form.unit_ids.length > 0 && (
                <p className="text-xs text-muted-foreground">{form.unit_ids.length} unit(s) selected</p>
              )}
            </div>}
            <div className="space-y-2">
              <Label className="flex items-center gap-1">
                Linked Associations
                <Info className="h-3.5 w-3.5 text-destructive" />
              </Label>
              <div className="border rounded-md max-h-40 overflow-y-auto p-2 space-y-1">
                {associations.length === 0 ? (
                  <p className="text-xs text-muted-foreground p-1">No associations available.</p>
                ) : associations.map((a: any) => (
                  <label key={a.id} className="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-muted cursor-pointer text-sm">
                    <Checkbox
                      checked={form.association_ids.includes(a.id)}
                      onCheckedChange={(checked) => {
                        const next = checked
                          ? [...form.association_ids, a.id]
                          : form.association_ids.filter((id) => id !== a.id);
                        setForm({ ...form, association_ids: next });
                      }}
                    />
                    {a.name}
                  </label>
                ))}
              </div>
              {form.association_ids.length > 0 && (
                <p className="text-xs text-muted-foreground">{form.association_ids.length} association(s) selected</p>
              )}
            </div>
            {/* ─── Primary Designation ─── */}
            {(() => {
              const userOwners = (owners as any[]).filter((o) => o.user_id === editUser?.user_id);
              const showPrimaryOwner = userOwners.length > 1;
              const showPrimaryAssoc = (form.association_ids?.length || 0) > 1;
              if (!showPrimaryOwner && !showPrimaryAssoc) return null;
              return (
                <div className="space-y-3 rounded-md border border-border bg-muted/30 p-3">
                  <Label className="text-sm font-semibold">Primary Designation</Label>
                  <p className="text-xs text-muted-foreground">
                    When this user has multiple linked properties or associations, the primary one loads by default after sign-in.
                  </p>
                  {showPrimaryOwner && (
                    <div className="space-y-1.5">
                      <Label className="text-xs font-normal">Primary Property</Label>
                      <Select
                        value={form.primary_owner_id || "none"}
                        onValueChange={(v) => setForm({ ...form, primary_owner_id: v === "none" ? "" : v })}
                      >
                        <SelectTrigger className="h-8 text-sm"><SelectValue placeholder="No primary set" /></SelectTrigger>
                        <SelectContent>
                          <SelectItem value="none">No primary set</SelectItem>
                          {userOwners.map((o: any) => {
                            const name = [o.first_name, o.last_name].filter(Boolean).join(" ") || "Owner";
                            const assocName = o.associations?.name ? ` (${o.associations.name})` : "";
                            return (
                              <SelectItem key={o.id} value={o.id}>{name}{assocName}</SelectItem>
                            );
                          })}
                        </SelectContent>
                      </Select>
                    </div>
                  )}
                  {showPrimaryAssoc && (
                    <div className="space-y-1.5">
                      <Label className="text-xs font-normal">Primary Association</Label>
                      <Select
                        value={form.primary_association_id || "none"}
                        onValueChange={(v) => setForm({ ...form, primary_association_id: v === "none" ? "" : v })}
                      >
                        <SelectTrigger className="h-8 text-sm"><SelectValue placeholder="No primary set" /></SelectTrigger>
                        <SelectContent>
                          <SelectItem value="none">No primary set</SelectItem>
                          {form.association_ids.map((aid) => {
                            const a = (associations as any[]).find((x) => x.id === aid);
                            return a ? <SelectItem key={aid} value={aid}>{a.name}</SelectItem> : null;
                          })}
                        </SelectContent>
                      </Select>
                    </div>
                  )}
                </div>
              );
            })()}
            <div className="space-y-3">
              <Label className="text-sm font-semibold">Additional Flags</Label>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Is Board Member?</Label>
                <Switch checked={form.is_board_member} onCheckedChange={(v) => setForm({ ...form, is_board_member: v })} />
              </div>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Is ARC Member?</Label>
                <Switch checked={form.is_arc_member} onCheckedChange={(v) => setForm({ ...form, is_arc_member: v })} />
              </div>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Is Fining Committee?</Label>
                <Switch checked={form.is_fining_committee} onCheckedChange={(v) => setForm({ ...form, is_fining_committee: v })} />
              </div>
              <div className="flex items-center justify-between">
                <Label className="text-sm font-normal">Bill Approval Authority?</Label>
                <Switch checked={form.is_bill_approver} onCheckedChange={(v) => setForm({ ...form, is_bill_approver: v })} />
              </div>
            </div>
          </div>
          </ScrollArea>
          <DialogFooter className="border-t border-border p-6 pt-4">
            <Button variant="outline" onClick={() => { setEditUser(null); resetForm(); }}>Cancel</Button>
            <Button onClick={handleUpdate} disabled={saving}>{saving ? "Saving..." : "Save Changes"}</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ─── Reset Password Dialog ─── */}
      <Dialog open={!!resetPwUser} onOpenChange={(open) => { if (!open) setResetPwUser(null); }}>
        <DialogContent className="max-w-sm">
          <DialogHeader>
            <DialogTitle>Reset Password</DialogTitle>
            <DialogDescription>Set a new password for {resetPwUser?.full_name || resetPwUser?.email}</DialogDescription>
          </DialogHeader>
          <div className="space-y-2">
            <Label>New Password</Label>
            <Input type="password" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} placeholder="Minimum 6 characters" />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setResetPwUser(null)}>Cancel</Button>
            <Button onClick={handleResetPassword} disabled={saving || !newPassword}>
              {saving ? "Resetting..." : "Reset Password"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* ─── Delete Confirmation ─── */}
      <AlertDialog open={!!deleteUser} onOpenChange={(open) => { if (!open) setDeleteUser(null); }}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle className="flex items-center gap-2">
              <AlertTriangle className="h-5 w-5 text-destructive" /> Delete User
            </AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to permanently delete <strong>{deleteUser?.full_name || deleteUser?.email}</strong>? 
              This will remove their account, profile, roles, and unlink them from any owner records. This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={handleDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
              {saving ? "Deleting..." : "Delete User"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* ─── Bulk Delete Confirmation ─── */}
      <AlertDialog open={bulkDeleteOpen} onOpenChange={(open) => { if (!open) setBulkDeleteOpen(false); }}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle className="flex items-center gap-2">
              <AlertTriangle className="h-5 w-5 text-destructive" /> Bulk Delete Users
            </AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to permanently delete <strong>{selectedIds.size} user(s)</strong>?
              This will remove their accounts, profiles, roles, and unlink them from any owner records. This action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={bulkDeleting}>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={handleBulkDelete} disabled={bulkDeleting} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
              {bulkDeleting ? <><Loader2 className="h-4 w-4 animate-spin mr-2" /> Deleting...</> : `Delete ${selectedIds.size} Users`}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
      {/* ─── Bulk Update Dialog ─── */}
      <Dialog open={bulkUpdateOpen} onOpenChange={(open) => { if (!open) setBulkUpdateOpen(false); }}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Bulk Update {selectedIds.size} User(s)</DialogTitle>
            <DialogDescription>Leave fields blank to skip them. Only filled fields will be updated.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Set Role</Label>
              <Select value={bulkForm.role || "skip"} onValueChange={(v) => setBulkForm({ ...bulkForm, role: v === "skip" ? "" : v })}>
                <SelectTrigger><SelectValue placeholder="— Don't change —" /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="skip">— Don't change —</SelectItem>
                  {ROLES.map((r) => <SelectItem key={r.value} value={r.value}>{r.label}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Set Association</Label>
              <Select value={bulkForm.association_id || "skip"} onValueChange={(v) => setBulkForm({ ...bulkForm, association_id: v === "skip" ? "" : v })}>
                <SelectTrigger><SelectValue placeholder="— Don't change —" /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="skip">— Don't change —</SelectItem>
                  {associations.map((a: any) => <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label>Set Status</Label>
              <Select value={bulkForm.blocked || "skip"} onValueChange={(v) => setBulkForm({ ...bulkForm, blocked: v === "skip" ? "" : v })}>
                <SelectTrigger><SelectValue placeholder="— Don't change —" /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="skip">— Don't change —</SelectItem>
                  <SelectItem value="false">Active</SelectItem>
                  <SelectItem value="true">Blocked</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkUpdateOpen(false)}>Cancel</Button>
            <Button onClick={handleBulkUpdate} disabled={bulkUpdating || (!bulkForm.role && !bulkForm.association_id && bulkForm.blocked === "")}>
              {bulkUpdating ? <><Loader2 className="h-4 w-4 animate-spin mr-2" /> Updating...</> : "Apply Changes"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Invite by Email Dialog */}
      <Dialog open={inviteDialogOpen} onOpenChange={setInviteDialogOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Invite Users by Email</DialogTitle>
            <DialogDescription>Send one or more invitation emails. Separate multiple addresses with commas, spaces, or new lines.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Email Address(es)</Label>
              <Textarea
                placeholder="user@example.com, another@example.com"
                value={inviteEmail}
                onChange={(e) => setInviteEmail(e.target.value)}
                rows={4}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setInviteDialogOpen(false)}>Cancel</Button>
            <Button onClick={handleInviteUser} disabled={inviting || !inviteEmail.trim()} className="gap-2">
              {inviting ? <><Loader2 className="h-4 w-4 animate-spin" /> Sending...</> : <><MailPlus className="h-4 w-4" /> Send Invitation</>}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Send Reset Link with Message Dialog */}
      <Dialog open={!!resetLinkUser} onOpenChange={(open) => { if (!open) { setResetLinkUser(null); setResetLinkMessage(""); } }}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Send Password Reset Link</DialogTitle>
            <DialogDescription>
              A password reset link will be sent to <strong>{resetLinkUser?.email}</strong>. You can optionally include a personal message.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div className="space-y-2">
              <Label>Attached Message <span className="text-muted-foreground text-xs">(optional)</span></Label>
              <Textarea
                placeholder="e.g. Hi, we've updated our system. Please use this link to reset your password..."
                value={resetLinkMessage}
                onChange={(e) => setResetLinkMessage(e.target.value)}
                rows={4}
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => { setResetLinkUser(null); setResetLinkMessage(""); }}>Cancel</Button>
            <Button onClick={handleSendResetLink} disabled={resetLinkSending} className="gap-2">
              {resetLinkSending ? <><Loader2 className="h-4 w-4 animate-spin" /> Sending...</> : <><Send className="h-4 w-4" /> Send Reset Link</>}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
