// Media Library — Firebase Storage + Firestore-backed asset manager

const { useState, useEffect, useMemo, useRef } = React;

const STORAGE_LIMIT_BYTES = 50 * 1024 * 1024 * 1024;
const OVERSIZE_THRESHOLD_BYTES = 500 * 1024;
const MAX_UPLOAD_BYTES = 5 * 1024 * 1024;
const RECENT_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
const ACCEPTED_EXTENSIONS = ["png", "jpg", "jpeg", "gif", "svg", "webp"];

const normalizeExtension = (value = "") => {
  const ext = String(value).toLowerCase().replace(/^\./, "").replace("svg+xml", "svg");
  return ext === "jpeg" ? "jpg" : ext;
};

const getFileExtension = (name = "") => {
  const parts = String(name).split(".");
  return parts.length > 1 ? normalizeExtension(parts.pop()) : "";
};

const formatBytes = (bytes) => {
  if (!bytes) return "0 B";
  const units = ["B", "KB", "MB", "GB", "TB"];
  let value = bytes;
  let unitIndex = 0;
  while (value >= 1024 && unitIndex < units.length - 1) {
    value /= 1024;
    unitIndex += 1;
  }
  const decimals = value >= 100 || unitIndex === 0 ? 0 : value >= 10 ? 1 : 2;
  return `${value.toFixed(decimals)} ${units[unitIndex]}`;
};

const formatDate = (ts) => {
  if (!ts) return "Pending";
  const d = ts.toDate ? ts.toDate() : new Date(ts);
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
};

const timeAgo = (ts) => {
  if (!ts) return "Pending";
  const now = Date.now();
  const t = ts.toDate ? ts.toDate().getTime() : new Date(ts).getTime();
  const diff = now - t;
  const mins = Math.floor(diff / 60000);
  if (mins < 1) return "Just now";
  if (mins < 60) return `${mins} min ago`;
  const hours = Math.floor(mins / 60);
  if (hours < 24) return `${hours} h ago`;
  const days = Math.floor(hours / 24);
  if (days === 1) return "Yesterday";
  if (days < 7) return `${days} days ago`;
  if (days < 30) return `${Math.floor(days / 7)} weeks ago`;
  return formatDate(ts);
};

const isRecentAsset = (asset) => {
  const createdAt = asset?.createdAt?.toDate ? asset.createdAt.toDate().getTime() : asset?.createdAt ? new Date(asset.createdAt).getTime() : 0;
  return createdAt > 0 && Date.now() - createdAt <= RECENT_WINDOW_MS;
};

const matchesDateFilter = (asset, filter) => {
  if (filter === "all") return true;
  const createdAt = asset?.createdAt?.toDate ? asset.createdAt.toDate().getTime() : asset?.createdAt ? new Date(asset.createdAt).getTime() : 0;
  if (!createdAt) return false;
  const age = Date.now() - createdAt;
  if (filter === "today") return age <= 24 * 60 * 60 * 1000;
  if (filter === "week") return age <= 7 * 24 * 60 * 60 * 1000;
  if (filter === "month") return age <= 30 * 24 * 60 * 60 * 1000;
  return true;
};

const parseTagInput = (raw) => {
  const seen = new Set();
  return raw
    .split(",")
    .map(tag => tag.trim().toLowerCase())
    .filter(Boolean)
    .filter(tag => {
      if (seen.has(tag)) return false;
      seen.add(tag);
      return true;
    });
};

