import { useState, useEffect, useMemo, useCallback, useRef } from "react";
import { supabase } from "@/integrations/supabase/client";
import { Search, MapPin, Mail, User, Building2, ArrowUpDown, ChevronUp, ChevronDown, ExternalLink, Info, Plus, Edit2, Trash2, Upload, Download, Settings2, Play, Wand2, Home, HomeIcon } from "lucide-react";
import BulkApplyWorkflowDialog from "@/components/bulk-workflow/BulkApplyWorkflowDialog";
import { Checkbox } from "@/components/ui/checkbox";
import ImportSpreadsheetDialog from "@/components/ImportSpreadsheetDialog";
import LedgerCSVImportDialog from "@/components/LedgerCSVImportDialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { useToast } from "@/hooks/use-toast";
import { useNavigate } from "react-router-dom";
import * as XLSX from "xlsx";
import UnitStatusTagsEditor from "@/components/units/UnitStatusTagsEditor";

interface UnitRow {
  id: string;
  unit_number: string;
  address: string | null;
  status: string | null;
  association_id: string;
  account_number: string | null;
  parcel_id?: string | null;
  lot?: string | null;
  is_rental?: boolean | null;
  status_tags?: string[] | null;
  associations?: { name: string } | null;
  owners?: { id: string; first_name: string; last_name: string; email: string | null; balance: number | null }[];
  outstanding_balance?: number;
}

interface Association {
  id: string;
  name: string;
}

const emptyForm = { unit_number: "", address: "", status: "active", account_number: "", parcel_id: "", lot: "", is_rental: false };

