import { useState, useEffect, useMemo, useCallback, Fragment } from "react";
import { useSearchParams } from "react-router-dom";
import { supabase } from "@/integrations/supabase/client";
import { useAuth } from "@/contexts/AuthContext";
import { useToast } from "@/hooks/use-toast";
import { useDocumentSummary } from "@/hooks/useDocumentSummary";
import { FileText, Plus, Search, Trash2, Download, MoreHorizontal, FolderPlus, Upload, Eye, EyeOff, Folder, FolderOpen, ChevronRight, ChevronDown, File, Share2, UploadCloud, Pencil, FolderInput, Loader2, HardDrive, ExternalLink, Unlink, Globe, Copy, Link, Users, Home, Sparkles, ArrowUp, CornerLeftUp, Shield } from "lucide-react";
import { Tooltip, TooltipContent, TooltipTrigger, TooltipProvider } from "@/components/ui/tooltip";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { format } from "date-fns";
import ShareDialog from "@/components/ShareDialog";
import { useDropzone } from "react-dropzone";
import { useGoogleDrive } from "@/hooks/useGoogleDrive";
import GoogleDrivePickerDialog from "@/components/documents/GoogleDrivePickerDialog";
import GoogleDriveFolderPickerDialog from "@/components/documents/GoogleDriveFolderPickerDialog";
import { buildSecureStorageKey, downloadWithDisplayName } from "@/lib/secureStorageNaming";

const defaultFolders = [
  "Uncategorized", "Bank Statements", "Buildium", "Collections", "Financials", "Insurance",
  "Litigation", "Management Reports", "Meetings", "New Owner Files",
  "Owner Correspondence", "Reports",
];

/* ── Collapsible Folder Sidebar ── */
interface FolderSidebarProps {
  populatedFolders: string[];
  associations: { id: string; name: string }[];
  documents: any[];
  selectedFolder: string | null;
  setSelectedFolder: (f: string) => void;
  canUpload: boolean;
  setParentFolderForNew: (f: string | null) => void;
  setNewFolderName: (n: string) => void;
  setFolderDialogOpen: (o: boolean) => void;
  handleDeleteFolder: (f: string) => void;
  handleRenameFolder: (f: string) => void;
  setShareTarget: (t: { type: "folder" | "document"; name: string; docId?: string }) => void;
  setShareOpen: (o: boolean) => void;
  globalRootFolders: string[];
  showGlobalFolders: boolean;
}

function FolderSidebar({
  populatedFolders, associations, documents, selectedFolder, setSelectedFolder,
  canUpload, setParentFolderForNew, setNewFolderName, setFolderDialogOpen,
  handleDeleteFolder, handleRenameFolder, setShareTarget, setShareOpen,
  globalRootFolders, showGlobalFolders,
}: FolderSidebarProps) {
  const [expandedAssocs, setExpandedAssocs] = useState<Set<string>>(() => new Set());

  const { categoryFolders, assocTree, driveOrphanFolders } = useMemo(() => {
    const assocNames = new Set(associations.map(a => a.name));
    const cats: string[] = [];
    const tree: Record<string, string[]> = {};
    const driveOrphans: string[] = [];

    for (const folder of populatedFolders) {
      const parts = folder.split("/");
      const root = parts[0];

      if (root === "Google Drive") {
        if (parts.length === 1) continue;
        driveOrphans.push(folder);
        continue;
      }

      if (assocNames.has(root)) {
        if (!tree[root]) tree[root] = [];
        if (parts.length > 1) tree[root].push(folder);
      } else {
        const parentAssoc = Array.from(assocNames).find(n => folder.startsWith(n + "/"));
        if (parentAssoc) {
          if (!tree[parentAssoc]) tree[parentAssoc] = [];
          tree[parentAssoc].push(folder);
        } else {
          cats.push(folder);
        }
      }
    }

    return { categoryFolders: cats, assocTree: tree, driveOrphanFolders: driveOrphans };
  }, [populatedFolders, associations]);

  const toggleAssoc = (name: string) => {
    setExpandedAssocs(prev => {
      const next = new Set(prev);
      if (next.has(name)) next.delete(name); else next.add(name);
      return next;
    });
  };

  useEffect(() => {
    if (!selectedFolder) return;
    for (const assocName of Object.keys(assocTree)) {
      if (selectedFolder === assocName || selectedFolder.startsWith(assocName + "/")) {
        setExpandedAssocs(prev => {
          if (prev.has(assocName)) return prev;
          const next = new Set(prev);
          next.add(assocName);
          return next;
        });
      }
    }
  }, [selectedFolder, assocTree]);

  const renderFolderItem = (folder: string, displayName: string, indent = 0) => {
    const isSelected = selectedFolder === folder;
    return (
      <div key={folder} className="flex items-center group" style={{ paddingLeft: indent }}>
        <button
          onClick={() => setSelectedFolder(folder)}
          title={displayName}
          className={`flex-1 min-w-0 text-left text-sm px-3 py-1.5 rounded-l-md flex items-center gap-2 transition-colors ${
            isSelected ? "bg-primary text-primary-foreground font-medium" : "text-foreground hover:bg-muted"
          }`}
        >
          {isSelected ? <FolderOpen className="h-3.5 w-3.5 shrink-0" /> : <Folder className="h-3.5 w-3.5 shrink-0" />}
          <span className="truncate">{displayName}</span>
        </button>
        {canUpload && (
          <>
            <button onClick={() => { setParentFolderForNew(folder); setNewFolderName(""); setFolderDialogOpen(true); }}
              className={`px-1 py-1.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0 ${isSelected ? "text-primary-foreground/70 hover:text-primary-foreground" : "text-muted-foreground hover:text-foreground"}`}
              title="Create subfolder"><FolderPlus className="h-3 w-3" /></button>
            <button onClick={(e) => { e.stopPropagation(); handleRenameFolder(folder); }}
              className={`px-1 py-1.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0 ${isSelected ? "text-primary-foreground/70 hover:text-primary-foreground" : "text-muted-foreground hover:text-foreground"}`}
              title="Rename folder"><Pencil className="h-3 w-3" /></button>
            <button onClick={(e) => { e.stopPropagation(); handleDeleteFolder(folder); }}
              className={`px-1 py-1.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0 ${isSelected ? "text-primary-foreground/70 hover:text-primary-foreground" : "text-destructive/70 hover:text-destructive"}`}
              title="Delete folder (must be empty)"><Trash2 className="h-3 w-3" /></button>
          </>
        )}
        <button onClick={() => { setShareTarget({ type: "folder", name: folder }); setShareOpen(true); }}
          className={`px-1 py-1.5 rounded-r-md opacity-0 group-hover:opacity-100 transition-opacity shrink-0 ${isSelected ? "text-primary-foreground/70 hover:text-primary-foreground" : "text-muted-foreground hover:text-foreground"}`}
          title="Share folder"><Share2 className="h-3 w-3" /></button>
      </div>
    );
  };

  const globalSet = new Set(showGlobalFolders ? globalRootFolders : []);
  const visibleCategoryFolders = categoryFolders.filter(f => !globalSet.has(f.split("/")[0]));

  const parentFolder = selectedFolder
    ? selectedFolder.includes("/")
      ? selectedFolder.split("/").slice(0, -1).join("/")
      : null
    : null;

  return (
    <div className="w-[250px] shrink-0 flex flex-col max-h-[calc(100vh-220px)]">
      <div className="flex items-center justify-between mb-2 px-1">
        <h3 className="text-xs font-bold uppercase text-muted-foreground tracking-wider">FOLDERS</h3>
        {selectedFolder && parentFolder !== undefined && (
          <button
            onClick={() => setSelectedFolder(parentFolder || "")}
            className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors"
            title="Go to parent folder"
          >
            <ArrowUp className="h-3 w-3" /> Up
          </button>
        )}
      </div>
      <div className="overflow-y-auto flex-1 space-y-0.5 pr-1">
        {showGlobalFolders && globalRootFolders.length > 0 && (
          <div className="mb-2">
            <div className="flex items-center gap-1.5 px-2 pb-1">
              <span className="text-[10px] font-semibold uppercase text-muted-foreground/60 tracking-wider">Global Folders</span>
              <Badge variant="outline" className="text-[9px] px-1 py-0 h-3.5">Admin</Badge>
            </div>
            {globalRootFolders.map(folder => renderFolderItem(folder, folder))}
          </div>
        )}

        {visibleCategoryFolders.map(folder => renderFolderItem(folder, folder))}

        {Object.keys(assocTree).length > 0 && (
          <div className="border-t border-border/50 mt-2 pt-2">
            <div className="text-[10px] font-semibold uppercase text-muted-foreground/60 px-2 pb-1 tracking-wider">
              By Association
            </div>
          </div>
        )}

        {Object.keys(assocTree).sort().map(assocName => {
          const isExpanded = expandedAssocs.has(assocName);
          const subfolders = assocTree[assocName];
          const isAssocSelected = selectedFolder === assocName;

          return (
            <div key={assocName}>
              <div className="flex items-center group">
                <button onClick={() => toggleAssoc(assocName)} className="p-1 text-muted-foreground hover:text-foreground shrink-0">
                  {isExpanded ? <ChevronDown className="h-3 w-3" /> : <ChevronRight className="h-3 w-3" />}
                </button>
                <button
                  onClick={() => { setSelectedFolder(assocName); if (!isExpanded) toggleAssoc(assocName); }}
                  title={assocName}
                  className={`flex-1 min-w-0 text-left text-[13px] px-2 py-1.5 rounded-md flex items-center gap-2 transition-colors ${
                    isAssocSelected ? "bg-primary text-primary-foreground font-medium" : "text-foreground hover:bg-muted font-medium"
                  }`}
                >
                  {isAssocSelected ? <FolderOpen className="h-3.5 w-3.5 shrink-0" /> : <Folder className="h-3.5 w-3.5 shrink-0" />}
                  <span className="truncate">{assocName}</span>
                </button>
              </div>
              {isExpanded && subfolders.length > 0 && (
                <div className="ml-5 space-y-0.5 mt-0.5">
                  {subfolders.map(sub => renderFolderItem(sub, sub.split("/").pop() || sub, 8))}
                </div>
              )}
            </div>
          );
        })}

        {driveOrphanFolders.length > 0 && (
          <div className="border-t border-border/50 mt-2 pt-2">
            <div className="text-[10px] font-semibold uppercase text-muted-foreground/60 px-2 pb-1 tracking-wider">Google Drive</div>
            {driveOrphanFolders.map(folder => renderFolderItem(folder, folder.split("/").pop() || folder, 8))}
          </div>
        )}
      </div>
    </div>
  );
}