const sanitizeFileName = (name = "asset") =>
  name.replace(/[^\w.\-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");

const readImageDimensions = (file) => new Promise((resolve) => {
  const src = URL.createObjectURL(file);
  const img = new Image();
  img.onload = () => {
    resolve({ width: img.naturalWidth || 0, height: img.naturalHeight || 0 });
    URL.revokeObjectURL(src);
  };
  img.onerror = () => {
    resolve({ width: 0, height: 0 });
    URL.revokeObjectURL(src);
  };
  img.src = src;
});

const MediaFilterDropdown = ({ options, value, onChange, onClose, label }) => {
  const ref = useRef(null);

  useEffect(() => {
    const handler = (e) => {
      if (ref.current && !ref.current.contains(e.target)) onClose();
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, [onClose]);

  return (
    <div className="filter-drop" ref={ref}>
      <div className="filter-drop-label">{label}</div>
      {options.map(o => (
        <button key={o.id} className={`filter-drop-item${value === o.id ? " is-active" : ""}`}
          onClick={() => { onChange(o.id); onClose(); }}>
          <span>{o.label}</span>
          <span className="filter-drop-count">{o.count ?? ""}</span>
          {value === o.id && <Icon name="check" size={12} className="filter-drop-check" />}
        </button>
      ))}
    </div>
  );
};

const UploadRow = ({ upload }) => (
  <div className={`media-upload-row${upload.error ? " is-error" : upload.status === "complete" ? " is-complete" : ""}`}>
    <div className="media-upload-copy">
      <div className="media-upload-name" title={upload.name}>{upload.name}</div>
      <div className="media-upload-status">
        {upload.error || (upload.status === "complete" ? "Uploaded" : `${upload.progress}%`)}
      </div>
    </div>
    <div className="media-upload-track">
      <div className="media-upload-fill" style={{ width: `${upload.status === "complete" ? 100 : upload.progress}%` }} />
    </div>
  </div>
);

const AssetCard = ({ asset, selected, onClick }) => {
  const ext = normalizeExtension(asset.ext || getFileExtension(asset.name)).toUpperCase() || "FILE";
  const dimensions = asset.width && asset.height ? `${asset.width} × ${asset.height}` : "Dimensions pending";
  const sizeLabel = formatBytes(asset.sizeBytes);

  return (
    <div className={`asset-card${selected ? " is-selected" : ""}`} onClick={onClick}>
      <div className="asset-thumb">
        {ext === "SVG" && <div className="checker" />}
        {asset.downloadURL ? (
          <img src={asset.downloadURL} alt={asset.name} loading="lazy" />
        ) : (
          <div className="asset-thumb-placeholder">
            <Icon name="image" size={24} />
            <span>No preview</span>
          </div>
        )}
        <div className="asset-badges">
          <span className="asset-type-pill">{ext}</span>
          <span className={`asset-size${asset.sizeBytes > OVERSIZE_THRESHOLD_BYTES ? " is-warn" : ""}`}>{sizeLabel}</span>
        </div>
      </div>
      <div className="asset-meta">
        <div className="asset-name" title={asset.name}>{asset.name}</div>
        <div className="asset-dims">
          <span>{dimensions}</span>
          <span className="sep" />
          <span>used {asset.uses || 0}×</span>
        </div>
      </div>
    </div>
  );
};

const AssetGroupSection = ({ title, count, subtitle, assets, selectedAssetId, onSelectAsset }) => (
  <section className="media-group">
    <div className="media-group-head">
      <div>
        <div className="media-group-title">{title}</div>
        {subtitle && <div className="media-group-sub">{subtitle}</div>}
      </div>
      <div className="media-group-count">{count} {count === 1 ? "file" : "files"}</div>
    </div>
    <div className="media-grid">
      {assets.map(asset => (
        <AssetCard
          key={asset.id}
          asset={asset}
          selected={selectedAssetId === asset.id}
          onClick={() => onSelectAsset(asset.id)}
        />
      ))}
    </div>
  </section>
);

const FolderActionsMenu = ({ folder, onRename, onDelete, onClose, align = "right" }) => {
  const menuRef = useRef(null);
  const [confirmDelete, setConfirmDelete] = useState(false);

  useEffect(() => {
    const handler = (e) => {
      if (menuRef.current && !menuRef.current.contains(e.target)) onClose();
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, [onClose]);

  return (
    <div className={`member-menu media-folder-menu media-folder-menu--${align}`} ref={menuRef} onClick={e => e.stopPropagation()}>
      {confirmDelete ? (
        <>
          <div className="mm-confirm-text">Delete {folder.name}?</div>
          <div className="mm-confirm-actions">
            <button className="mm-btn mm-btn--cancel" onClick={() => setConfirmDelete(false)}>Cancel</button>
            <button className="mm-btn mm-btn--danger" onClick={() => onDelete(folder)}>Delete</button>
          </div>
        </>
      ) : (
        <>
          <button className="mm-item" onClick={() => onRename(folder)}>
            <Icon name="type" size={14} />
            <span>Rename folder</span>
          </button>
          <div className="mm-sep" />
          <button className="mm-item mm-item--danger" onClick={() => setConfirmDelete(true)}>
            <Icon name="trash" size={14} />
            <span>Delete folder</span>
          </button>
        </>
      )}
    </div>
  );
};

const CreateFolderModal = ({ open, onClose, onSubmit, assetCount, loading, destinationLabel, isSubfolder, defaultParentId, folderOptions }) => {
  const [name, setName] = useState("");
  const [parentId, setParentId] = useState("");
  const [error, setError] = useState("");
  const inputRef = useRef(null);

  useEffect(() => {
    if (!open) return undefined;
    setName("");
    setParentId(defaultParentId || "");
    setError("");
    const focusTimer = setTimeout(() => inputRef.current?.focus(), 80);
    return () => {
      clearTimeout(focusTimer);
    };
  }, [open, defaultParentId]);

  const submitFolder = () => {
    const nextName = name.trim();
    if (!nextName) {
      setError("Give this folder a name.");
      return;
    }
    onSubmit(nextName, parentId || null).catch((err) => {
      setError(err?.message || "Unable to create the folder.");
    });
  };

  useEffect(() => {
    if (!open) return undefined;
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "Enter") {
        e.preventDefault();
        submitFolder();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => {
      window.removeEventListener("keydown", onKey);
    };
  }, [open, onClose, onSubmit, name]);

  if (!open) return null;

  return (
    <div className="media-folder-overlay" onClick={onClose}>
      <div className="media-folder-modal" onClick={(e) => e.stopPropagation()}>
        <div className="media-folder-head">
          <div className="media-folder-mark">
            <Icon name="layers" size={18} />
          </div>
          <div className="media-folder-title-stack">
            <div className="media-folder-title">Create a media folder</div>
            <div className="media-folder-sub">Group assets for campaigns, brand kits, launches, or handoff batches.</div>
          </div>
          <button className="media-folder-close" onClick={onClose}>
            <Icon name="x" size={14} />
          </button>
        </div>

        <div className="media-folder-body">
          <div className="media-folder-preview">
            <div className="media-folder-preview-badge">{assetCount} {assetCount === 1 ? "asset" : "assets"}</div>
            <div className="media-folder-preview-copy">
              {isSubfolder
                ? `This subfolder will be created inside ${destinationLabel}.`
                : "New folders immediately show up in `All assets` and in the sidebar."}
            </div>
          </div>

          <label className="media-folder-label">Place inside</label>
          <div className="media-folder-input-wrap media-folder-select-wrap">
            <Icon name="layers" size={14} />
            <select value={parentId} onChange={(e) => setParentId(e.target.value)}>
              <option value="">Top level</option>
              {folderOptions.map(folder => (
                <option key={folder.id} value={folder.id}>{folder.label}</option>
              ))}
            </select>
          </div>
          <div className="media-folder-hint">
            Choose a parent folder now, or leave it at top level.
          </div>

          <label className="media-folder-label">Folder name</label>
          <div className={`media-folder-input-wrap${error ? " is-error" : ""}`}>
            <Icon name="file" size={14} />
            <input
              ref={inputRef}
              value={name}
              onChange={(e) => {
                setName(e.target.value);
                if (error) setError("");
              }}
              placeholder="Spring launch, Brand, Product shots…"
              maxLength={60}
            />
          </div>
          {error && (
            <div className="media-folder-error">
              <Icon name="warn" size={12} />
              {error}
            </div>
          )}
        </div>

        <div className="media-folder-foot">
          <div className="media-folder-foot-note">Press Enter to create</div>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="primary" iconLeft="plus" onClick={submitFolder}>
            {loading ? "Creating…" : isSubfolder ? "Create subfolder" : "Create folder"}
          </Button>
        </div>
      </div>
    </div>
  );
};

const RenameFolderModal = ({ open, folder, onClose, onSubmit, loading }) => {
  const [name, setName] = useState("");
  const [error, setError] = useState("");
  const inputRef = useRef(null);

  useEffect(() => {
    if (!open || !folder) return undefined;
    setName(folder.name || "");
    setError("");
    const focusTimer = setTimeout(() => {
      inputRef.current?.focus();
      inputRef.current?.select?.();
    }, 80);
    return () => clearTimeout(focusTimer);
  }, [open, folder]);

  const submitRename = () => {
    const nextName = name.trim();
    if (!nextName) {
      setError("Give this folder a name.");
      return;
    }
    if (nextName === folder?.name) {
      onClose();
      return;
    }
    onSubmit(folder, nextName).catch((err) => {
      setError(err?.message || "Unable to rename the folder.");
    });
  };

  useEffect(() => {
    if (!open) return undefined;
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      if (e.key === "Enter") {
        e.preventDefault();
        submitRename();
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open, name, folder]);

  if (!open || !folder) return null;

  return (
    <div className="media-folder-overlay" onClick={onClose}>
      <div className="media-folder-modal" onClick={(e) => e.stopPropagation()}>
        <div className="media-folder-head">
          <div className="media-folder-mark">
            <Icon name="type" size={18} />
          </div>
          <div className="media-folder-title-stack">
            <div className="media-folder-title">Rename folder</div>
            <div className="media-folder-sub">Update the folder name without changing its position in the library tree.</div>
          </div>
          <button className="media-folder-close" onClick={onClose}>
            <Icon name="x" size={14} />
          </button>
        </div>

        <div className="media-folder-body">
          <label className="media-folder-label">Folder name</label>
          <div className={`media-folder-input-wrap${error ? " is-error" : ""}`}>
            <Icon name="file" size={14} />
            <input
              ref={inputRef}
              value={name}
              onChange={(e) => {
                setName(e.target.value);
                if (error) setError("");
              }}
              placeholder="Folder name"
              maxLength={60}
            />
          </div>
          {error && (
            <div className="media-folder-error">
              <Icon name="warn" size={12} />
              {error}
            </div>
          )}
        </div>

        <div className="media-folder-foot">
          <div className="media-folder-foot-note">Press Enter to save</div>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="primary" iconLeft="check" onClick={submitRename}>
            {loading ? "Saving…" : "Save name"}
          </Button>
        </div>
      </div>
    </div>
  );
};

const MediaView = ({ profile }) => {
  const [assets, setAssets] = useState([]);
  const [folders, setFolders] = useState([]);
  const [loading, setLoading] = useState(true);
  const [activeFolder, setActiveFolder] = useState("all");
  const [selectedAssetId, setSelectedAssetId] = useState(null);
  const [query, setQuery] = useState("");
  const [typeFilter, setTypeFilter] = useState("all");
  const [sizeFilter, setSizeFilter] = useState("all");
  const [dateFilter, setDateFilter] = useState("all");
  const [typeDropOpen, setTypeDropOpen] = useState(false);
  const [sizeDropOpen, setSizeDropOpen] = useState(false);
  const [dateDropOpen, setDateDropOpen] = useState(false);
  const [activeTag, setActiveTag] = useState("");
  const [dragOver, setDragOver] = useState(false);
  const [uploading, setUploading] = useState([]);
  const [feedback, setFeedback] = useState(null);
  const [renameDraft, setRenameDraft] = useState("");
  const [tagsDraft, setTagsDraft] = useState("");
  const [savingAsset, setSavingAsset] = useState(false);
  const [createFolderOpen, setCreateFolderOpen] = useState(false);
  const [creatingFolder, setCreatingFolder] = useState(false);
  const [renameFolderState, setRenameFolderState] = useState({ open: false, folder: null, loading: false });
  const [openFolderMenu, setOpenFolderMenu] = useState(null);
  const fileInputRef = useRef(null);

  const wid = profile?.workspaceId;

  useEffect(() => {
    if (!wid) return;
    setLoading(true);

    const foldersRef = fbDb.collection("workspaces").doc(wid).collection("assetFolders");
    const assetsRef = fbDb.collection("workspaces").doc(wid).collection("assets");

    const unsubFolders = foldersRef.orderBy("order").onSnapshot(snap => {
      setFolders(snap.docs.map(d => ({ id: d.id, ...d.data() })));
    });

    const unsubAssets = assetsRef.orderBy("createdAt", "desc").onSnapshot(snap => {
      setAssets(snap.docs.map(d => ({ id: d.id, ...d.data() })));
      setLoading(false);
    }, () => {
      setLoading(false);
      setFeedback({ type: "error", text: "Unable to load assets from Firebase." });
    });

    return () => {
      unsubFolders();
      unsubAssets();
    };
  }, [wid]);

  useEffect(() => {
    if (!feedback) return undefined;
    const timer = setTimeout(() => setFeedback(null), 3200);
    return () => clearTimeout(timer);
  }, [feedback]);

  const selectedAsset = useMemo(
    () => assets.find(asset => asset.id === selectedAssetId) || null,
    [assets, selectedAssetId]
  );

  useEffect(() => {
    if (selectedAssetId && !selectedAsset) {
      setSelectedAssetId(null);
    }
  }, [selectedAssetId, selectedAsset]);

  useEffect(() => {
    if (activeFolder !== "all" && activeFolder !== "recent" && activeFolder !== "uncategorized" && !folders.some(folder => folder.id === activeFolder)) {
      setActiveFolder("all");
    }
  }, [activeFolder, folders]);

  useEffect(() => {
    setRenameDraft(selectedAsset?.name || "");
    setTagsDraft((selectedAsset?.tags || []).join(", "));
  }, [selectedAsset]);

  const storageUsedBytes = useMemo(
    () => assets.reduce((sum, asset) => sum + (asset.sizeBytes || 0), 0),
    [assets]
  );

  const optimizationCount = useMemo(
    () => assets.filter(asset => (asset.sizeBytes || 0) > OVERSIZE_THRESHOLD_BYTES).length,
    [assets]
  );

  const tagCounts = useMemo(() => {
    const counts = {};
    assets.forEach(asset => {
      (asset.tags || []).forEach(tag => {
        counts[tag] = (counts[tag] || 0) + 1;
      });
    });
    return Object.entries(counts)
      .map(([id, count]) => ({ id, label: id, count }))
      .sort((a, b) => b.count - a.count || a.label.localeCompare(b.label))
      .slice(0, 8);
  }, [assets]);

  const smartViews = useMemo(() => [
    { id: "all", label: "All assets", icon: "grid", count: assets.length },
    { id: "recent", label: "Recent", icon: "history", count: assets.filter(isRecentAsset).length },
    { id: "uncategorized", label: "No folder", icon: "file", count: assets.filter(asset => !asset.folderId).length },
  ], [assets]);

  const folderMap = useMemo(() => (
    folders.reduce((acc, folder) => {
      acc[folder.id] = folder;
      return acc;
    }, {})
  ), [folders]);

  const folderChildrenMap = useMemo(() => {
    const map = {};
    folders.forEach(folder => {
      const key = folder.parentId || "__root__";
      if (!map[key]) map[key] = [];
      map[key].push(folder);
    });
    Object.values(map).forEach(list => list.sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.name.localeCompare(b.name)));
    return map;
  }, [folders]);

  const getFolderChain = (folderId) => {
    const chain = [];
    let current = folderMap[folderId];
    let guard = 0;
    while (current && guard < 24) {
      chain.unshift(current);
      current = current.parentId ? folderMap[current.parentId] : null;
      guard += 1;
    }
    return chain;
  };

  const getFolderPathLabel = (folderId) => getFolderChain(folderId).map(folder => folder.name).join(" / ");

  const getDescendantFolderIds = (folderId) => {
    const ids = [folderId];
    const stack = [folderId];
    let guard = 0;
    while (stack.length > 0 && guard < 500) {
      const currentId = stack.pop();
      const children = folderChildrenMap[currentId] || [];
      children.forEach(child => {
        ids.push(child.id);
        stack.push(child.id);
      });
      guard += 1;
    }
    return ids;
  };

  const folderTreeRows = useMemo(() => {
    const rows = [];
    const build = (parentId, depth) => {
      (folderChildrenMap[parentId || "__root__"] || []).forEach(folder => {
        const subtreeIds = new Set(getDescendantFolderIds(folder.id));
        const count = assets.filter(asset => subtreeIds.has(asset.folderId)).length;
        rows.push({ ...folder, depth, count });
        build(folder.id, depth + 1);
      });
    };
    build(null, 0);
    return rows;
  }, [folderChildrenMap, assets]);

  const currentFolder = activeFolder && !["all", "recent", "uncategorized"].includes(activeFolder)
    ? folderMap[activeFolder] || null
    : null;
  const currentFolderChain = currentFolder ? getFolderChain(currentFolder.id) : [];
  const childFolders = currentFolder ? (folderChildrenMap[currentFolder.id] || []) : [];
  const createFolderDestinationLabel = currentFolder ? `Media / ${getFolderPathLabel(currentFolder.id)}` : "Media";
  const folderOptions = useMemo(() => (
    folders
      .map(folder => ({ id: folder.id, label: getFolderPathLabel(folder.id) || folder.name }))
      .sort((a, b) => a.label.localeCompare(b.label))
  ), [folders]);

  const activeFolderLabel = activeFolder === "all" ? "All assets"
    : activeFolder === "recent" ? "Recent uploads"
    : activeFolder === "uncategorized" ? "Assets without folder"
    : folders.find(folder => folder.id === activeFolder)?.name || "Media";

  const filteredAssets = useMemo(() => {
    let list = [...assets];

    if (activeFolder === "recent") list = list.filter(isRecentAsset);
    else if (activeFolder === "uncategorized") list = list.filter(asset => !asset.folderId);
    else if (activeFolder !== "all") list = list.filter(asset => asset.folderId === activeFolder);

    if (activeTag) list = list.filter(asset => (asset.tags || []).includes(activeTag));
    if (typeFilter !== "all") list = list.filter(asset => normalizeExtension(asset.ext) === typeFilter);
    if (sizeFilter === "oversized") list = list.filter(asset => (asset.sizeBytes || 0) > OVERSIZE_THRESHOLD_BYTES);
    if (sizeFilter === "huge") list = list.filter(asset => (asset.sizeBytes || 0) > 1024 * 1024);
    if (dateFilter !== "all") list = list.filter(asset => matchesDateFilter(asset, dateFilter));

    if (query.trim()) {
      const q = query.trim().toLowerCase();
      list = list.filter(asset =>
        asset.name?.toLowerCase().includes(q) ||
        normalizeExtension(asset.ext).includes(q) ||
        (asset.tags || []).some(tag => tag.toLowerCase().includes(q))
      );
    }

    return list;
  }, [assets, activeFolder, activeTag, typeFilter, sizeFilter, dateFilter, query]);

  const typeOptions = useMemo(() => {
    const counts = { all: assets.length };
    assets.forEach(asset => {
      const ext = normalizeExtension(asset.ext || getFileExtension(asset.name));
      if (!ext) return;
      counts[ext] = (counts[ext] || 0) + 1;
    });
    return [
      { id: "all", label: "All types", count: counts.all },
      ...["png", "jpg", "gif", "svg", "webp"].map(ext => ({
        id: ext,
        label: ext.toUpperCase(),
        count: counts[ext] || 0,
      })).filter(option => option.count > 0),
    ];
  }, [assets]);

  const sizeOptions = useMemo(() => ([
    { id: "all", label: "Any size", count: assets.length },
    { id: "oversized", label: "> 500 KB", count: assets.filter(asset => (asset.sizeBytes || 0) > OVERSIZE_THRESHOLD_BYTES).length },
    { id: "huge", label: "> 1 MB", count: assets.filter(asset => (asset.sizeBytes || 0) > 1024 * 1024).length },
  ]), [assets]);

  const dateOptions = useMemo(() => ([
    { id: "all", label: "Any date", count: assets.length },
    { id: "today", label: "Today", count: assets.filter(asset => matchesDateFilter(asset, "today")).length },
    { id: "week", label: "Last 7 days", count: assets.filter(asset => matchesDateFilter(asset, "week")).length },
    { id: "month", label: "Last 30 days", count: assets.filter(asset => matchesDateFilter(asset, "month")).length },
  ]), [assets]);

  const activeFilterCount = (typeFilter !== "all" ? 1 : 0) + (sizeFilter !== "all" ? 1 : 0) + (dateFilter !== "all" ? 1 : 0) + (activeTag ? 1 : 0);
  const showGroupedAllAssets = activeFolder === "all" && folders.length > 0;

  const groupedAssets = useMemo(() => {
    if (!showGroupedAllAssets) return [];

    const sections = folders
      .map(folder => {
        const items = filteredAssets.filter(asset => asset.folderId === folder.id);
        if (items.length === 0) return null;
        return {
          id: folder.id,
          title: getFolderPathLabel(folder.id) || folder.name,
          subtitle: folder.parentId ? "Subfolder" : "Folder",
          items,
        };
      })
      .filter(Boolean);

    const withoutFolder = filteredAssets.filter(asset => !asset.folderId || !folders.some(folder => folder.id === asset.folderId));
    if (withoutFolder.length > 0) {
      sections.push({
        id: "uncategorized",
        title: "No folder",
        subtitle: "Assets not assigned to a folder yet",
        items: withoutFolder,
      });
    }

    return sections;
  }, [showGroupedAllAssets, folders, filteredAssets]);

  const updateUpload = (id, patch) => {
    setUploading(prev => prev.map(item => item.id === id ? { ...item, ...patch } : item));
  };

  const finishUpload = (id) => {
    setTimeout(() => {
      setUploading(prev => prev.filter(item => item.id !== id));
    }, 1600);
  };

  const handleFiles = async (fileList) => {
    const files = Array.from(fileList || []);
    if (!wid || files.length === 0) return;
    const targetFolderId = activeFolder !== "all" && activeFolder !== "recent" && activeFolder !== "uncategorized"
      ? activeFolder
      : null;

    let unsupported = 0;
    let tooLarge = 0;

    for (const file of files) {
      const ext = normalizeExtension(getFileExtension(file.name));
      if (!ACCEPTED_EXTENSIONS.includes(ext)) {
        unsupported += 1;
        continue;
      }
      if (file.size > MAX_UPLOAD_BYTES) {
        tooLarge += 1;
        continue;
      }

      const uploadId = `upload-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
      setUploading(prev => [...prev, { id: uploadId, name: file.name, progress: 0, status: "preparing", error: "" }]);

      try {
        const dimensions = await readImageDimensions(file);
        const assetRef = fbDb.collection("workspaces").doc(wid).collection("assets").doc();
        const storagePath = `workspaces/${wid}/assets/${assetRef.id}/${Date.now()}-${sanitizeFileName(file.name)}`;
        const storageRef = fbStorage.ref(storagePath);
        const task = storageRef.put(file, file.type ? { contentType: file.type } : undefined);

        await new Promise((resolve, reject) => {
          task.on("state_changed", (snap) => {
            const progress = snap.totalBytes ? Math.round((snap.bytesTransferred / snap.totalBytes) * 100) : 0;
            updateUpload(uploadId, { progress, status: "uploading" });
          }, reject, resolve);
        });

        const downloadURL = await task.snapshot.ref.getDownloadURL();
        try {
          await assetRef.set({
            name: file.name,
            ext: ext.toUpperCase(),
            width: dimensions.width,
            height: dimensions.height,
            sizeBytes: file.size,
            storagePath,
            downloadURL,
            folderId: targetFolderId,
            tags: [],
            uses: 0,
            uploadedBy: fbAuth.currentUser?.uid || null,
            createdAt: firebase.firestore.FieldValue.serverTimestamp(),
            updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
          });
        } catch (err) {
          await storageRef.delete().catch(() => {});
          throw err;
        }

        updateUpload(uploadId, { progress: 100, status: "complete" });
        setSelectedAssetId(assetRef.id);
        finishUpload(uploadId);
      } catch (err) {
        updateUpload(uploadId, { status: "error", error: "Upload failed" });
      }
    }

    if (unsupported || tooLarge) {
      const parts = [];
      if (unsupported) parts.push(`${unsupported} unsupported file${unsupported > 1 ? "s" : ""}`);
      if (tooLarge) parts.push(`${tooLarge} file${tooLarge > 1 ? "s" : ""} over 5 MB`);
      setFeedback({ type: "error", text: `Skipped ${parts.join(" and ")}.` });
    } else {
      setFeedback({ type: "success", text: "Upload started." });
    }
  };

  const openCreateFolder = () => setCreateFolderOpen(true);

  const createFolder = async (folderName, parentIdOverride = null) => {
    if (!wid) return;
    const trimmedName = folderName.trim();
    if (!trimmedName) {
      throw new Error("Give this folder a name.");
    }

    const parentId = parentIdOverride !== null ? parentIdOverride : currentFolder?.id || null;
    const siblingCount = folders.filter(folder => (folder.parentId || null) === parentId).length;

    setCreatingFolder(true);
    try {
      const ref = fbDb.collection("workspaces").doc(wid).collection("assetFolders").doc();
      await ref.set({
        name: trimmedName,
        parentId,
        order: siblingCount,
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
      });
      setActiveFolder(ref.id);
      setCreateFolderOpen(false);
      setFeedback({ type: "success", text: `Folder "${trimmedName}" created.` });
    } catch (err) {
      throw new Error("Unable to create the folder.");
    } finally {
      setCreatingFolder(false);
    }
  };

  const renameFolder = async (folder) => {
    if (!folder) return;
    setRenameFolderState({ open: true, folder, loading: false });
    setOpenFolderMenu(null);
  };

  const submitRenameFolder = async (folder, nextName) => {
    if (!wid || !folder) return;
    setRenameFolderState({ open: true, folder, loading: true });
    try {
      await fbDb.collection("workspaces").doc(wid).collection("assetFolders").doc(folder.id).update({
        name: nextName,
      });
      setRenameFolderState({ open: false, folder: null, loading: false });
      setFeedback({ type: "success", text: `Folder renamed to "${nextName.trim()}".` });
    } catch (err) {
      setRenameFolderState({ open: true, folder, loading: false });
      throw new Error("Unable to rename the folder.");
    }
  };

  const deleteFolder = async (folder) => {
    if (!wid || !folder) return;
    const descendantIds = getDescendantFolderIds(folder.id);
    const assetsToMove = assets.filter(asset => descendantIds.includes(asset.folderId));
    const batch = fbDb.batch();

    try {
      assetsToMove.forEach(asset => {
        const assetRef = fbDb.collection("workspaces").doc(wid).collection("assets").doc(asset.id);
        batch.update(assetRef, {
          folderId: null,
          updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
        });
      });

      descendantIds.forEach(folderId => {
        const folderRef = fbDb.collection("workspaces").doc(wid).collection("assetFolders").doc(folderId);
        batch.delete(folderRef);
      });

      await batch.commit();
      if (activeFolder !== "all" && descendantIds.includes(activeFolder)) {
        setActiveFolder("all");
      }
      setFeedback({
        type: "success",
        text: assetsToMove.length > 0
          ? `Folder deleted. ${assetsToMove.length} asset${assetsToMove.length === 1 ? "" : "s"} moved to No folder.`
          : "Folder deleted.",
      });
    } catch (err) {
      setFeedback({ type: "error", text: "Unable to delete the folder." });
    } finally {
      setOpenFolderMenu(null);
    }
  };

  const saveSelectedAsset = async () => {
    if (!wid || !selectedAsset) return;
    const nextName = renameDraft.trim();
    if (!nextName) {
      setFeedback({ type: "error", text: "Filename cannot be empty." });
      return;
    }

    setSavingAsset(true);
    try {
      await fbDb.collection("workspaces").doc(wid).collection("assets").doc(selectedAsset.id).update({
        name: nextName,
        tags: parseTagInput(tagsDraft),
        updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
      });
      setFeedback({ type: "success", text: "Asset updated." });
    } catch (err) {
      setFeedback({ type: "error", text: "Unable to save asset changes." });
    } finally {
      setSavingAsset(false);
    }
  };

  const moveSelectedAsset = async (folderId) => {
    if (!wid || !selectedAsset) return;
    try {
      await fbDb.collection("workspaces").doc(wid).collection("assets").doc(selectedAsset.id).update({
        folderId: folderId || null,
        updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
      });
    } catch (err) {
      setFeedback({ type: "error", text: "Unable to move the asset." });
    }
  };

  const deleteSelectedAsset = async () => {
    if (!wid || !selectedAsset) return;
    if (!confirm(`Delete "${selectedAsset.name}" from the media library?`)) return;

    try {
      if (selectedAsset.storagePath) {
        try {
          await fbStorage.ref(selectedAsset.storagePath).delete();
        } catch (err) {
          if (err?.code !== "storage/object-not-found") throw err;
        }
      }
      await fbDb.collection("workspaces").doc(wid).collection("assets").doc(selectedAsset.id).delete();
      setSelectedAssetId(null);
      setFeedback({ type: "success", text: "Asset deleted." });
    } catch (err) {
      setFeedback({ type: "error", text: "Unable to delete this asset." });
    }
  };

  if (!wid || loading) {
    return (
      <div className="media" style={{ display: "flex", alignItems: "center", justifyContent: "center" }}>
        <span className="auth-spinner" />
      </div>
    );
  }

  return (
    <div className="media">
      <aside className="media-side">
        <h3>Library</h3>
        {smartViews.map(view => (
          <button key={view.id} className={`loc-namespace${activeFolder === view.id ? " is-active" : ""}`}
            onClick={() => setActiveFolder(view.id)}>
            <Icon name={view.icon} size={13} />
            <span>{view.label}</span>
            <span className="count">{view.count}</span>
          </button>
        ))}

        <div className="media-side-inline-action">
          <h3>Folders</h3>
          <button className="media-mini-action" onClick={openCreateFolder}>
            <Icon name="plus" size={12} />
            {currentFolder ? "Sub" : "New"}
          </button>
        </div>
        {folderTreeRows.map(folder => (
          <div key={folder.id} className={`media-folder-row${activeFolder === folder.id ? " is-active" : ""}`}>
            <button className={`loc-namespace${activeFolder === folder.id ? " is-active" : ""}`}
              onClick={() => setActiveFolder(folder.id)}
              style={{ paddingLeft: `${10 + folder.depth * 18}px` }}>
              <span className="media-folder-indent">
                {folder.depth > 0 ? <Icon name="chevronRight" size={10} style={{ opacity: 0.34 }} /> : null}
              </span>
              <Icon name="layers" size={13} />
              <span>{folder.name}</span>
              <span className="count">{folder.count}</span>
            </button>
            <button className={`media-folder-more${openFolderMenu === folder.id ? " is-open" : ""}`}
              title="Folder actions"
              onClick={(e) => {
                e.stopPropagation();
                setOpenFolderMenu(openFolderMenu === folder.id ? null : folder.id);
              }}>
              <Icon name="moreH" size={13} />
            </button>
            {openFolderMenu === folder.id && (
              <FolderActionsMenu
                folder={folder}
                onRename={renameFolder}
                onDelete={deleteFolder}
                onClose={() => setOpenFolderMenu(null)}
              />
            )}
          </div>
        ))}
        {folderTreeRows.length === 0 && (
          <div className="media-side-empty">Create your first media folder.</div>
        )}

        <h3>Tags</h3>
        <div style={{ padding: "6px 14px", display: "flex", flexWrap: "wrap", gap: 4 }}>
          {tagCounts.length === 0 && <span className="media-side-empty-tag">No tags yet</span>}
          {tagCounts.map(tag => (
            <button key={tag.id} className={`rail-tag${activeTag === tag.id ? " is-active" : ""}`}
              onClick={() => setActiveTag(activeTag === tag.id ? "" : tag.id)}>
              {tag.label}
              <span className="tag-count">{tag.count}</span>
            </button>
          ))}
        </div>

        <div className="rail-storage" style={{ marginTop: "auto", borderTop: "1px solid var(--border-1)" }}>
          <div className="rail-storage-head">
            <span>Asset storage</span>
            <span>{formatBytes(storageUsedBytes)} / 50 GB</span>
          </div>
          <div className="rail-storage-track">
            <div className="rail-storage-fill" style={{ width: `${Math.min(100, (storageUsedBytes / STORAGE_LIMIT_BYTES) * 100)}%`, background: "linear-gradient(90deg, #16a34a, #4ade80)" }} />
          </div>
          <div className="rail-storage-meta">{optimizationCount} assets flagged for optimization</div>
        </div>
      </aside>

      <section className="media-main">
        <header className="media-head">
          <div className="titles">
            <div className="loc-eyebrow" style={{ color: "var(--accent)" }}>Media</div>
            {currentFolderChain.length > 0 && (
              <div className="dash-breadcrumb media-breadcrumb">
                <button className="media-crumb" onClick={() => setActiveFolder("all")}>All assets</button>
                {currentFolderChain.map((folder, index) => (
                  <React.Fragment key={folder.id}>
                    <span>/</span>
                    <button
                      className={`media-crumb${index === currentFolderChain.length - 1 ? " is-current" : ""}`}
                      onClick={() => setActiveFolder(folder.id)}>
                      {folder.name}
                    </button>
                  </React.Fragment>
                ))}
              </div>
            )}
            <div className="loc-h1">
              {activeFolderLabel}
              <span className="dash-h1-count">{filteredAssets.length} {filteredAssets.length === 1 ? "file" : "files"}</span>
              {currentFolder && (
                <span className="media-folder-head-actions">
                  <button className="media-folder-head-btn" onClick={() => renameFolder(currentFolder)}>
                    <Icon name="type" size={12} />
                    Rename
                  </button>
                  <button className="media-folder-head-btn is-danger" onClick={() => deleteFolder(currentFolder)}>
                    <Icon name="trash" size={12} />
                    Delete
                  </button>
                </span>
              )}
            </div>
            <div className="loc-sub">
              Upload to Firebase Storage, tag assets, organize them in folders, and reuse them across your workspace.
            </div>
          </div>
          <Button variant="ghost" iconLeft="settings" onClick={() => setSizeFilter("oversized")}>Optimize all</Button>
          <Button variant="secondary" iconLeft="file" onClick={openCreateFolder}>{currentFolder ? "New subfolder" : "New folder"}</Button>
          <Button variant="primary" iconLeft="plus" onClick={() => fileInputRef.current?.click()}>Upload</Button>
          <input
            ref={fileInputRef}
            type="file"
            accept={ACCEPTED_EXTENSIONS.map(ext => `.${ext}`).join(",")}
            multiple
            style={{ display: "none" }}
            onChange={(e) => {
              handleFiles(e.target.files);
              e.target.value = "";
            }}
          />
        </header>

        <div className="media-toolbar">
          <div className="dash-search">
            <Icon name="search" size={13} />
            <input
              placeholder="Search assets, filenames, tags…"
              value={query}
              onChange={e => setQuery(e.target.value)}
            />
            {query && (
              <button className="dash-search-clear" onClick={() => setQuery("")}>
                <Icon name="x" size={11} />
              </button>
            )}
            {!query && <span className="kbd-hint">/</span>}
          </div>

          <div style={{ position: "relative" }}>
            <button className={`filter-chip${typeFilter !== "all" ? " is-active" : ""}`}
              onClick={() => { setTypeDropOpen(open => !open); setSizeDropOpen(false); setDateDropOpen(false); }}>
              <Icon name="image" size={13} />
              {typeFilter !== "all" ? typeFilter.toUpperCase() : "Type"}
              <Icon name="chevronDown" size={11} />
            </button>
            {typeDropOpen && (
              <MediaFilterDropdown
                options={typeOptions}
                value={typeFilter}
                onChange={setTypeFilter}
                onClose={() => setTypeDropOpen(false)}
                label="Filter by file type"
              />
            )}
          </div>

          <div style={{ position: "relative" }}>
            <button className={`filter-chip${sizeFilter !== "all" ? " is-active" : ""}`}
              onClick={() => { setSizeDropOpen(open => !open); setTypeDropOpen(false); setDateDropOpen(false); }}>
              <Icon name="warn" size={13} />
              {sizeFilter === "all" ? "Size" : sizeOptions.find(option => option.id === sizeFilter)?.label}
              <Icon name="chevronDown" size={11} />
            </button>
            {sizeDropOpen && (
              <MediaFilterDropdown
                options={sizeOptions}
                value={sizeFilter}
                onChange={setSizeFilter}
                onClose={() => setSizeDropOpen(false)}
                label="Filter by file size"
              />
            )}
          </div>

          <div style={{ position: "relative" }}>
            <button className={`filter-chip${dateFilter !== "all" ? " is-active" : ""}`}
              onClick={() => { setDateDropOpen(open => !open); setTypeDropOpen(false); setSizeDropOpen(false); }}>
              <Icon name="history" size={13} />
              {dateFilter === "all" ? "Uploaded" : dateOptions.find(option => option.id === dateFilter)?.label}
              <Icon name="chevronDown" size={11} />
            </button>
            {dateDropOpen && (
              <MediaFilterDropdown
                options={dateOptions}
                value={dateFilter}
                onChange={setDateFilter}
                onClose={() => setDateDropOpen(false)}
                label="Filter by upload date"
              />
            )}
          </div>

          {activeFilterCount > 0 && (
            <button className="filter-clear" onClick={() => { setTypeFilter("all"); setSizeFilter("all"); setDateFilter("all"); setActiveTag(""); }}>
              <Icon name="x" size={11} />
              Clear filters
            </button>
          )}

          <div className="dash-toolbar-spacer" />
          <span style={{ font: "500 11px var(--font-sans)", color: "var(--fg-3)" }}>
            {selectedAsset ? `Selected: ${selectedAsset.name}` : `${assets.length} total assets`}
          </span>
        </div>

        <div className="media-grid-wrap">
          {feedback && (
            <div className={`media-feedback media-feedback--${feedback.type}`}>
              <Icon name={feedback.type === "error" ? "warn" : "check"} size={14} />
              <span>{feedback.text}</span>
            </div>
          )}

          <div className={`dropzone${dragOver ? " is-drag" : ""}`}
            onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
            onDragLeave={() => setDragOver(false)}
            onDrop={(e) => {
              e.preventDefault();
              setDragOver(false);
              handleFiles(e.dataTransfer.files);
            }}>
            <div className="dropzone-icon"><Icon name="download" size={20} style={{ transform: "rotate(180deg)" }} /></div>
            <div className="dropzone-meta">
              <div className="title">Drop files to upload</div>
              <div className="sub">
                Supports <code>PNG</code> <code>JPG</code> <code>SVG</code> <code>GIF</code> <code>WEBP</code> ·
                max 5 MB per file · stored in Firebase Storage with searchable metadata in Firestore
              </div>
            </div>
            <Button variant="secondary" iconLeft="plus" onClick={() => fileInputRef.current?.click()}>Browse</Button>
          </div>

          {uploading.length > 0 && (
            <div className="media-upload-list">
              {uploading.map(upload => <UploadRow key={upload.id} upload={upload} />)}
            </div>
          )}

          {currentFolder && childFolders.length > 0 && (
            <div className="media-subfolders">
              <div className="media-subfolders-head">
                <div className="media-subfolders-title">Subfolders</div>
                <div className="media-subfolders-meta">{childFolders.length} {childFolders.length === 1 ? "folder" : "folders"}</div>
              </div>
              <div className="media-subfolder-grid">
                {childFolders.map(folder => (
                  <button key={folder.id} className="media-subfolder-card" onClick={() => setActiveFolder(folder.id)}>
                    <div className="media-subfolder-row">
                      <span className="media-subfolder-icon"><Icon name="layers" size={14} /></span>
                      <span className="media-subfolder-name">{folder.name}</span>
                      <Icon name="chevronRight" size={12} />
                    </div>
                    <div className="media-subfolder-meta">
                      {assets.filter(asset => asset.folderId === folder.id).length} direct asset{assets.filter(asset => asset.folderId === folder.id).length === 1 ? "" : "s"}
                    </div>
                  </button>
                ))}
              </div>
            </div>
          )}

          {selectedAsset && (
            <div className="asset-detail">
              <div className="asset-detail-preview">
                <div className="asset-detail-frame">
                  {normalizeExtension(selectedAsset.ext) === "svg" && <div className="checker" />}
                  {selectedAsset.downloadURL ? (
                    <img src={selectedAsset.downloadURL} alt={selectedAsset.name} />
                  ) : (
                    <div className="asset-thumb-placeholder">
                      <Icon name="image" size={24} />
                      <span>No preview</span>
                    </div>
                  )}
                </div>
              </div>

              <div className="asset-detail-main">
                <div className="asset-detail-head">
                  <div>
                    <div className="asset-detail-kicker">Asset details</div>
                    <div className="asset-detail-title">{selectedAsset.name}</div>
                  </div>
                  <div className="asset-detail-meta">
                    <span>{formatBytes(selectedAsset.sizeBytes)}</span>
                    <span className="sep" />
                    <span>{selectedAsset.width || 0} × {selectedAsset.height || 0}</span>
                    <span className="sep" />
                    <span>{timeAgo(selectedAsset.createdAt)}</span>
                  </div>
                </div>

                <div className="asset-detail-grid">
                  <label className="asset-form-field">
                    <span>Filename</span>
                    <input value={renameDraft} onChange={e => setRenameDraft(e.target.value)} />
                  </label>

                  <label className="asset-form-field">
                    <span>Folder</span>
                    <select value={selectedAsset.folderId || ""} onChange={e => moveSelectedAsset(e.target.value)}>
                      <option value="">No folder</option>
                      {folders.map(folder => <option key={folder.id} value={folder.id}>{getFolderPathLabel(folder.id) || folder.name}</option>)}
                    </select>
                  </label>

                  <label className="asset-form-field asset-form-field--wide">
                    <span>Tags</span>
                    <input
                      placeholder="brand, hero, legal approved"
                      value={tagsDraft}
                      onChange={e => setTagsDraft(e.target.value)}
                    />
                  </label>

                  <div className="asset-tag-list">
                    {(selectedAsset.tags || []).length > 0
                      ? (selectedAsset.tags || []).map(tag => <span key={tag} className="rail-tag">{tag}</span>)
                      : <span className="media-side-empty-tag">No tags assigned</span>}
                  </div>
                </div>

                <div className="asset-detail-actions">
                  <Button variant="secondary" iconLeft="eye" onClick={() => window.open(selectedAsset.downloadURL, "_blank", "noopener,noreferrer")}>Open file</Button>
                  <Button variant="ghost" iconLeft="download" onClick={() => window.open(selectedAsset.downloadURL, "_blank", "noopener,noreferrer")}>Open URL</Button>
                  <div className="asset-detail-spacer" />
                  <Button variant="secondary" onClick={saveSelectedAsset}>{savingAsset ? "Saving…" : "Save changes"}</Button>
                  <Button variant="ghost" iconLeft="trash" onClick={deleteSelectedAsset}>Delete</Button>
                </div>

                <div className="asset-detail-foot">
                  Uploaded {formatDate(selectedAsset.createdAt)} by {selectedAsset.uploadedBy === fbAuth.currentUser?.uid ? "you" : "a teammate"}.
                </div>
              </div>
            </div>
          )}

          {filteredAssets.length === 0 ? (
            <div className="media-empty">
              <Icon name="image" size={30} />
              <div className="media-empty-title">No assets found</div>
              <div className="media-empty-sub">
                {query || activeFilterCount > 0 || activeFolder !== "all"
                  ? "Try another search, folder, or filter."
                  : "Upload your first file to start building the media library."}
              </div>
              {!query && (
                <Button variant="primary" iconLeft="plus" onClick={() => fileInputRef.current?.click()}>Upload assets</Button>
              )}
            </div>
          ) : showGroupedAllAssets ? (
            <div className="media-groups">
              {groupedAssets.map(group => (
                <AssetGroupSection
                  key={group.id}
                  title={group.title}
                  subtitle={group.subtitle}
                  count={group.items.length}
                  assets={group.items}
                  selectedAssetId={selectedAssetId}
                  onSelectAsset={setSelectedAssetId}
                />
              ))}
            </div>
          ) : (
            <div className="media-grid">
              {filteredAssets.map(asset => (
                <AssetCard
                  key={asset.id}
                  asset={asset}
                  selected={selectedAssetId === asset.id}
                  onClick={() => setSelectedAssetId(asset.id)}
                />
              ))}
            </div>
          )}
        </div>
      </section>

      <CreateFolderModal
        open={createFolderOpen}
        onClose={() => !creatingFolder && setCreateFolderOpen(false)}
        onSubmit={createFolder}
        assetCount={assets.length}
        loading={creatingFolder}
        destinationLabel={createFolderDestinationLabel}
        isSubfolder={!!currentFolder}
        defaultParentId={currentFolder?.id || ""}
        folderOptions={folderOptions}
      />

      <RenameFolderModal
        open={renameFolderState.open}
        folder={renameFolderState.folder}
        onClose={() => !renameFolderState.loading && setRenameFolderState({ open: false, folder: null, loading: false })}
        onSubmit={submitRenameFolder}
        loading={renameFolderState.loading}
      />
    </div>
  );
};

Object.assign(window, { MediaView });