export default function UnitsPage() {
  const [units, setUnits] = useState<UnitRow[]>([]);
  const [associations, setAssociations] = useState<Association[]>([]);
  const [selectedAssociationId, setSelectedAssociationId] = useState<string>("");
  const [loading, setLoading] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const [sortConfig, setSortConfig] = useState<{ key: string; direction: "asc" | "desc" }>({ key: "unit", direction: "asc" });
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editingUnit, setEditingUnit] = useState<UnitRow | null>(null);
  const [form, setForm] = useState(emptyForm);
  const [saving, setSaving] = useState(false);
  const [importDialogOpen, setImportDialogOpen] = useState(false);
  const [selectedUnitIds, setSelectedUnitIds] = useState<Set<string>>(new Set());
  const [bulkStatusDialogOpen, setBulkStatusDialogOpen] = useState(false);
  const [bulkStatus, setBulkStatus] = useState("active");
  const [bulkUpdating, setBulkUpdating] = useState(false);
  const [bulkAssigningAccounts, setBulkAssigningAccounts] = useState(false);
  const [bulkWorkflowOpen, setBulkWorkflowOpen] = useState(false);
  const refreshTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const isFetchingRef = useRef(false);
  const { toast } = useToast();
  const navigate = useNavigate();

  const createUniqueAccountNumber = (usedNumbers: Set<string>) => {
    let candidate: string;
    do {
      candidate = String(Math.floor(100000 + Math.random() * 900000));
    } while (usedNumbers.has(candidate));
    usedNumbers.add(candidate);
    return candidate;
  };

  const fetchUnits = useCallback(async () => {
    if (!selectedAssociationId) {
      setUnits([]);
      return;
    }

    if (isFetchingRef.current) return;

    isFetchingRef.current = true;
    setLoading(true);
    try {
      let query = supabase
        .from("units")
        .select(`
          id, unit_number, address, status, association_id, account_number, parcel_id, lot, is_rental, status_tags,
          associations(name),
          owners!left(id, first_name, last_name, email, balance, status)
        `)
        .eq("owners.status", "active")
        .not("status", "eq", "archived")
        .order("unit_number");

      if (selectedAssociationId !== "all") {
        query = query.eq("association_id", selectedAssociationId);
      }

      const { data, error } = await query;
      if (error) throw error;

      // Fetch outstanding balances from ledger entries (paginate to avoid 1000-row limit)
      const unitIds = (data || []).map((u: any) => u.id);
      const balanceMap = new Map<string, number>();
      if (unitIds.length > 0) {
        // Batch unitIds into chunks for .in() queries, and paginate each
        const chunkSize = 200;
        for (let i = 0; i < unitIds.length; i += chunkSize) {
          const chunk = unitIds.slice(i, i + chunkSize);
          let from = 0;
          const pageSize = 1000;
          while (true) {
            const { data: ledger } = await supabase
              .from("owner_ledger_entries")
              .select("unit_id, debit, credit")
              .in("unit_id", chunk)
              .range(from, from + pageSize - 1);
            (ledger || []).forEach((entry: any) => {
              if (entry.unit_id) {
                const prev = balanceMap.get(entry.unit_id) || 0;
                balanceMap.set(entry.unit_id, prev + (entry.debit || 0) - (entry.credit || 0));
              }
            });
            if (!ledger || ledger.length < pageSize) break;
            from += pageSize;
          }
        }
      }

      const unitsWithBalances = (data || []).map((u: any) => ({
        ...u,
        outstanding_balance: balanceMap.get(u.id) || 0,
      }));
      setUnits(unitsWithBalances as UnitRow[]);
    } catch (err: any) {
      toast({ title: "Error fetching units", description: err.message, variant: "destructive" });
    } finally {
      setLoading(false);
      isFetchingRef.current = false;
    }
  }, [selectedAssociationId, toast]);

  useEffect(() => {
    supabase.from("associations").select("id, name").eq("status", "active").order("name").then(({ data }) => {
      if (data) {
        setAssociations(data);
        if (data.length > 0) setSelectedAssociationId(data[0].id);
      }
    });
  }, []);

  useEffect(() => {
    if (selectedAssociationId) fetchUnits();
    else setUnits([]);
  }, [selectedAssociationId, fetchUnits]);

  useEffect(() => {
    if (!selectedAssociationId) return;

    const scheduleRefresh = () => {
      if (refreshTimeoutRef.current) clearTimeout(refreshTimeoutRef.current);
      refreshTimeoutRef.current = setTimeout(() => {
        fetchUnits();
      }, 750);
    };

    const channel = supabase.channel(`owners-sync-units-${selectedAssociationId}`);

    if (selectedAssociationId === "all") {
      channel.on("postgres_changes", { event: "*", schema: "public", table: "owners" }, scheduleRefresh);
    } else {
      channel.on(
        "postgres_changes",
        { event: "*", schema: "public", table: "owners", filter: `association_id=eq.${selectedAssociationId}` },
        scheduleRefresh,
      );
    }

    channel.subscribe();

    return () => {
      if (refreshTimeoutRef.current) {
        clearTimeout(refreshTimeoutRef.current);
        refreshTimeoutRef.current = null;
      }
      supabase.removeChannel(channel);
    };
  }, [selectedAssociationId, fetchUnits]);

  const openAddDialog = () => {
    setEditingUnit(null);
    setForm(emptyForm);
    setDialogOpen(true);
  };

  const openEditDialog = (unit: UnitRow, e: React.MouseEvent) => {
    e.stopPropagation();
    setEditingUnit(unit);
    setForm({ unit_number: unit.unit_number || "", address: unit.address || "", status: unit.status || "active", account_number: unit.account_number || "", parcel_id: unit.parcel_id || "", lot: unit.lot || "", is_rental: !!unit.is_rental });
    setDialogOpen(true);
  };

  const generateAccountNumber = async () => {
    try {
      const { data: existing } = await supabase
        .from("units")
        .select("account_number")
        .not("account_number", "is", null);
      const usedNumbers = new Set((existing || []).map((u: any) => u.account_number).filter(Boolean));
      setForm((prev) => ({ ...prev, account_number: createUniqueAccountNumber(usedNumbers) }));
    } catch {
      toast({ title: "Failed to generate account number", variant: "destructive" });
    }
  };

  const handleSave = async () => {
    if (!form.unit_number.trim()) {
      toast({ title: "Unit number is required", variant: "destructive" });
      return;
    }
    const assocId = editingUnit ? editingUnit.association_id : (selectedAssociationId !== "all" ? selectedAssociationId : "");
    if (!assocId) {
      toast({ title: "Please select a specific association first", variant: "destructive" });
      return;
    }
    setSaving(true);
    try {
      const payload = {
        unit_number: form.unit_number.trim(),
        address: form.address.trim() || null,
        status: form.status,
        account_number: form.account_number.trim() || null,
        parcel_id: form.parcel_id.trim() || null,
        lot: form.lot.trim() || null,
        is_rental: !!form.is_rental,
        association_id: assocId,
      };
      if (editingUnit) {
        const { error } = await supabase.from("units").update(payload).eq("id", editingUnit.id);
        if (error) throw error;
        toast({ title: "Unit updated" });
      } else {
        console.log("Inserting unit payload:", JSON.stringify(payload));
        const { data: insertData, error } = await supabase.from("units").insert(payload).select();
        console.log("Unit insert result - data:", insertData, "error:", error);
        if (error) throw error;
        toast({ title: "Unit created" });
      }
      setDialogOpen(false);
      fetchUnits();
    } catch (err: any) {
      toast({ title: "Error saving unit", description: err.message, variant: "destructive" });
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async (unit: UnitRow, e: React.MouseEvent) => {
    e.stopPropagation();
    if (!confirm(`Delete unit ${unit.unit_number}? This will unlink any owners assigned to it.`)) return;
    try {
      const { error } = await supabase.from("units").delete().eq("id", unit.id);
      if (error) throw error;
      toast({ title: "Unit deleted" });
      fetchUnits();
    } catch (err: any) {
      toast({ title: "Error deleting unit", description: err.message, variant: "destructive" });
    }
  };

  const handleSort = (key: string) => {
    setSortConfig((current) => {
      if (current.key === key) return { key, direction: current.direction === "asc" ? "desc" : "asc" };
      return { key, direction: "asc" };
    });
  };

  const processedData = useMemo(() => {
    let filtered = units;
    if (searchQuery.trim()) {
      const q = searchQuery.toLowerCase();
      filtered = filtered.filter((u) =>
        (u.unit_number || "").toLowerCase().includes(q) ||
        (u.address || "").toLowerCase().includes(q) ||
        (u.associations?.name || "").toLowerCase().includes(q) ||
        (u.owners || []).some((o) =>
          `${o.first_name} ${o.last_name}`.toLowerCase().includes(q) ||
          (o.email || "").toLowerCase().includes(q)
        ) ||
        (u.account_number || "").toLowerCase().includes(q)
      );
    }
    return filtered.sort((a, b) => {
      let valA: string, valB: string;
      if (sortConfig.key === "association") {
        valA = a.associations?.name || "";
        valB = b.associations?.name || "";
      } else {
        valA = a.unit_number || "";
        valB = b.unit_number || "";
      }
      if (valA < valB) return sortConfig.direction === "asc" ? -1 : 1;
      if (valA > valB) return sortConfig.direction === "asc" ? 1 : -1;
      return 0;
    });
  }, [units, searchQuery, sortConfig]);

  const showAllAssociations = selectedAssociationId === "all" || !selectedAssociationId;
  const showPromptToSelect = !selectedAssociationId;

  const SortIcon = ({ columnKey }: { columnKey: string }) => {
    if (sortConfig.key !== columnKey) return <ArrowUpDown className="ml-2 h-4 w-4 text-muted-foreground" />;
    return sortConfig.direction === "asc"
      ? <ChevronUp className="ml-2 h-4 w-4 text-foreground" />
      : <ChevronDown className="ml-2 h-4 w-4 text-foreground" />;
  };

  const allOwners = (unit: UnitRow) => unit.owners || [];

  const handleExport = () => {
    const rows = processedData.map((unit) => {
      const owners = allOwners(unit);
      return {
        "Association": unit.associations?.name || "",
        "Unit #": unit.unit_number || "",
        "Account #": unit.account_number || "",
        "Address": unit.address || "",
        "Owner(s)": owners.map((o) => `${o.first_name} ${o.last_name}`).join("; ") || "",
        "Email(s)": owners.map((o) => o.email).filter(Boolean).join("; ") || "",
        "Status": (unit.status || "active").charAt(0).toUpperCase() + (unit.status || "active").slice(1),
      };
    });
    const ws = XLSX.utils.json_to_sheet(rows);
    const colWidths = [{ wch: 28 }, { wch: 10 }, { wch: 14 }, { wch: 36 }, { wch: 30 }, { wch: 34 }, { wch: 14 }];
    ws["!cols"] = colWidths;
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Unit Directory");
    XLSX.writeFile(wb, `Unit_Directory_${new Date().toISOString().slice(0, 10)}.xlsx`);
    toast({ title: "Exported", description: `${rows.length} units exported to Excel.` });
  };

  const openImportDialog = () => {
    if (showPromptToSelect) {
      toast({ title: "Select an association first", variant: "destructive" });
      return;
    }
    if (showAllAssociations) {
      toast({
        title: "Select one association",
        description: "Choose a specific association before importing units.",
        variant: "destructive",
      });
      return;
    }
    setImportDialogOpen(true);
  };

  const statusBadge = (status: string | null) => {
    const s = (status || "active").toLowerCase();
    const cls =
      s === "delinquent" ? "bg-destructive/10 text-destructive" :
      s === "inactive" ? "bg-muted text-muted-foreground" :
      "bg-emerald-50 text-emerald-700 dark:bg-emerald-950 dark:text-emerald-400";
    return (
      <span className={`inline-flex items-center rounded-full px-3 py-1 text-[10px] font-medium uppercase tracking-wide ${cls}`}>
        {s === "active" ? "Good Standing" : status}
      </span>
    );
  };

  const toggleUnitSelect = (id: string) => {
    setSelectedUnitIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  };

  const toggleSelectAll = () => {
    if (selectedUnitIds.size === processedData.length) {
      setSelectedUnitIds(new Set());
    } else {
      setSelectedUnitIds(new Set(processedData.map((u) => u.id)));
    }
  };

  const handleBulkStatusUpdate = async () => {
    if (selectedUnitIds.size === 0) return;
    setBulkUpdating(true);
    try {
      const { error } = await supabase.from("units").update({ status: bulkStatus }).in("id", Array.from(selectedUnitIds));
      if (error) throw error;
      toast({ title: `${selectedUnitIds.size} unit(s) updated to ${bulkStatus}` });
      setSelectedUnitIds(new Set());
      setBulkStatusDialogOpen(false);
      fetchUnits();
    } catch (err: any) {
      toast({ title: "Error updating units", description: err.message, variant: "destructive" });
    } finally {
      setBulkUpdating(false);
    }
  };

  const handleBulkAssignAccountNumbers = async () => {
    const selectedUnits = units.filter((unit) => selectedUnitIds.has(unit.id));
    const missingAccountUnits = selectedUnits.filter((unit) => !unit.account_number?.trim());

    if (missingAccountUnits.length === 0) {
      toast({ title: "No missing account numbers", description: "Selected units already have account numbers." });
      return;
    }

    setBulkAssigningAccounts(true);
    try {
      const { data: existing, error: existingError } = await supabase
        .from("units")
        .select("account_number")
        .not("account_number", "is", null);
      if (existingError) throw existingError;

      const usedNumbers = new Set((existing || []).map((unit: any) => unit.account_number).filter(Boolean));
      const updates = missingAccountUnits.map((unit) =>
        supabase
          .from("units")
          .update({ account_number: createUniqueAccountNumber(usedNumbers) })
          .eq("id", unit.id)
          .is("account_number", null)
      );

      const results = await Promise.all(updates);
      const error = results.find((result) => result.error)?.error;
      if (error) throw error;

      toast({ title: "Account numbers assigned", description: `${missingAccountUnits.length} unit(s) updated. Existing account numbers were left unchanged.` });
      setSelectedUnitIds(new Set());
      fetchUnits();
    } catch (err: any) {
      toast({ title: "Error assigning account numbers", description: err.message, variant: "destructive" });
    } finally {
      setBulkAssigningAccounts(false);
    }
  };

  const handleBulkSetRental = async (markAsRental: boolean) => {
    if (selectedUnitIds.size === 0) return;
    const ids = Array.from(selectedUnitIds);
    try {
      const { error } = await supabase.from("units").update({ is_rental: markAsRental }).in("id", ids);
      if (error) throw error;
      toast({
        title: markAsRental
          ? `Marked ${ids.length} unit(s) as rental`
          : `Removed rental flag from ${ids.length} unit(s)`,
        description: markAsRental
          ? "Violation notices will be addressed to Current Tenant(s) c/o the owner."
          : "Violation notices will be addressed directly to the owner.",
      });
      setSelectedUnitIds(new Set());
      fetchUnits();
    } catch (err: any) {
      toast({ title: "Error updating rental status", description: err.message, variant: "destructive" });
    }
  };

  return (
    <div className="space-y-6 animate-in fade-in duration-500 max-w-7xl mx-auto pb-12 p-6">
      <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">
            <Building2 className="w-6 h-6" />
          </div>
          <div>
            <h1 className="text-3xl font-bold text-foreground tracking-tight">Units Directory</h1>
            <p className="text-muted-foreground mt-1">Cross-association unit and owner directory for administrative oversight.</p>
          </div>
        </div>

        <div className="flex items-center gap-3">
          <Select value={selectedAssociationId} onValueChange={setSelectedAssociationId}>
            <SelectTrigger className="w-full md:w-[280px]">
              <SelectValue placeholder="Select association..." />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Associations</SelectItem>
              {associations.map((a) => (
                <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Button variant="outline" onClick={handleExport} disabled={showPromptToSelect || processedData.length === 0} className="gap-2">
            <Download className="h-4 w-4" /> Export
          </Button>
          <Button variant="outline" onClick={openImportDialog} disabled={showPromptToSelect} className="gap-2">
            <Upload className="h-4 w-4" /> Import Units
          </Button>
          <LedgerCSVImportDialog
            associationId={selectedAssociationId !== "all" ? selectedAssociationId : undefined}
            onSuccess={fetchUnits}
          />
          <Button onClick={openAddDialog} disabled={showPromptToSelect || showAllAssociations} className="gap-2">
            <Plus className="h-4 w-4" /> Add Unit
          </Button>
        </div>
      </div>

      <Card className="border shadow-sm rounded-xl overflow-hidden">
        <CardContent className="p-4 md:p-6">
          <div className="flex flex-col md:flex-row gap-4 items-center justify-between mb-6">
            <div className="relative w-full md:max-w-md">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <Input
                placeholder="Search unit, owner, association, email..."
                className="pl-9 w-full h-10 rounded-lg"
                value={searchQuery}
                onChange={(e) => setSearchQuery(e.target.value)}
                disabled={showPromptToSelect}
              />
            </div>
            <div className="flex items-center gap-2">
              <div className="text-sm font-medium text-muted-foreground bg-muted px-3 py-1.5 rounded-lg border">
                {showPromptToSelect ? "Awaiting selection" : `Showing ${processedData.length} units`}
              </div>
              {selectedUnitIds.size > 0 && (
                <>
                  <Button variant="outline" size="sm" onClick={() => setBulkWorkflowOpen(true)} className="gap-2">
                    <Play className="h-4 w-4" /> Apply Workflow ({selectedUnitIds.size})
                  </Button>
                  <Button variant="outline" size="sm" onClick={handleBulkAssignAccountNumbers} disabled={bulkAssigningAccounts} className="gap-2">
                    <Wand2 className="h-4 w-4" /> {bulkAssigningAccounts ? "Assigning..." : "Assign Missing Acct #"}
                  </Button>
                  <Button variant="outline" size="sm" onClick={() => handleBulkSetRental(true)} className="gap-2">
                    <Home className="h-4 w-4" /> Mark as Rental
                  </Button>
                  <Button variant="outline" size="sm" onClick={() => handleBulkSetRental(false)} className="gap-2">
                    <HomeIcon className="h-4 w-4" /> Unmark Rental
                  </Button>
                  <Button variant="outline" size="sm" onClick={() => { setBulkStatus("active"); setBulkStatusDialogOpen(true); }} className="gap-2">
                    <Settings2 className="h-4 w-4" /> Update {selectedUnitIds.size} Selected
                  </Button>
                </>
              )}
            </div>
          </div>

          <div className="rounded-lg border overflow-hidden">
            <Table>
              <TableHeader className="bg-muted/50 border-b">
                <TableRow className="hover:bg-muted/50">
                  <TableHead className="w-10 py-3">
                    <Checkbox
                      checked={processedData.length > 0 && selectedUnitIds.size === processedData.length}
                      onCheckedChange={toggleSelectAll}
                      disabled={showPromptToSelect || processedData.length === 0}
                    />
                  </TableHead>
                  {showAllAssociations && (
                    <TableHead className="font-semibold w-[200px] py-3">
                      <Button variant="ghost" onClick={() => handleSort("association")} className="hover:bg-muted -ml-4 h-8 flex items-center uppercase tracking-wider text-xs">
                        Association <SortIcon columnKey="association" />
                      </Button>
                    </TableHead>
                  )}
                  <TableHead className="font-semibold w-32 py-3">
                    <Button variant="ghost" onClick={() => handleSort("unit")} className="hover:bg-muted -ml-4 h-8 flex items-center uppercase tracking-wider text-xs">
                      Unit # <SortIcon columnKey="unit" />
                    </Button>
                  </TableHead>
                  <TableHead className="font-semibold uppercase tracking-wider text-xs py-3 w-32">Acct #</TableHead>
                  <TableHead className="font-semibold uppercase tracking-wider text-xs py-3">Owner</TableHead>
                  <TableHead className="font-semibold uppercase tracking-wider text-xs py-3">Contact</TableHead>
                  <TableHead className="font-semibold uppercase tracking-wider text-xs py-3">Status</TableHead>
                  <TableHead className="font-semibold uppercase tracking-wider text-xs text-right py-3 w-28">Balance</TableHead>
                  <TableHead className="font-semibold uppercase tracking-wider text-xs text-right py-3 w-24">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {showPromptToSelect ? (
                  <TableRow>
                    <TableCell colSpan={showAllAssociations ? 9 : 8} className="h-64 text-center text-muted-foreground">
                      <div className="flex flex-col items-center justify-center">
                        <Info className="h-12 w-12 text-muted-foreground/30 mb-3" />
                        <p className="text-lg font-medium text-foreground">Please select an association</p>
                        <p className="text-sm text-muted-foreground mt-1">Choose an association from the dropdown above to view its units.</p>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : loading ? (
                  Array.from({ length: 8 }).map((_, i) => (
                    <TableRow key={i} className="border-b">
                      {showAllAssociations && <TableCell className="py-4"><Skeleton className="h-4 w-40" /></TableCell>}
                      <TableCell className="py-4"><Skeleton className="h-4 w-16" /></TableCell>
                      <TableCell className="py-4"><Skeleton className="h-4 w-24" /></TableCell>
                      <TableCell className="py-4"><div className="space-y-2"><Skeleton className="h-4 w-32" /><Skeleton className="h-3 w-48" /></div></TableCell>
                      <TableCell className="py-4"><Skeleton className="h-4 w-40" /></TableCell>
                      <TableCell className="py-4"><Skeleton className="h-6 w-24 rounded-full" /></TableCell>
                      <TableCell className="py-4"><Skeleton className="h-4 w-16 ml-auto" /></TableCell>
                    </TableRow>
                  ))
                ) : processedData.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={showAllAssociations ? 9 : 8} className="h-64 text-center text-muted-foreground">
                      <div className="flex flex-col items-center justify-center">
                        <Building2 className="h-12 w-12 text-muted-foreground/30 mb-3" />
                        <p className="text-lg font-medium text-foreground">No units found</p>
                        <p className="text-sm text-muted-foreground mt-1">Click "Add Unit" to create your first unit for this association.</p>
                      </div>
                    </TableCell>
                  </TableRow>
                ) : (
                  processedData.map((unit) => {
                    const owners = allOwners(unit);
                    return (
                      <TableRow
                        key={unit.id}
                        className={`hover:bg-muted/50 transition-colors cursor-pointer group border-b ${selectedUnitIds.has(unit.id) ? "bg-primary/5" : ""}`}
                        onClick={() => navigate(`/dashboard/units/${unit.id}`)}
                      >
                        <TableCell className="py-4" onClick={(e) => e.stopPropagation()}>
                          <Checkbox
                            checked={selectedUnitIds.has(unit.id)}
                            onCheckedChange={() => toggleUnitSelect(unit.id)}
                          />
                        </TableCell>
                        {showAllAssociations && (
                          <TableCell className="font-medium text-foreground py-4">
                            {unit.associations?.name || "Unknown"}
                          </TableCell>
                        )}
                        <TableCell className="py-4">
                          <div className="flex items-center gap-1.5">
                            <Badge variant="outline" className="bg-muted/50 font-mono font-medium group-hover:border-primary/30 group-hover:bg-primary/5 group-hover:text-primary transition-colors px-2.5 py-0.5">
                              {unit.unit_number || "-"}
                            </Badge>
                            {unit.is_rental && (
                              <Badge variant="secondary" className="text-[10px] px-1.5 py-0 h-5">Rental</Badge>
                            )}
                          </div>
                        </TableCell>
                        <TableCell className="py-4">
                          <span className="text-sm text-muted-foreground font-mono">{unit.account_number || "—"}</span>
                        </TableCell>
                        <TableCell className="py-4">
                          <div className="flex flex-col gap-1.5">
                            {owners.length > 0 ? owners.map((o) => (
                              <div key={o.id} className="flex items-center text-sm font-semibold text-foreground">
                                <User className="h-4 w-4 mr-2 text-muted-foreground flex-shrink-0" />
                                {o.first_name} {o.last_name}
                              </div>
                            )) : (
                              <div className="flex items-center text-sm text-muted-foreground/60 italic">
                                <User className="h-4 w-4 mr-2 flex-shrink-0" />
                                No owner assigned
                              </div>
                            )}
                            <div className="flex items-center text-xs text-muted-foreground">
                              <MapPin className="h-3.5 w-3.5 mr-2 text-muted-foreground flex-shrink-0" />
                              <span className="truncate max-w-[250px]" title={unit.address || ""}>
                                {unit.address || "No address on file"}
                              </span>
                            </div>
                          </div>
                        </TableCell>
                        <TableCell className="py-4">
                          <div className="flex flex-col gap-1" onClick={(e) => e.stopPropagation()}>
                            {owners.length > 0 ? owners.map((o) => (
                              <div key={o.id} className="flex items-center text-sm text-muted-foreground">
                                <Mail className="h-4 w-4 mr-2 text-muted-foreground flex-shrink-0" />
                                {o.email ? (
                                  <a href={`mailto:${o.email}`} className="hover:text-primary font-medium hover:underline truncate max-w-[200px] transition-colors" title={o.email}>
                                    {o.email}
                                  </a>
                                ) : (
                                  <span className="text-muted-foreground/60 italic">No email</span>
                                )}
                              </div>
                            )) : (
                              <div className="flex items-center text-sm text-muted-foreground/60 italic">
                                <Mail className="h-4 w-4 mr-2 flex-shrink-0" />
                                No email
                              </div>
                            )}
                          </div>
                        </TableCell>
                        <TableCell className="py-4" onClick={(e) => e.stopPropagation()}>
                          <div className="flex flex-col gap-1.5">
                            {statusBadge(unit.status)}
                            <UnitStatusTagsEditor
                              unitId={unit.id}
                              value={unit.status_tags}
                              onChange={(next) => {
                                setUnits((prev) => prev.map((u) => u.id === unit.id ? { ...u, status_tags: next } : u));
                              }}
                            />
                          </div>
                        </TableCell>
                        <TableCell className="text-right py-4">
                          {(unit.outstanding_balance ?? 0) !== 0 ? (
                            <span className={`text-sm font-semibold ${(unit.outstanding_balance ?? 0) > 0 ? "text-destructive" : "text-emerald-600"}`}>
                              ${Math.abs(unit.outstanding_balance ?? 0).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
                              {(unit.outstanding_balance ?? 0) < 0 ? " CR" : ""}
                            </span>
                          ) : (
                            <span className="text-sm text-muted-foreground">$0.00</span>
                          )}
                        </TableCell>
                        <TableCell className="text-right py-4">
                          <div className="flex items-center justify-end gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                            <Button variant="ghost" size="icon" className="h-8 w-8 text-muted-foreground hover:text-primary" onClick={(e) => openEditDialog(unit, e)}>
                              <Edit2 className="h-4 w-4" />
                            </Button>
                            <Button variant="ghost" size="icon" className="h-8 w-8 text-muted-foreground hover:text-destructive" onClick={(e) => handleDelete(unit, e)}>
                              <Trash2 className="h-4 w-4" />
                            </Button>
                          </div>
                        </TableCell>
                      </TableRow>
                    );
                  })
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>

      {/* Add / Edit Unit Dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{editingUnit ? "Edit Unit" : "Add Unit"}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 pt-2">
            <div>
              <Label>Unit Number *</Label>
              <Input value={form.unit_number} onChange={(e) => setForm({ ...form, unit_number: e.target.value })} placeholder="e.g. 101, A-12, Lot 5" />
            </div>
            <div>
              <Label>Account Number</Label>
              <div className="flex gap-2">
                <Input value={form.account_number} onChange={(e) => setForm({ ...form, account_number: e.target.value })} placeholder="e.g. 101-2603-01" className="flex-1" />
                <Button type="button" variant="outline" size="icon" onClick={generateAccountNumber} title="Auto-generate">
                  <Wand2 className="h-4 w-4" />
                </Button>
              </div>
            </div>
            <div>
              <Label>Address</Label>
              <Input value={form.address} onChange={(e) => setForm({ ...form, address: e.target.value })} placeholder="Property address" />
            </div>
            <div>
              <Label>Parcel ID</Label>
              <Input value={form.parcel_id} onChange={(e) => setForm({ ...form, parcel_id: e.target.value })} placeholder="e.g. 12-34-56-78" />
            </div>
            <div>
              <Label>Lot</Label>
              <Input value={form.lot} onChange={(e) => setForm({ ...form, lot: e.target.value })} placeholder="e.g. Lot 42" />
            </div>
            <div>
              <Label>Status</Label>
              <Select value={form.status} onValueChange={(v) => setForm({ ...form, status: v })}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">Active</SelectItem>
                  <SelectItem value="inactive">Inactive</SelectItem>
                  <SelectItem value="delinquent">Delinquent</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="flex items-start gap-3 rounded-md border bg-muted/30 p-3">
              <Checkbox
                id="is_rental"
                checked={!!form.is_rental}
                onCheckedChange={(checked) => setForm({ ...form, is_rental: checked === true })}
                className="mt-0.5"
              />
              <div className="space-y-1">
                <Label htmlFor="is_rental" className="cursor-pointer font-medium">This unit is a rental</Label>
                <p className="text-xs text-muted-foreground">
                  When enabled, violation notices for this unit will be addressed to "Current Tenant(s)" automatically.
                </p>
              </div>
            </div>
            <div className="flex justify-end gap-2 pt-2">
              <Button variant="outline" onClick={() => setDialogOpen(false)}>Cancel</Button>
              <Button onClick={handleSave} disabled={saving}>{saving ? "Saving..." : editingUnit ? "Update" : "Create"}</Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      <ImportSpreadsheetDialog
        open={importDialogOpen}
        onOpenChange={setImportDialogOpen}
        title="Import Units"
        description="Upload a CSV or Excel file to bulk-create units for the selected association, including optional account numbers."
        templateFileName="units_import_template.xlsx"
        expectedColumns={[
          { key: "unit_number", label: "Unit Number", required: true },
          { key: "account_number", label: "Account Number" },
          { key: "parcel_id", label: "Parcel ID", aliases: ["Parcel", "APN"] },
          { key: "lot", label: "Lot", aliases: ["Lot Number", "Lot #"] },
          { key: "address", label: "Address" },
          { key: "status", label: "Status" },
          { key: "image_url", label: "Image URL" },
        ]}
        onImport={async (rows) => {
          const assocId = selectedAssociationId !== "all" ? selectedAssociationId : "";
          if (!assocId) throw new Error("Select a specific association first.");

          const unitsToInsert = rows.map((row, index) => {
            const unitNumber = (row.unit_number || row.unit || "").trim();
            if (!unitNumber) throw new Error(`Row ${index + 1} is missing a unit number.`);

            const normalizedStatus = (row.status || "active").trim().toLowerCase();
            const status = ["active", "inactive", "delinquent"].includes(normalizedStatus) ? normalizedStatus : "active";

            return {
              association_id: assocId,
              unit_number: unitNumber,
              account_number: (row.account_number || row.account || "").trim() || null,
              parcel_id: (row.parcel_id || "").trim() || null,
              lot: (row.lot || "").trim() || null,
              address: (row.address || "").trim() || null,
              status,
              image_url: (row.image_url || "").trim() || null,
            };
          });

          const { error } = await supabase.from("units").insert(unitsToInsert);
          if (error) throw error;
          toast({ title: `${unitsToInsert.length} units imported` });
          fetchUnits();
        }}
      />

      {/* Bulk Status Update Dialog */}
      <Dialog open={bulkStatusDialogOpen} onOpenChange={setBulkStatusDialogOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Bulk Update Status — {selectedUnitIds.size} Unit(s)</DialogTitle>
          </DialogHeader>
          <div className="space-y-4 pt-2">
            <div>
              <Label>New Status</Label>
              <Select value={bulkStatus} onValueChange={setBulkStatus}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">Active</SelectItem>
                  <SelectItem value="inactive">Inactive</SelectItem>
                  <SelectItem value="delinquent">Delinquent</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="flex justify-end gap-2 pt-2">
              <Button variant="outline" onClick={() => setBulkStatusDialogOpen(false)}>Cancel</Button>
              <Button onClick={handleBulkStatusUpdate} disabled={bulkUpdating}>
                {bulkUpdating ? "Updating..." : `Update ${selectedUnitIds.size} Units`}
              </Button>
            </div>
          </div>
        </DialogContent>
      </Dialog>

      <BulkApplyWorkflowDialog
        open={bulkWorkflowOpen}
        onOpenChange={setBulkWorkflowOpen}
        units={processedData
          .filter((u) => selectedUnitIds.has(u.id))
          .map((u) => ({
            unitId: u.id,
            unitNumber: u.unit_number,
            associationId: u.association_id,
            associationName: u.associations?.name || "",
          }))}
        onSuccess={() => {
          setSelectedUnitIds(new Set());
          fetchUnits();
        }}
      />
    </div>
  );
}