export default function DocumentsPage({
  boardAssociationIds,
  viewerRole = "admin",
  boardCanUpload = false,
}: {
  boardAssociationIds?: string[];
  viewerRole?: "admin" | "board" | "homeowner";
  /** For board viewers: whether this board member is permitted to upload. */
  boardCanUpload?: boolean;
} = {}) {
  const { toast } = useToast();
  const { isAdmin } = useAuth();
  const [documents, setDocuments] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [selectedFolder, setSelectedFolder] = useState<string | null>(null);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [folderDialogOpen, setFolderDialogOpen] = useState(false);
  const [newFolderName, setNewFolderName] = useState("");
  const [parentFolderForNew, setParentFolderForNew] = useState<string | null>(null);
  const [customFolders, setCustomFolders] = useState<string[]>(() => {
    try {
      const stored = localStorage.getItem("doc_custom_folders");
      return stored ? JSON.parse(stored) : [];
    } catch { return []; }
  });
  const [form, setForm] = useState({ title: "", category: "general", file_name: "" });
  const [shareOpen, setShareOpen] = useState(false);
  const [shareTarget, setShareTarget] = useState<{ type: "folder" | "document"; name: string; docId?: string }>({ type: "folder", name: "" });

  // Edit document state
  const [editDialogOpen, setEditDialogOpen] = useState(false);
  const [editDoc, setEditDoc] = useState<any>(null);
  const [editForm, setEditForm] = useState({ title: "", category: "", file_name: "", association_id: "" });

  // Associations for the upload dialog
  const [associations, setAssociations] = useState<{ id: string; name: string }[]>([]);
  const [selectedAssociationId, setSelectedAssociationId] = useState("");
  const [filterAssociationId, setFilterAssociationId] = useState<string>("all");
  const [pendingFiles, setPendingFiles] = useState<File[]>([]);
  const [uploading, setUploading] = useState(false);
  const [importingBuildium, setImportingBuildium] = useState(false);
  const [isDraggingOver, setIsDraggingOver] = useState(false);

  // Bulk selection state
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [bulkDialogOpen, setBulkDialogOpen] = useState(false);
  const [bulkForm, setBulkForm] = useState({ category: "", association_id: "" });
  const [bulkSaving, setBulkSaving] = useState(false);
  const [bulkVisibility, setBulkVisibility] = useState<string[]>([]);
  // Visibility chosen for files in the upload dialog
  const [uploadVisibility, setUploadVisibility] = useState<string[]>([]);

  // Google Drive integration
  const [searchParams] = useSearchParams();
  const drive = useGoogleDrive();
  const { generateSummary, isSummarizing } = useDocumentSummary();
  const [drivePickerOpen, setDrivePickerOpen] = useState(false);
  const [driveFolderPickerOpen, setDriveFolderPickerOpen] = useState(false);
  const [driveUploadFolder, setDriveUploadFolder] = useState<{ id: string | null; name: string } | null>(null);

  // Hidden-from-homeowner folder rules. folder_path is the path WITHOUT the association name prefix
  // (empty string means the entire association).
  const [hiddenFolderRules, setHiddenFolderRules] = useState<{ id: string; association_id: string; folder_path: string }[]>([]);

  const fetchHiddenFolders = useCallback(async () => {
    const { data } = await (supabase as any)
      .from("association_hidden_homeowner_folders")
      .select("id, association_id, folder_path");
    setHiddenFolderRules(data || []);
  }, []);

  useEffect(() => { fetchHiddenFolders(); }, [fetchHiddenFolders]);

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

  // Fetch shared drive files
  useEffect(() => {
    drive.fetchSharedFiles(boardAssociationIds);
  }, [drive.isConnected, JSON.stringify(boardAssociationIds || [])]);

  // Map association IDs to names for Drive files
  const assocIdToName = useMemo(() => {
    const map: Record<string, string> = {};
    associations.forEach(a => { map[a.id] = a.name; });
    return map;
  }, [associations]);

  const populatedFolders = useMemo(() => {
    const folderSet = new Set<string>();
    documents.forEach(d => {
      const docFolder = d.category === "general" || !d.category ? "Uncategorized" : d.category;
      const assocName = d.associations?.name;
      if (assocName) {
        folderSet.add(assocName);
        const parts = docFolder.split("/").filter(Boolean);
        parts.forEach((_, index) => {
          folderSet.add(`${assocName}/${parts.slice(0, index + 1).join("/")}`);
        });
      } else {
        const parts = docFolder.split("/").filter(Boolean);
        parts.forEach((_, index) => folderSet.add(parts.slice(0, index + 1).join("/")));
      }
    });
    // Also include custom folders created by the user
    customFolders.forEach(f => folderSet.add(f));
    // Add Drive shared files as folder entries
    drive.sharedFiles.forEach(sf => {
      const assocNames = (sf.association_ids || [])
        .map((aid: string) => assocIdToName[aid])
        .filter(Boolean);
      if (assocNames.length > 0) {
        assocNames.forEach((name: string) => {
          folderSet.add(name);
          folderSet.add(`${name}/${sf.drive_file_name}`);
        });
      } else {
        // No association linked — show as top-level Drive subfolder
        folderSet.add(`Google Drive/${sf.drive_file_name}`);
      }
    });
    if (drive.sharedFiles.some(sf => !(sf.association_ids?.length))) {
      folderSet.add("Google Drive");
    }
    const sorted = Array.from(folderSet).sort((a, b) => {
      if (a === "Uncategorized") return -1;
      if (b === "Uncategorized") return 1;
      return a.localeCompare(b);
    });
    return sorted;
  }, [documents, customFolders, drive.sharedFiles, assocIdToName]);

  const isBoardView = viewerRole === "board" || (!!boardAssociationIds?.length && viewerRole !== "homeowner");
  const isHomeownerView = viewerRole === "homeowner";
  const isReadOnlyView = isBoardView || isHomeownerView;
  // Board members can upload only when granted the per-member permission;
  // homeowners are always read-only; staff can always upload.
  const canUpload = isHomeownerView ? false : isBoardView ? boardCanUpload : true;

  const getFolderAssociation = (folder: string | null) => {
    if (!folder) return null;
    return associations.find(a => folder === a.name || folder.startsWith(`${a.name}/`)) || null;
  };

  const getDocumentCategoryForFolder = (folder: string | null) => {
    if (!folder) return "general";
    const assoc = getFolderAssociation(folder);
    const folderName = assoc ? (folder === assoc.name ? "Uncategorized" : folder.slice(assoc.name.length + 1)) : folder;
    return folderName === "Uncategorized" ? "general" : folderName;
  };

  // Resolve a sidebar folder path -> { association_id, subPath } (subPath '' = whole assoc)
  const resolveFolderRule = useCallback((folder: string) => {
    const assoc = associations.find(a => folder === a.name || folder.startsWith(`${a.name}/`));
    if (!assoc) return null;
    const subPath = folder === assoc.name ? "" : folder.slice(assoc.name.length + 1);
    return { association_id: assoc.id, subPath };
  }, [associations]);

  const isFolderHidden = useCallback((folder: string) => {
    const r = resolveFolderRule(folder);
    if (!r) return false;
    return hiddenFolderRules.some(h =>
      h.association_id === r.association_id &&
      (h.folder_path === r.subPath || (r.subPath && r.subPath.startsWith(h.folder_path + "/")) || h.folder_path === "")
    );
  }, [hiddenFolderRules, resolveFolderRule]);

  const toggleFolderHidden = useCallback(async (folder: string) => {
    const r = resolveFolderRule(folder);
    if (!r) {
      toast({ title: "Cannot hide this folder", description: "Only association folders can be hidden from homeowners.", variant: "destructive" });
      return;
    }
    const existing = hiddenFolderRules.find(h => h.association_id === r.association_id && h.folder_path === r.subPath);
    if (existing) {
      const { error } = await (supabase as any).from("association_hidden_homeowner_folders").delete().eq("id", existing.id);
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      toast({ title: "Folder visible to homeowners" });
    } else {
      const { error } = await (supabase as any).from("association_hidden_homeowner_folders").insert({
        association_id: r.association_id,
        folder_path: r.subPath,
      });
      if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
      toast({ title: "Folder hidden from homeowners" });
    }
    fetchHiddenFolders();
  }, [hiddenFolderRules, resolveFolderRule, fetchHiddenFolders, toast]);

  const fetchDocuments = async () => {
    setLoading(true);
    let query = supabase.from("documents").select("*, associations(name)").order("created_at", { ascending: false });
    if (isReadOnlyView && boardAssociationIds?.length) {
      query = query.in("association_id", boardAssociationIds!);
    }
    if (isBoardView) {
      // Board members should only see docs with board or public visibility
      query = query.or("visibility.cs.{board_member},visibility.cs.{public}");
    } else if (isHomeownerView) {
      // Homeowners should only see docs marked for homeowner or public
      query = query.or("visibility.cs.{homeowner},visibility.cs.{public}");
    }
    const { data, error } = await query;
    if (error) toast({ title: "Error", description: error.message, variant: "destructive" });
    else setDocuments(data || []);
    setLoading(false);
  };

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

  useEffect(() => { fetchDocuments(); fetchAssociations(); }, [JSON.stringify(boardAssociationIds || [])]);

  // Default view: show overview of ALL files and folders (no folder pre-selected).

  // When an association filter is chosen, auto-open that association's folder
  // so its subfolders/files are immediately visible.
  useEffect(() => {
    if (filterAssociationId === "all" || filterAssociationId === "none") {
      setSelectedFolder(null);
      return;
    }
    const assoc = associations.find(a => a.id === filterAssociationId);
    if (assoc) setSelectedFolder(assoc.name);
    else setSelectedFolder(null);
  }, [filterAssociationId, associations]);

  // For board/homeowner views, lock the filter to their association automatically.
  useEffect(() => {
    if (!isReadOnlyView) return;
    if (associations.length === 0) return;
    const target = boardAssociationIds?.[0] || associations[0]?.id;
    if (target && filterAssociationId !== target) {
      setFilterAssociationId(target);
    }
  }, [isReadOnlyView, associations, boardAssociationIds]);

  // Upload files to storage + create document records
  const handleUploadFiles = async () => {
    const isGlobalUpload = selectedAssociationId === "__none__";
    if (!selectedAssociationId || (isGlobalUpload && !isAdmin)) {
      toast({ title: "Association required", description: "Please select an association before uploading.", variant: "destructive" });
      return;
    }
    if (pendingFiles.length === 0) return;

    setUploading(true);
    let successCount = 0;

    for (const file of pendingFiles) {
      try {
        // Sanitize + randomize the storage key so the public URL doesn't
        // expose the document's real name. The original filename is kept on
        // the documents row (file_name) for display & download.
        const folderForKey = getDocumentCategoryForFolder(selectedFolder);
        const storagePath = buildSecureStorageKey(
          file.name,
          `${isGlobalUpload ? "global" : selectedAssociationId}/${folderForKey}`,
        );

        const { error: uploadError } = await supabase.storage.from("files").upload(storagePath, file, {
          upsert: false,
          contentType: file.type,
        });
        if (uploadError) throw uploadError;

        const { data: urlData } = supabase.storage.from("files").getPublicUrl(storagePath);

        const { data: insertData, error: dbError } = await supabase.from("documents").insert({
          title: file.name.replace(/\.[^/.]+$/, ""),
          file_name: file.name,
          file_url: urlData.publicUrl,
          file_size: file.size,
          category: getDocumentCategoryForFolder(selectedFolder),
          association_id: isGlobalUpload ? null : selectedAssociationId,
          visibility: uploadVisibility,
          is_public: uploadVisibility.includes("public"),
        }).select("id").single();
        if (dbError) throw dbError;
        successCount++;

        // Trigger AI summary in background for management reports
        const folderLower = (selectedFolder || "").toLowerCase();
        if (folderLower.includes("management") || folderLower.includes("report")) {
          generateSummary(insertData.id, urlData.publicUrl, file.name).then(() => {
            fetchDocuments();
          });
        }

        // Save to Google Drive when a destination was chosen for this upload.
        if (driveUploadFolder) {
          const result = await drive.uploadFile(file, driveUploadFolder.id || undefined);
          if (!result.success) throw new Error(`Saved locally, but failed to save ${file.name} to Google Drive.`);
        }
      } catch (err: any) {
        toast({ title: `Failed to upload ${file.name}`, description: err.message, variant: "destructive" });
      }
    }

    if (successCount > 0) {
      toast({ title: `${successCount} file${successCount > 1 ? "s" : ""} uploaded` });
      fetchDocuments();
    }
    setUploading(false);
    setDialogOpen(false);
    setPendingFiles([]);
    setSelectedAssociationId("");
    setDriveUploadFolder(null);
    setUploadVisibility([]);
  };

  // Import documents from Buildium for the currently filtered association(s).
  // Runs one association per request to stay under the 150s edge function idle timeout.
  const handleImportFromBuildium = async (scope: "association" | "company" = "association") => {
    setImportingBuildium(true);
    try {
      const isCompany = scope === "company";
      const folderAssoc = isCompany ? null : getFolderAssociation(selectedFolder);
      const targetAssocIds = isCompany
        ? []
        : folderAssoc
          ? [folderAssoc.id]
          : filterAssociationId !== "all"
            ? [filterAssociationId]
            : associations.map(a => a.id);
      if (!isCompany && targetAssocIds.length === 0) {
        toast({ title: "No associations available", variant: "destructive" });
        return;
      }
      toast({
        title: "Importing from Buildium…",
        description: isCompany
          ? "Processing company-level files. This may take a few minutes."
          : `Processing ${targetAssocIds.length} association${targetAssocIds.length > 1 ? "s" : ""}. This may take a few minutes.`,
      });

      let totalFetched = 0;
      let totalCreated = 0;
      let totalSkipped = 0;
      const failures: string[] = [];

      const runLoop = async (label: string, body: Record<string, unknown>) => {
        let offset = 0;
        let fetchedMax = 0;
        while (true) {
          const { data, error } = await supabase.functions.invoke("buildium-sync", {
            body: { ...body, documentOffset: offset, documentLimit: 1 },
          });
          if (error) throw error;
          const r = data?.results?.documents;
          if (!r) break;
          fetchedMax = Math.max(fetchedMax, r.fetched || 0);
          totalCreated += r.created || 0;
          totalSkipped += r.skipped || 0;
          if (Array.isArray(r.errors) && r.errors.length) failures.push(`${label}: ${r.errors.join("; ")}`);
          if (typeof r.nextOffset !== "number") break;
          offset = r.nextOffset;
        }
        totalFetched += fetchedMax;
      };

      if (isCompany) {
        try {
          await runLoop("company", { syncType: "documents", documentScope: "company" });
        } catch (e: any) {
          failures.push(`company: ${e.message || e}`);
        }
      } else {
        for (const assocId of targetAssocIds) {
          const assocName = associations.find(a => a.id === assocId)?.name || assocId;
          try {
            await runLoop(assocName, { syncType: "documents", selectedAssociationIds: [assocId] });
          } catch (e: any) {
            failures.push(`${assocName}: ${e.message || e}`);
          }
        }
      }

      toast({
        title: failures.length ? "Buildium import finished with errors" : "Buildium import complete",
        description: `Fetched ${totalFetched}, created ${totalCreated}, skipped ${totalSkipped}.${failures.length ? ` ${failures.length} association(s) failed.` : ""}`,
        variant: failures.length ? "destructive" : "default",
      });
      fetchDocuments();
    } catch (err: any) {
      toast({ title: "Buildium import failed", description: err.message, variant: "destructive" });
    } finally {
      setImportingBuildium(false);
    }
  };

  // Open upload dialog with files
  const openUploadWithFiles = (files: File[]) => {
    setPendingFiles(files);
    setForm({ title: "", category: getDocumentCategoryForFolder(selectedFolder), file_name: "" });
    if (associations.length === 1) setSelectedAssociationId(associations[0].id);
    else setSelectedAssociationId("");
    // Board members default to sharing with the board so co-board members can see it.
    setUploadVisibility(isBoardView ? ["board_member"] : []);
    setDialogOpen(true);
  };

  // Dropzone config
  const onDrop = useCallback((acceptedFiles: File[]) => {
    setIsDraggingOver(false);
    if (!canUpload) return;
    if (acceptedFiles.length > 0) openUploadWithFiles(acceptedFiles);
  }, [associations, selectedFolder, canUpload]);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop,
    noClick: true,
    noKeyboard: true,
    onDragEnter: () => setIsDraggingOver(true),
    onDragLeave: () => setIsDraggingOver(false),
  });

  const handleCreate = async () => {
    const isGlobalUpload = selectedAssociationId === "__none__";
    if (!selectedAssociationId || (isGlobalUpload && !isAdmin)) {
      toast({ title: "Association required", description: "Please select an association.", variant: "destructive" });
      return;
    }
    const { error } = await supabase.from("documents").insert({ ...form, category: getDocumentCategoryForFolder(selectedFolder), association_id: isGlobalUpload ? null : selectedAssociationId });
    if (error) { toast({ title: "Error", description: error.message, variant: "destructive" }); return; }
    toast({ title: "Document added" });
    setDialogOpen(false);
    fetchDocuments();
  };

  const handleDelete = async (id: string) => {
    const { error } = await supabase.from("documents").delete().eq("id", id);
    if (error) toast({ title: "Error", description: error.message, variant: "destructive" });
    else { toast({ title: "Document deleted" }); fetchDocuments(); }
  };

  const handleCreateFolder = () => {
    const trimmed = newFolderName.trim();
    if (!trimmed) {
      toast({ title: "Folder name required", description: "Please enter a name for the new folder.", variant: "destructive" });
      return;
    }
    const fullName = parentFolderForNew ? `${parentFolderForNew}/${trimmed}` : trimmed;
    if (populatedFolders.includes(fullName)) {
      toast({ title: "Folder already exists", variant: "destructive" });
      return;
    }
    const updated = [...customFolders, fullName];
    setCustomFolders(updated);
    localStorage.setItem("doc_custom_folders", JSON.stringify(updated));
    setNewFolderName("");
    setParentFolderForNew(null);
    setFolderDialogOpen(false);
    setSelectedFolder(fullName);
    toast({ title: "Folder created", description: fullName });
  };

  const handleDeleteFolder = async (folder: string) => {
    const docsInFolder = documents.filter(d => {
      const docFolder = d.category === "general" || !d.category ? "Uncategorized" : d.category;
      const assocName = d.associations?.name;
      const normalizedFolder = assocName ? `${assocName}/${docFolder}` : docFolder;
      return normalizedFolder === folder || normalizedFolder.startsWith(folder + "/");
    });

    if (docsInFolder.length > 0) {
      toast({
        title: "Folder is not empty",
        description: `"${folder}" contains ${docsInFolder.length} document(s). Move or delete them before deleting the folder.`,
        variant: "destructive",
      });
      return;
    }

    // Also block if it has populated subfolders from other custom folders
    const hasSubfolders = customFolders.some(f => f !== folder && f.startsWith(folder + "/"));
    if (hasSubfolders) {
      if (!confirm(`Delete folder "${folder}" and its empty subfolders?`)) return;
    } else {
      if (!confirm(`Delete folder "${folder}"?`)) return;
    }

    // Remove from custom folders (including any subfolders)
    const updated = customFolders.filter(f => f !== folder && !f.startsWith(folder + "/"));
    setCustomFolders(updated);
    localStorage.setItem("doc_custom_folders", JSON.stringify(updated));

    if (selectedFolder === folder || selectedFolder?.startsWith(folder + "/")) {
      setSelectedFolder(null);
    }
    fetchDocuments();
    toast({ title: "Folder deleted", description: folder });
  };

  const handleRenameFolder = async (folder: string) => {
    // Don't allow renaming an association-root folder
    const assoc = getFolderAssociation(folder);
    if (assoc && folder === assoc.name) {
      toast({ title: "Cannot rename", description: "Association folders cannot be renamed.", variant: "destructive" });
      return;
    }
    if (folder === "Uncategorized" || (assoc && folder === `${assoc.name}/Uncategorized`)) {
      toast({ title: "Cannot rename", description: "The Uncategorized folder cannot be renamed.", variant: "destructive" });
      return;
    }
    if (folder.startsWith("Google Drive")) {
      toast({ title: "Cannot rename", description: "Google Drive folders cannot be renamed here.", variant: "destructive" });
      return;
    }

    const currentName = folder.split("/").pop() || folder;
    const input = prompt(`Rename folder "${currentName}" to:`, currentName);
    if (input === null) return;
    const trimmed = input.trim();
    if (!trimmed || trimmed === currentName) return;
    if (trimmed.includes("/")) {
      toast({ title: "Invalid name", description: "Folder name cannot contain '/'.", variant: "destructive" });
      return;
    }

    const parentParts = folder.split("/");
    parentParts.pop();
    const newFullName = parentParts.length > 0 ? `${parentParts.join("/")}/${trimmed}` : trimmed;

    if (populatedFolders.includes(newFullName)) {
      toast({ title: "Folder already exists", variant: "destructive" });
      return;
    }

    // Update documents whose category matches this folder (or any subfolder of it)
    const docsToUpdate = documents.filter(d => {
      const docFolder = d.category === "general" || !d.category ? "Uncategorized" : d.category;
      const assocName = d.associations?.name;
      const normalizedFolder = assocName ? `${assocName}/${docFolder}` : docFolder;
      return normalizedFolder === folder || normalizedFolder.startsWith(folder + "/");
    });

    for (const doc of docsToUpdate) {
      const docAssocName = doc.associations?.name;
      const oldCat = doc.category === "general" || !doc.category ? "Uncategorized" : doc.category;
      const oldNormalized = docAssocName ? `${docAssocName}/${oldCat}` : oldCat;
      const newNormalized = oldNormalized === folder ? newFullName : newFullName + oldNormalized.slice(folder.length);
      const newCat = docAssocName ? newNormalized.slice(docAssocName.length + 1) : newNormalized;
      const { error } = await supabase
        .from("documents")
        .update({ category: newCat === "Uncategorized" ? "general" : newCat })
        .eq("id", doc.id);
      if (error) {
        toast({ title: "Error renaming", description: error.message, variant: "destructive" });
        return;
      }
    }

    // Update custom folder entries (including subfolders)
    const updated = customFolders.map(f => {
      if (f === folder) return newFullName;
      if (f.startsWith(folder + "/")) return newFullName + f.slice(folder.length);
      return f;
    });
    setCustomFolders(updated);
    localStorage.setItem("doc_custom_folders", JSON.stringify(updated));

    if (selectedFolder === folder) setSelectedFolder(newFullName);
    else if (selectedFolder?.startsWith(folder + "/")) setSelectedFolder(newFullName + selectedFolder.slice(folder.length));

    fetchDocuments();
    toast({ title: "Folder renamed", description: `${folder} → ${newFullName}` });
  };

  const openEditDialog = (doc: any) => {
    setEditDoc(doc);
    setEditForm({
      title: doc.title || "",
      category: doc.category === "general" || !doc.category ? "Uncategorized" : doc.category,
      file_name: doc.file_name || "",
      association_id: doc.association_id || "",
    });
    setEditDialogOpen(true);
  };

  const handleEditSave = async () => {
    if (!editDoc) return;
    const category = editForm.category === "Uncategorized" ? "general" : editForm.category;
    const { error } = await supabase
      .from("documents")
      .update({ title: editForm.title, category, file_name: editForm.file_name, association_id: editForm.association_id || null })
      .eq("id", editDoc.id);
    if (error) {
      toast({ title: "Error", description: error.message, variant: "destructive" });
    } else {
      toast({ title: "Document updated" });
      setEditDialogOpen(false);
      setEditDoc(null);
      fetchDocuments();
    }
  };

  const handleDownload = async (doc: any) => {
    if (!doc.file_url) { toast({ title: "No file available" }); return; }
    // Use the original/display name (file_name or title) so the user never
    // sees the obfuscated storage key.
    const displayName = doc.file_name || doc.title || "document";
    await downloadWithDisplayName(doc.file_url, displayName);
  };

  // Bulk update handler
  const handleBulkUpdate = async () => {
    if (selectedIds.size === 0) return;
    setBulkSaving(true);
    try {
      const updates: Record<string, any> = {};
      if (bulkForm.category) updates.category = bulkForm.category === "Uncategorized" ? "general" : bulkForm.category;
      if (bulkForm.association_id) updates.association_id = bulkForm.association_id;
      if (Object.keys(updates).length === 0) {
        toast({ title: "No changes selected", variant: "destructive" });
        setBulkSaving(false);
        return;
      }
      const { error } = await supabase
        .from("documents")
        .update(updates)
        .in("id", Array.from(selectedIds));
      if (error) throw error;
      toast({ title: `${selectedIds.size} document(s) updated` });
      setSelectedIds(new Set());
      setBulkDialogOpen(false);
      setBulkForm({ category: "", association_id: "" });
      fetchDocuments();
    } catch (err: any) {
      toast({ title: "Error", description: err.message, variant: "destructive" });
    } finally {
      setBulkSaving(false);
    }
  };

  const handleBulkDelete = async () => {
    if (selectedIds.size === 0) return;
    setBulkSaving(true);
    try {
      const { error } = await supabase.from("documents").delete().in("id", Array.from(selectedIds));
      if (error) throw error;
      toast({ title: `${selectedIds.size} document(s) deleted` });
      setSelectedIds(new Set());
      fetchDocuments();
    } catch (err: any) {
      toast({ title: "Error", description: err.message, variant: "destructive" });
    } finally {
      setBulkSaving(false);
    }
  };

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

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

  const driveFileNames = new Set(drive.sharedFiles.map(sf => sf.drive_file_name));
  const selectedAssociation = useMemo(() => {
    if (!selectedFolder) return null;
    return associations.find(a => selectedFolder === a.name || selectedFolder.startsWith(`${a.name}/`)) || null;
  }, [associations, selectedFolder]);
  const selectedAssociationFolder = selectedAssociation && selectedFolder !== selectedAssociation.name
    ? selectedFolder!.slice(selectedAssociation.name.length + 1)
    : null;

  const childFolders = useMemo(() => {
    const children = new Map<string, { fullPath: string; name: string; count: number }>();

    // Overview (no folder selected): list each association as a folder so users can drill in
    if (!selectedFolder) {
      const counts = new Map<string, number>();
      let unassignedBuildiumCount = 0;
      const globalCounts = new Map<string, number>();
      const assocNameSet = new Set(associations.map(a => a.name));
      documents.forEach(d => {
        const name = d.associations?.name;
        if (name) {
          counts.set(name, (counts.get(name) || 0) + 1);
        } else if (!d.association_id) {
          // Company-level files not attached to any association
          const docFolder = d.category === "general" || !d.category ? "Uncategorized" : d.category;
          const root = docFolder.split("/")[0];
          if (root === "Buildium") {
            unassignedBuildiumCount++;
          } else if (root && !assocNameSet.has(root)) {
            globalCounts.set(root, (globalCounts.get(root) || 0) + 1);
          }
        }
      });
      associations.forEach(a => {
        if (counts.has(a.name) || customFolders.some(f => f === a.name || f.startsWith(`${a.name}/`))) {
          children.set(a.name, { fullPath: a.name, name: a.name, count: counts.get(a.name) || 0 });
        }
      });
      // Always surface a top-level Buildium folder for company-scope files not attached to an association
      children.set("Buildium", { fullPath: "Buildium", name: "Buildium", count: unassignedBuildiumCount });
      // Admin-only: surface other top-level folders that have no association
      if (isAdmin) {
        // include custom top-level folders too
        customFolders.forEach(f => {
          if (f.includes("/")) return;
          if (assocNameSet.has(f) || f === "Buildium") return;
          if (!globalCounts.has(f)) globalCounts.set(f, 0);
        });
        globalCounts.forEach((count, name) => {
          children.set(name, { fullPath: name, name, count });
        });
      }
      return Array.from(children.values()).sort((a, b) => a.name.localeCompare(b.name));
    }

    const addChild = (folderPath: string, fullPathPrefix = "") => {
      const base = selectedAssociationFolder || (!selectedAssociation ? selectedFolder : "");
      if (base && !folderPath.startsWith(`${base}/`)) return;
      const remainder = base ? folderPath.slice(base.length + 1) : folderPath;
      const nextName = remainder.split("/")[0];
      if (!nextName || nextName === folderPath && base === folderPath) return;
      const fullPath = `${fullPathPrefix}${base ? `${base}/` : ""}${nextName}`;
      const key = selectedAssociation ? `${selectedAssociation.name}/${fullPath}` : fullPath;
      const existing = children.get(key);
      children.set(key, { fullPath: key, name: nextName, count: (existing?.count || 0) + 1 });
    };

    documents.forEach(d => {
      const docFolder = d.category === "general" || !d.category ? "Uncategorized" : d.category;
      if (selectedAssociation && d.associations?.name !== selectedAssociation.name) return;
      if (selectedAssociation && !selectedAssociationFolder) addChild(docFolder);
      else if (docFolder.startsWith(`${selectedAssociationFolder || selectedFolder}/`)) addChild(docFolder);
    });

    customFolders.forEach(folder => {
      if (selectedAssociation) {
        if (folder.startsWith(`${selectedAssociation.name}/`)) addChild(folder.slice(selectedAssociation.name.length + 1));
      } else if (folder.startsWith(`${selectedFolder}/`)) {
        addChild(folder);
      }
    });

    // When viewing an association root, surface default category folders even when empty
    if (selectedAssociation && !selectedAssociationFolder) {
      defaultFolders.forEach(f => addChild(f));
    }

    let result = Array.from(children.values()).sort((a, b) => a.name.localeCompare(b.name));
    if (isHomeownerView) {
      result = result.filter(c => !isFolderHidden(c.fullPath));
    }
    return result;
  }, [associations, customFolders, documents, selectedAssociation, selectedAssociationFolder, selectedFolder, isHomeownerView, isFolderHidden, isAdmin]);

  const filterAssociationName = useMemo(() => {
    if (filterAssociationId === "all" || filterAssociationId === "none") return null;
    return associations.find(a => a.id === filterAssociationId)?.name || null;
  }, [filterAssociationId, associations]);

  const filtered = documents.filter((d) => {
    // Hide regular docs when viewing a Drive folder/subfolder
    if (selectedFolder === "Google Drive") return false;
    if (selectedFolder && selectedFolder.includes("/") && driveFileNames.has(selectedFolder.split("/").pop()!)) return false;
    // On overview (no folder selected), only show association folders — hide individual files
    if (!selectedFolder) return false;
    // Hide documents in folders the staff have hidden from homeowners
    if (isHomeownerView) {
      const docFolderRaw = d.category === "general" || !d.category ? "Uncategorized" : d.category;
      const assocNm = d.associations?.name;
      const fullPath = assocNm ? `${assocNm}/${docFolderRaw}` : docFolderRaw;
      if (isFolderHidden(fullPath)) return false;
    }
    const matchSearch = !search || d.title.toLowerCase().includes(search.toLowerCase());
    const docFolder = d.category === "general" || !d.category ? "Uncategorized" : d.category;
    const assocName = d.associations?.name;
    if (filterAssociationId === "none" && d.association_id) return false;
    const matchAssocFilter = !filterAssociationName || assocName === filterAssociationName;
    // Top-level "Buildium" folder = company-scope files not attached to an association
    if (selectedFolder === "Buildium" && !selectedAssociation) {
      return matchSearch && matchAssocFilter && !d.association_id && docFolder === "Buildium";
    }
    const matchFolder = !selectedFolder
      ? true
      : selectedAssociation
        ? !!selectedAssociationFolder && assocName === selectedAssociation.name && docFolder === selectedAssociationFolder
        : selectedFolder === "Uncategorized"
          ? (docFolder === "Uncategorized" || docFolder === "general")
          : docFolder === selectedFolder;
    return matchSearch && matchFolder && matchAssocFilter;
  });

  const filteredDriveFiles = drive.sharedFiles.filter(sf => {
    const sfAssocNames = (sf.association_ids || []).map((aid: string) => assocIdToName[aid]).filter(Boolean);
    if (filterAssociationName && !sfAssocNames.includes(filterAssociationName)) return false;
    if (!selectedFolder) return true;
    const hasAssoc = sfAssocNames.length > 0;

    if (selectedFolder.includes("/")) {
      const parts = selectedFolder.split("/");
      const parentFolder = parts[0];
      const driveName = parts.slice(1).join("/");
      if (parentFolder === "Google Drive" && !hasAssoc && sf.drive_file_name === driveName) return true;
      if (sfAssocNames.includes(parentFolder) && sf.drive_file_name === driveName) return true;
      return false;
    }
    if (selectedFolder === "Google Drive" && !hasAssoc) return true;
    if (sfAssocNames.includes(selectedFolder)) return true;
    return false;
  });

  return (
    <div className="space-y-6" {...(canUpload ? getRootProps() : {})}>
      {canUpload && <input {...getInputProps()} />}

      {/* Drag overlay */}
      {canUpload && isDraggingOver && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-primary/10 backdrop-blur-sm pointer-events-none">
          <div className="flex flex-col items-center gap-3 rounded-2xl border-2 border-dashed border-primary bg-card p-12 shadow-2xl">
            <UploadCloud className="h-14 w-14 text-primary animate-bounce" />
            <p className="text-lg font-semibold text-foreground">Drop files to upload</p>
            <p className="text-sm text-muted-foreground">Files will be added to <span className="font-medium text-foreground">{selectedFolder}</span></p>
          </div>
        </div>
      )}

      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
        <div>
          <h1 className="text-2xl font-bold text-foreground">Documents</h1>
          <p className="text-sm text-muted-foreground mt-1">{canUpload ? "Manage and organize your files — drag & drop files anywhere to upload" : "View and download documents"}</p>
        </div>
        {canUpload && (
          <div className="flex gap-2">
            {!isBoardView && (
              drive.isConnected ? (
                <>
                  <Button variant="outline" className="gap-2" onClick={() => setDrivePickerOpen(true)}>
                    <HardDrive className="h-4 w-4" /> Link from Drive
                  </Button>
                  <Button variant="ghost" size="sm" className="gap-2 text-destructive hover:text-destructive" onClick={drive.disconnect}>
                    Disconnect Drive
                  </Button>
                </>
              ) : !drive.loading && (
                <Button variant="outline" className="gap-2" onClick={drive.connect}>
                  <HardDrive className="h-4 w-4" /> Connect Google Drive
                </Button>
              )
            )}
            <Button variant="outline" className="gap-2" onClick={() => { setParentFolderForNew(null); setNewFolderName(""); setFolderDialogOpen(true); }}>
              <FolderPlus className="h-4 w-4" /> New Folder
            </Button>
            <Button variant="outline" className="gap-2" onClick={() => handleImportFromBuildium("association")} disabled={importingBuildium}>
              {importingBuildium ? <Loader2 className="h-4 w-4 animate-spin" /> : <Download className="h-4 w-4" />}
              Import from Buildium
            </Button>
            {isAdmin && (
              <Button variant="outline" className="gap-2" onClick={() => handleImportFromBuildium("company")} disabled={importingBuildium}>
                {importingBuildium ? <Loader2 className="h-4 w-4 animate-spin" /> : <Download className="h-4 w-4" />}
                Import Company Files
              </Button>
            )}
            <Button className="gap-2" onClick={() => openUploadWithFiles([])}>
              <Plus className="h-4 w-4" /> Upload Documents
            </Button>
          </div>
        )}
      </div>

      <div className="flex gap-6 min-w-0">
        {/* File List */}
        <div className="flex-1 min-w-0">
          <div className="flex items-center justify-between mb-4 gap-3 flex-wrap">
            <div className="flex items-center gap-2 text-sm text-muted-foreground">
              <span className="font-medium text-foreground">{selectedFolder} Documents</span>
              <span>|</span>
              <span>{filtered.length + filteredDriveFiles.length + childFolders.length} items</span>
            </div>
            <div className="flex items-center gap-2">
              {!isReadOnlyView && (
                <Select value={filterAssociationId} onValueChange={setFilterAssociationId}>
                  <SelectTrigger className="w-[220px] h-9">
                    <SelectValue placeholder="Filter by client..." />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">All Clients</SelectItem>
                    {isAdmin && <SelectItem value="none">No Association (Company)</SelectItem>}
                    {associations.map(a => (
                      <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              )}
              <div className="relative w-[250px]">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                <Input placeholder="Search in this folder..." className="pl-10 h-9" value={search} onChange={(e) => setSearch(e.target.value)} />
              </div>
            </div>
          </div>

          {/* Bulk Actions Bar */}
          {canUpload && selectedIds.size > 0 && (
            <div className="flex items-center gap-3 mb-3 p-3 rounded-lg border bg-primary/5 border-primary/20">
              <span className="text-sm font-medium text-foreground">{selectedIds.size} selected</span>
              <div className="flex gap-2 ml-auto">
                <Popover>
                  <PopoverTrigger asChild>
                    <Button size="sm" variant="outline" className="gap-1.5" disabled={bulkSaving}>
                      <Globe className="h-3.5 w-3.5" /> Set Visibility
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-56 p-3" align="start">
                    <p className="text-xs font-semibold text-muted-foreground mb-2 uppercase tracking-wider">Share with</p>
                    {[
                      { value: "board_member", label: "Board Members", icon: Users },
                      { value: "homeowner", label: "Homeowners", icon: Home },
                      { value: "public", label: "Public", icon: Globe },
                    ].map(opt => (
                      <label key={opt.value} className="flex items-center gap-2 py-1.5 cursor-pointer text-sm">
                        <Checkbox
                          checked={bulkVisibility.includes(opt.value)}
                          onCheckedChange={(checked) => {
                            setBulkVisibility(prev =>
                              checked ? [...prev, opt.value] : prev.filter(v => v !== opt.value)
                            );
                          }}
                        />
                        <opt.icon className="h-3.5 w-3.5 text-muted-foreground" />
                        {opt.label}
                      </label>
                    ))}
                    <div className="flex gap-2 mt-3">
                      <Button size="sm" className="flex-1" disabled={bulkSaving} onClick={async () => {
                        setBulkSaving(true);
                        const updateData: any = { visibility: bulkVisibility, is_public: bulkVisibility.includes("public") };
                        const { error } = await supabase.from("documents").update(updateData).in("id", Array.from(selectedIds));
                        if (error) toast({ title: "Error", description: error.message, variant: "destructive" });
                        else { toast({ title: `Visibility updated for ${selectedIds.size} document(s)` }); setSelectedIds(new Set()); fetchDocuments(); }
                        setBulkSaving(false);
                        setBulkVisibility([]);
                      }}>
                        Apply
                      </Button>
                      <Button size="sm" variant="outline" disabled={bulkSaving} onClick={async () => {
                        setBulkSaving(true);
                        const { error } = await supabase.from("documents").update({ visibility: [], is_public: false } as any).in("id", Array.from(selectedIds));
                        if (error) toast({ title: "Error", description: error.message, variant: "destructive" });
                        else { toast({ title: `${selectedIds.size} document(s) set to private` }); setSelectedIds(new Set()); fetchDocuments(); }
                        setBulkSaving(false);
                        setBulkVisibility([]);
                      }}>
                        Clear All
                      </Button>
                    </div>
                  </PopoverContent>
                </Popover>
                {!isBoardView && (
                  <Button size="sm" variant="outline" className="gap-1.5" onClick={() => { setBulkForm({ category: "", association_id: "" }); setBulkDialogOpen(true); }}>
                    <FolderInput className="h-3.5 w-3.5" /> Move / Reassign
                  </Button>
                )}
                {!isBoardView && (
                  <Button size="sm" variant="destructive" className="gap-1.5" onClick={handleBulkDelete} disabled={bulkSaving}>
                    <Trash2 className="h-3.5 w-3.5" /> Delete
                  </Button>
                )}
                <Button size="sm" variant="ghost" onClick={() => setSelectedIds(new Set())}>
                  Clear
                </Button>
              </div>
            </div>
          )}

          <div className="rounded-lg border bg-card overflow-hidden">
            <Table className="table-fixed w-full">
              <TableHeader>
                <TableRow>
                  {canUpload && (
                    <TableHead className="w-[40px]">
                      <Checkbox
                        checked={filtered.length > 0 && selectedIds.size === filtered.length}
                        onCheckedChange={toggleSelectAll}
                      />
                    </TableHead>
                  )}
                  <TableHead className={`text-xs font-bold uppercase ${canUpload ? "w-[35%]" : "w-[40%]"}`}>Name</TableHead>
                  <TableHead className={`text-xs font-bold uppercase ${canUpload ? "w-[25%]" : "w-[25%]"}`}>Association</TableHead>
                  <TableHead className={`text-xs font-bold uppercase ${canUpload ? "w-[20%]" : "w-[20%]"}`}>Date Added</TableHead>
                  <TableHead className={`text-xs font-bold uppercase text-right ${canUpload ? "w-[15%]" : "w-[15%]"}`}>Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {filtered.length === 0 && filteredDriveFiles.length === 0 && childFolders.length === 0 ? (
                  <>
                    {selectedFolder && (
                      <TableRow
                        key="folder-up-empty"
                        className="cursor-pointer hover:bg-muted/50"
                        onClick={() => {
                          const parts = selectedFolder.split("/");
                          parts.pop();
                          setSelectedFolder(parts.join("/") || null);
                        }}
                      >
                        {canUpload && <TableCell className="w-[40px]" />}
                        <TableCell className="overflow-hidden">
                          <div className="flex items-center gap-3 min-w-0 overflow-hidden">
                            <CornerLeftUp className="h-5 w-5 text-muted-foreground shrink-0" />
                            <div className="min-w-0 overflow-hidden">
                              <p className="font-medium text-sm truncate">..</p>
                              <p className="text-xs text-muted-foreground">Go to parent folder</p>
                            </div>
                          </div>
                        </TableCell>
                        <TableCell className="overflow-hidden">
                          <span className="text-sm text-muted-foreground block truncate">{selectedAssociation?.name || "—"}</span>
                        </TableCell>
                        <TableCell><span className="text-sm text-muted-foreground">—</span></TableCell>
                        <TableCell>
                          <div className="flex items-center justify-end">
                            <Button variant="ghost" size="icon" className="h-8 w-8" title="Up to parent folder">
                              <ArrowUp className="h-4 w-4" />
                            </Button>
                          </div>
                        </TableCell>
                      </TableRow>
                    )}
                    <TableRow>
                      <TableCell colSpan={canUpload ? 5 : 4} className="text-center py-12 text-muted-foreground">
                        <div className="flex flex-col items-center gap-2">
                          <FileText className="h-8 w-8 text-muted-foreground/40" />
                          <p>No documents in this folder.</p>
                          {canUpload && <p className="text-xs">Drag &amp; drop files here or click Upload Documents.</p>}
                        </div>
                      </TableCell>
                    </TableRow>
                  </>
                ) : <>
                  {selectedFolder && (
                    <TableRow
                      key="folder-up"
                      className="cursor-pointer hover:bg-muted/50"
                      onClick={() => {
                        const parts = selectedFolder.split("/");
                        parts.pop();
                        setSelectedFolder(parts.join("/") || null);
                      }}
                    >
                      {canUpload && <TableCell className="w-[40px]" />}
                      <TableCell className="overflow-hidden">
                        <div className="flex items-center gap-3 min-w-0 overflow-hidden">
                          <CornerLeftUp className="h-5 w-5 text-muted-foreground shrink-0" />
                          <div className="min-w-0 overflow-hidden">
                            <p className="font-medium text-sm truncate">..</p>
                            <p className="text-xs text-muted-foreground">Go to parent folder</p>
                          </div>
                        </div>
                      </TableCell>
                      <TableCell className="overflow-hidden">
                        <span className="text-sm text-muted-foreground block truncate">{selectedAssociation?.name || "—"}</span>
                      </TableCell>
                      <TableCell><span className="text-sm text-muted-foreground">—</span></TableCell>
                      <TableCell>
                        <div className="flex items-center justify-end">
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-8 w-8"
                            title="Up to parent folder"
                            onClick={(e) => {
                              e.stopPropagation();
                              const parts = selectedFolder.split("/");
                              parts.pop();
                              setSelectedFolder(parts.join("/") || null);
                            }}
                          >
                            <ArrowUp className="h-4 w-4" />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  )}
                  {childFolders.map(folder => {
                    const isAssocFolder = associations.some(a => folder.fullPath === a.name);
                    const isGlobal = !selectedFolder && !isAssocFolder && folder.fullPath !== "Buildium";
                    return (
                    <TableRow key={`folder-${folder.fullPath}`} className="cursor-pointer hover:bg-muted/50" onClick={() => setSelectedFolder(folder.fullPath)}>
                      {canUpload && <TableCell className="w-[40px]" />}
                      <TableCell className="overflow-hidden">
                        <div className="flex items-center gap-3 min-w-0 overflow-hidden">
                          <Folder className={`h-5 w-5 shrink-0 ${isGlobal ? "text-amber-500" : "text-primary"}`} />
                          <div className="min-w-0 overflow-hidden">
                            <div className="flex items-center gap-1.5">
                              <p className="font-medium text-sm truncate">{folder.name}</p>
                              {isGlobal && (
                                <Badge variant="outline" className="text-[10px] px-1.5 py-0 gap-0.5 border-amber-400 text-amber-600">
                                  <Shield className="h-2.5 w-2.5" /> Global · Admin
                                </Badge>
                              )}
                            </div>
                            <p className="text-xs text-muted-foreground">{folder.count} {folder.count === 1 ? "item" : "items"}</p>
                          </div>
                        </div>
                      </TableCell>
                      <TableCell className="overflow-hidden">
                        <span className="text-sm text-muted-foreground block truncate">
                          {isGlobal ? "No association" : (selectedAssociation?.name || "—")}
                        </span>
                      </TableCell>
                      <TableCell><span className="text-sm text-muted-foreground">—</span></TableCell>
                      <TableCell>
                        <div className="flex items-center justify-end gap-1">
                          {canUpload && (
                            <>
                              {resolveFolderRule(folder.fullPath) && (
                                <Button
                                  variant="ghost"
                                  size="icon"
                                  className={`h-8 w-8 ${isFolderHidden(folder.fullPath) ? "text-amber-600 hover:text-amber-700" : ""}`}
                                  title={isFolderHidden(folder.fullPath) ? "Hidden from homeowners — click to show" : "Visible to homeowners — click to hide"}
                                  onClick={(e) => { e.stopPropagation(); toggleFolderHidden(folder.fullPath); }}
                                >
                                  {isFolderHidden(folder.fullPath) ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
                                </Button>
                              )}
                              <Button variant="ghost" size="icon" className="h-8 w-8" title="Share folder"
                                onClick={(e) => { e.stopPropagation(); setShareTarget({ type: "folder", name: folder.fullPath }); setShareOpen(true); }}>
                                <Share2 className="h-4 w-4" />
                              </Button>
                              <Button variant="ghost" size="icon" className="h-8 w-8" title="Rename folder"
                                onClick={(e) => { e.stopPropagation(); handleRenameFolder(folder.fullPath); }}>
                                <Pencil className="h-4 w-4" />
                              </Button>
                              {!isBoardView && (
                                <Button variant="ghost" size="icon" className="h-8 w-8 text-destructive hover:text-destructive" title="Delete folder (must be empty)"
                                  onClick={(e) => { e.stopPropagation(); handleDeleteFolder(folder.fullPath); }}>
                                  <Trash2 className="h-4 w-4" />
                                </Button>
                              )}
                            </>
                          )}
                          <Button variant="ghost" size="icon" className="h-8 w-8" onClick={(e) => { e.stopPropagation(); setSelectedFolder(folder.fullPath); }}>
                            <ChevronRight className="h-4 w-4" />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  );})}
                  {filtered.map((d) => (
                  <TableRow key={d.id} className={selectedIds.has(d.id) ? "bg-primary/5" : ""}>
                    {canUpload && (
                      <TableCell className="w-[40px]">
                        <Checkbox
                          checked={selectedIds.has(d.id)}
                          onCheckedChange={() => toggleSelect(d.id)}
                        />
                      </TableCell>
                    )}
                    <TableCell className="overflow-hidden">
                      <div className="flex items-center gap-3 min-w-0 overflow-hidden">
                        <File className="h-5 w-5 text-destructive shrink-0" />
                        <div className="min-w-0 overflow-hidden">
                          <div className="flex items-center gap-1.5">
                            <p className="font-medium text-sm truncate">{d.title}</p>
                            {((d as any).visibility?.length > 0 || (d as any).is_public) && (
                              <div className="flex items-center gap-1 shrink-0">
                                {((d as any).visibility || []).includes("board_member") && (
                                  <Badge variant="secondary" className="text-[10px] px-1.5 py-0 gap-0.5"><Users className="h-2.5 w-2.5" /> Board</Badge>
                                )}
                                {((d as any).visibility || []).includes("homeowner") && (
                                  <Badge variant="secondary" className="text-[10px] px-1.5 py-0 gap-0.5"><Home className="h-2.5 w-2.5" /> Homeowner</Badge>
                                )}
                                {((d as any).visibility || []).includes("public") && (
                                  <Badge variant="secondary" className="text-[10px] px-1.5 py-0 gap-0.5"><Globe className="h-2.5 w-2.5" /> Public</Badge>
                                )}
                              </div>
                            )}
                          </div>
                          {d.file_name && <p className="text-xs text-muted-foreground truncate">{d.file_name}</p>}
                          {(d as any).ai_summary && (
                            <p className="text-xs text-muted-foreground mt-0.5 line-clamp-2 italic">
                              <Sparkles className="h-3 w-3 inline mr-1 text-primary" />
                              {(d as any).ai_summary}
                            </p>
                          )}
                          {isSummarizing(d.id) && (
                            <p className="text-xs text-muted-foreground mt-0.5 flex items-center gap-1">
                              <Loader2 className="h-3 w-3 animate-spin" /> Generating AI summary…
                            </p>
                          )}
                        </div>
                      </div>
                    </TableCell>
                    <TableCell className="overflow-hidden">
                      <span className="text-sm text-muted-foreground block truncate">{d.associations?.name || "—"}</span>
                    </TableCell>
                    <TableCell>
                      <div className="text-sm">{format(new Date(d.created_at), "MMM d, yyyy")}</div>
                      <div className="text-xs text-muted-foreground">{format(new Date(d.created_at), "h:mm a")}</div>
                    </TableCell>
                    <TableCell>
                      <div className="flex items-center justify-end gap-1">
                        {canUpload && (
                          <Popover>
                            <PopoverTrigger asChild>
                              <Button variant="ghost" size="icon" className="h-8 w-8" title="Set visibility">
                                <Globe className="h-4 w-4" />
                              </Button>
                            </PopoverTrigger>
                            <PopoverContent className="w-48 p-2" align="end">
                              {[
                                { value: "board_member", label: "Board Members", icon: Users },
                                { value: "homeowner", label: "Homeowners", icon: Home },
                                { value: "public", label: "Public", icon: Globe },
                              ].map(opt => {
                                const currentVis: string[] = (d as any).visibility || [];
                                const isChecked = currentVis.includes(opt.value);
                                return (
                                  <label key={opt.value} className="flex items-center gap-2 py-1 cursor-pointer text-sm">
                                    <Checkbox
                                      checked={isChecked}
                                      onCheckedChange={async (checked) => {
                                        const newVis = checked
                                          ? [...currentVis, opt.value]
                                          : currentVis.filter(v => v !== opt.value);
                                        const { error } = await supabase.from("documents").update({ visibility: newVis, is_public: newVis.includes("public") } as any).eq("id", d.id);
                                        if (error) toast({ title: "Error", description: error.message, variant: "destructive" });
                                        else fetchDocuments();
                                      }}
                                    />
                                    <opt.icon className="h-3.5 w-3.5 text-muted-foreground" />
                                    {opt.label}
                                  </label>
                                );
                              })}
                            </PopoverContent>
                          </Popover>
                        )}
                        {d.file_url && (
                          <Button variant="ghost" size="icon" className="h-8 w-8" title="View" onClick={() => window.open(d.file_url, "_blank", "noopener,noreferrer")}><Eye className="h-4 w-4" /></Button>
                        )}
                        {d.file_url && (
                          <Button variant="ghost" size="icon" className="h-8 w-8" title="Download" onClick={() => handleDownload(d)}><Download className="h-4 w-4" /></Button>
                        )}
                        {canUpload && (
                          <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                              <Button variant="ghost" size="icon" className="h-8 w-8"><MoreHorizontal className="h-4 w-4" /></Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent align="end">
                              <DropdownMenuItem onClick={() => openEditDialog(d)}>
                                <Pencil className="h-4 w-4 mr-2" /> Edit / Move
                              </DropdownMenuItem>
                              <DropdownMenuItem onClick={() => { setShareTarget({ type: "document", name: d.title, docId: d.id }); setShareOpen(true); }}>
                                <Share2 className="h-4 w-4 mr-2" /> Share with Code
                              </DropdownMenuItem>
                              {(d as any).is_public && d.file_url && (
                                <DropdownMenuItem onClick={() => {
                                  let safeUrl = d.file_url;
                                  try { safeUrl = encodeURI(decodeURI(d.file_url)); } catch {}
                                  navigator.clipboard.writeText(safeUrl);
                                  toast({ title: "Link copied", description: "Public document link copied to clipboard." });
                                }}>
                                  <Link className="h-4 w-4 mr-2" /> Copy Public Link
                                </DropdownMenuItem>
                              )}
                              {d.file_url && !(d as any).ai_summary && !isSummarizing(d.id) && (
                                <DropdownMenuItem onClick={async () => {
                                  const summary = await generateSummary(d.id, d.file_url, d.title);
                                  if (summary) { fetchDocuments(); toast({ title: "AI Summary Generated" }); }
                                  else toast({ title: "Summary failed", variant: "destructive" });
                                }}>
                                  <Sparkles className="h-4 w-4 mr-2" /> Generate AI Summary
                                </DropdownMenuItem>
                              )}
                              {!isBoardView && (
                                <>
                                  <DropdownMenuSeparator />
                                  <DropdownMenuItem className="text-destructive" onClick={() => handleDelete(d.id)}>
                                    <Trash2 className="h-4 w-4 mr-2" /> Delete
                                  </DropdownMenuItem>
                                </>
                              )}
                            </DropdownMenuContent>
                          </DropdownMenu>
                        )}
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
                </>
                }
                {/* Shared Google Drive files */}
                {filteredDriveFiles.map(sf => (
                  <TableRow key={`drive-${sf.id}`}>
                    {canUpload && <TableCell className="w-[40px]" />}
                    <TableCell className="overflow-hidden">
                      <div className="flex items-center gap-3 min-w-0 overflow-hidden">
                        {sf.drive_icon_link ? (
                          <img src={sf.drive_icon_link} alt="" className="h-5 w-5 shrink-0" />
                        ) : sf.is_folder ? (
                          <Folder className="h-5 w-5 text-primary shrink-0" />
                        ) : (
                          <HardDrive className="h-5 w-5 text-blue-500 shrink-0" />
                        )}
                         <div className="min-w-0 overflow-hidden">
                          <p className="font-medium text-sm truncate">{sf.drive_file_name}</p>
                          <div className="flex items-center gap-1.5">
                            <Badge variant="outline" className="text-[10px] px-1.5 py-0">
                              <HardDrive className="h-2.5 w-2.5 mr-1" />Google Drive
                            </Badge>
                            {sf.visibility.includes("board_member") && <Badge variant="secondary" className="text-[10px] px-1.5 py-0">Board</Badge>}
                            {sf.visibility.includes("homeowner") && <Badge variant="secondary" className="text-[10px] px-1.5 py-0">Homeowner</Badge>}
                          </div>
                        </div>
                      </div>
                    </TableCell>
                    <TableCell className="overflow-hidden">
                      <span className="text-sm text-muted-foreground block truncate">
                        {(sf.association_ids || []).map((aid: string) => assocIdToName[aid]).filter(Boolean).join(", ") || "—"}
                      </span>
                    </TableCell>
                    <TableCell>
                      <div className="text-sm">{format(new Date(sf.created_at), "MMM d, yyyy")}</div>
                    </TableCell>
                    <TableCell>
                      <div className="flex justify-end gap-1">
                        <Button variant="ghost" size="icon" className="h-8 w-8" onClick={() => drive.downloadFile(sf.drive_file_id, sf.drive_file_name)}>
                          <Download className="h-4 w-4" />
                        </Button>
                        {sf.drive_web_view_link && (
                          <Button variant="ghost" size="icon" className="h-8 w-8" asChild>
                            <a href={sf.drive_web_view_link} target="_blank" rel="noopener noreferrer">
                              <ExternalLink className="h-4 w-4" />
                            </a>
                          </Button>
                        )}
                        {canUpload && (
                          <Button variant="ghost" size="icon" className="h-8 w-8 text-destructive" onClick={() => drive.unshareFile(sf.id)}>
                            <Unlink className="h-4 w-4" />
                          </Button>
                        )}
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </div>
      </div>

      {/* Upload Dialog */}
      <Dialog open={dialogOpen} onOpenChange={(open) => { setDialogOpen(open); if (!open) { setPendingFiles([]); setSelectedAssociationId(""); setUploadVisibility([]); } }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{pendingFiles.length > 0 ? "Upload Files" : "Upload Document"}</DialogTitle>
            <DialogDescription>
              {pendingFiles.length > 0
                ? `${pendingFiles.length} file${pendingFiles.length > 1 ? "s" : ""} ready to upload to ${selectedFolder}.`
                : `Add a new document to ${selectedFolder}.`}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label>Association <span className="text-destructive">*</span></Label>
              <Select value={selectedAssociationId} onValueChange={setSelectedAssociationId}>
                <SelectTrigger><SelectValue placeholder="Select an association..." /></SelectTrigger>
                <SelectContent>
                  {isAdmin && <SelectItem value="__none__">No Association (Global / Admin)</SelectItem>}
                  {associations.map(a => (
                    <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div>
              <Label>Share with</Label>
              <p className="text-xs text-muted-foreground mb-2">Choose who can view these files. Staff always have access.</p>
              <div className="space-y-2">
                {[
                  { value: "board_member", label: "Board Members", icon: Users },
                  { value: "homeowner", label: "Homeowners", icon: Home },
                  { value: "public", label: "Public (anyone with link)", icon: Globe },
                ].map(opt => {
                  const Icon = opt.icon;
                  return (
                    <label key={opt.value} className="flex items-center gap-2 text-sm cursor-pointer">
                      <Checkbox
                        checked={uploadVisibility.includes(opt.value)}
                        onCheckedChange={(checked) => {
                          setUploadVisibility(prev =>
                            checked ? [...prev, opt.value] : prev.filter(v => v !== opt.value)
                          );
                        }}
                      />
                      <Icon className="h-3.5 w-3.5 text-muted-foreground" />
                      <span>{opt.label}</span>
                    </label>
                  );
                })}
              </div>
            </div>

            {pendingFiles.length > 0 ? (
              <div>
                <Label>Files</Label>
                <div className="space-y-1 mt-1 max-h-[200px] overflow-y-auto rounded-md border p-2">
                  {pendingFiles.map((f, i) => (
                    <div key={i} className="flex items-center justify-between text-sm py-1 px-2 rounded hover:bg-muted">
                      <div className="flex items-center gap-2 min-w-0">
                        <File className="h-4 w-4 text-muted-foreground shrink-0" />
                        <span className="truncate">{f.name}</span>
                      </div>
                      <span className="text-xs text-muted-foreground shrink-0 ml-2">{(f.size / 1024).toFixed(0)} KB</span>
                    </div>
                  ))}
                </div>
                <label className="mt-2 inline-flex items-center gap-2 text-sm text-primary cursor-pointer hover:underline">
                  <Plus className="h-3.5 w-3.5" /> Add more files
                  <input
                    type="file"
                    multiple
                    className="hidden"
                    onChange={(e) => {
                      const files = Array.from(e.target.files || []);
                      if (files.length) setPendingFiles(prev => [...prev, ...files]);
                    }}
                  />
                </label>
                {drive.isConnected && (
                  <div className="mt-3 rounded-md border border-border p-3 space-y-2">
                    <div className="flex items-center justify-between gap-3">
                      <div className="min-w-0">
                        <Label className="text-xs font-medium flex items-center gap-2">
                          <HardDrive className="h-4 w-4 text-primary" /> Save to Google Drive
                        </Label>
                        <p className="text-xs text-muted-foreground truncate">{driveUploadFolder?.name || "Choose a Drive folder for these files."}</p>
                      </div>
                      <Button type="button" variant="outline" size="sm" onClick={() => setDriveFolderPickerOpen(true)} disabled={uploading}>Choose</Button>
                    </div>
                    {driveUploadFolder && (
                      <Button type="button" variant="ghost" size="sm" className="h-7 px-2" onClick={() => setDriveUploadFolder(null)}>Remove Google Drive save</Button>
                    )}
                  </div>
                )}
              </div>
            ) : (
              <>
                <div>
                  <Label>Select Files</Label>
                  <label className="mt-1 flex flex-col items-center gap-2 rounded-lg border-2 border-dashed border-muted-foreground/25 p-6 cursor-pointer hover:border-primary/50 hover:bg-muted/30 transition-colors">
                    <UploadCloud className="h-8 w-8 text-muted-foreground/40" />
                    <span className="text-sm text-muted-foreground">Click to browse files</span>
                    <input
                      type="file"
                      multiple
                      className="hidden"
                      onChange={(e) => {
                        const files = Array.from(e.target.files || []);
                        if (files.length) setPendingFiles(files);
                      }}
                    />
                  </label>
                </div>
                {drive.isConnected && pendingFiles.length > 0 && (
                  <div className="rounded-md border border-border p-3 space-y-2">
                    <div className="flex items-center justify-between gap-3">
                      <div className="min-w-0">
                        <Label className="text-xs font-medium flex items-center gap-2">
                          <HardDrive className="h-4 w-4 text-primary" /> Save to Google Drive
                        </Label>
                        <p className="text-xs text-muted-foreground truncate">{driveUploadFolder?.name || "Choose a Drive folder for these files."}</p>
                      </div>
                      <Button type="button" variant="outline" size="sm" onClick={() => setDriveFolderPickerOpen(true)} disabled={uploading}>Choose</Button>
                    </div>
                    {driveUploadFolder && (
                      <Button type="button" variant="ghost" size="sm" className="h-7 px-2" onClick={() => setDriveUploadFolder(null)}>Remove Google Drive save</Button>
                    )}
                  </div>
                )}
                <div><Label>Or enter manually</Label></div>
                <div><Label>Title</Label><Input value={form.title} onChange={(e) => setForm({ ...form, title: e.target.value })} /></div>
                <div><Label>File Name</Label><Input value={form.file_name} onChange={(e) => setForm({ ...form, file_name: e.target.value })} placeholder="document.pdf" /></div>
              </>
            )}
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => { setDialogOpen(false); setPendingFiles([]); }}>Cancel</Button>
            {pendingFiles.length > 0 ? (
              <Button onClick={handleUploadFiles} disabled={uploading || !selectedAssociationId}>
                {uploading ? "Uploading..." : `Upload ${pendingFiles.length} File${pendingFiles.length > 1 ? "s" : ""}`}
              </Button>
            ) : (
              <Button onClick={handleCreate} disabled={!selectedAssociationId}>Upload</Button>
            )}
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* New Folder Dialog */}
      <Dialog open={folderDialogOpen} onOpenChange={setFolderDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create New Folder</DialogTitle>
            <DialogDescription>Create a new folder or subfolder to organize your documents.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label>Parent Folder (optional)</Label>
              <Select value={parentFolderForNew || "__none__"} onValueChange={(val) => setParentFolderForNew(val === "__none__" ? null : val)}>
                <SelectTrigger className="mt-1.5"><SelectValue placeholder="None (top-level folder)" /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="__none__">None (top-level folder)</SelectItem>
                  {populatedFolders.map(folder => (
                    <SelectItem key={folder} value={folder}>{folder}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Folder Name</Label>
              <Input
                className="mt-1.5"
                value={newFolderName}
                onChange={(e) => setNewFolderName(e.target.value)}
                placeholder="e.g., Board Reports"
                onKeyDown={(e) => { if (e.key === "Enter") handleCreateFolder(); }}
                autoFocus
              />
              {parentFolderForNew && newFolderName.trim() && (
                <p className="text-xs text-muted-foreground mt-1">Will create: <span className="font-medium">{parentFolderForNew}/{newFolderName.trim()}</span></p>
              )}
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setFolderDialogOpen(false)}>Cancel</Button>
            <Button onClick={handleCreateFolder} disabled={!newFolderName.trim()}>Create</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Edit / Move Document Dialog */}
      <Dialog open={editDialogOpen} onOpenChange={(open) => { setEditDialogOpen(open); if (!open) setEditDoc(null); }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Edit Document</DialogTitle>
            <DialogDescription>Update the document details or move it to a different folder.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label>Title</Label>
              <Input value={editForm.title} onChange={(e) => setEditForm({ ...editForm, title: e.target.value })} />
            </div>
            <div>
              <Label>File Name</Label>
              <Input value={editForm.file_name} onChange={(e) => setEditForm({ ...editForm, file_name: e.target.value })} placeholder="document.pdf" />
            </div>
            <div>
              <Label>Association</Label>
              <Select value={editForm.association_id} onValueChange={(val) => setEditForm({ ...editForm, association_id: val })}>
                <SelectTrigger><SelectValue placeholder="Select association..." /></SelectTrigger>
                <SelectContent>
                  {associations.map(a => (
                    <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Folder</Label>
              <Select value={editForm.category} onValueChange={(val) => setEditForm({ ...editForm, category: val })}>
                <SelectTrigger><SelectValue placeholder="Select folder" /></SelectTrigger>
                <SelectContent className="max-h-[320px]">
                  {[...new Set([
                    ...defaultFolders,
                    ...customFolders,
                    ...populatedFolders,
                    ...(editForm.category && !defaultFolders.includes(editForm.category) && !customFolders.includes(editForm.category) ? [editForm.category] : []),
                  ])]
                    .filter(folder => folder && folder !== "Google Drive" && !folder.startsWith("Google Drive/"))
                    .sort((a, b) => a.localeCompare(b))
                    .map(folder => (
                      <SelectItem key={folder} value={folder}>{folder}</SelectItem>
                    ))}
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setEditDialogOpen(false)}>Cancel</Button>
            <Button onClick={handleEditSave} disabled={!editForm.title}>Save Changes</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Bulk Update Dialog */}
      <Dialog open={bulkDialogOpen} onOpenChange={setBulkDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Bulk Update {selectedIds.size} Document(s)</DialogTitle>
            <DialogDescription>Choose a new folder and/or association. Leave blank to keep unchanged.</DialogDescription>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label>Move to Folder</Label>
              <Select value={bulkForm.category} onValueChange={(val) => setBulkForm({ ...bulkForm, category: val })}>
                <SelectTrigger><SelectValue placeholder="— Keep current folder —" /></SelectTrigger>
                <SelectContent className="max-h-[320px]">
                  {[...new Set([...defaultFolders, ...customFolders, ...populatedFolders])]
                    .filter(folder => folder && folder !== "Google Drive" && !folder.startsWith("Google Drive/"))
                    .sort((a, b) => a.localeCompare(b))
                    .map(folder => (
                      <SelectItem key={folder} value={folder}>{folder}</SelectItem>
                    ))}
                </SelectContent>
              </Select>
            </div>
            <div>
              <Label>Reassign Association</Label>
              <Select value={bulkForm.association_id} onValueChange={(val) => setBulkForm({ ...bulkForm, association_id: val })}>
                <SelectTrigger><SelectValue placeholder="— Keep current association —" /></SelectTrigger>
                <SelectContent>
                  {associations.map(a => (
                    <SelectItem key={a.id} value={a.id}>{a.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setBulkDialogOpen(false)}>Cancel</Button>
            <Button onClick={handleBulkUpdate} disabled={bulkSaving}>
              {bulkSaving ? <><Loader2 className="h-4 w-4 animate-spin mr-2" /> Updating...</> : "Update Documents"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Share Dialog */}
      <ShareDialog
        open={shareOpen}
        onOpenChange={setShareOpen}
        shareType={shareTarget.type}
        folderName={shareTarget.type === "folder" ? shareTarget.name : undefined}
        documentId={shareTarget.type === "document" ? shareTarget.docId : undefined}
        itemName={shareTarget.name}
      />

      {/* Google Drive Picker */}
      <GoogleDrivePickerDialog
        open={drivePickerOpen}
        onOpenChange={setDrivePickerOpen}
        driveFiles={drive.driveFiles}
        browsing={drive.browsing}
        browseFiles={drive.browseFiles}
        listSharedDrives={drive.listSharedDrives}
        onShare={drive.shareFiles}
        associations={associations}
      />

      <GoogleDriveFolderPickerDialog
        open={driveFolderPickerOpen}
        onOpenChange={setDriveFolderPickerOpen}
        driveFiles={drive.driveFiles}
        browsing={drive.browsing}
        browseFiles={drive.browseFiles}
        listSharedDrives={drive.listSharedDrives}
        onSelect={setDriveUploadFolder}
      />
    </div>
  );
}
