import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Axiosinstance } from "../services/auth/Axiosinstance";
import { useToast } from "../components/ToastProvider";

import FilesList from "../components/storage/FilesList";
import FilesGrid from "../components/storage/FilesGrid";
import FoldersGrid from "../components/storage/FoldersGrid";

import DetailsModal from "../components/storage/DetailsModal";
import RenameModal from "../components/storage/RenameModal";
import MoveModal from "../components/storage/MoveModal";
import ShareModal from "../components/storage/ShareModal";
import ColorPickerModal from "../components/storage/ColorPickerModal";
import ZipModal from "../components/storage/ZipModal";

import StarTopBar from "../components/storage/StarTopBar";
import StarPathBar from "../components/storage/StarPathBar";

import { FileMenu, FolderMenu } from "../components/storage/ItemMenus";

import { useStorageColors } from "../hooks/useStorageColors";
import { useStorageDashboardItems } from "../hooks/useStorageDashboardItems";

import { flattenFolderTree, getFileId, getFolderId } from "../utils/storage";
import PaginationControls from "../components/storage/PaginationControls";

/* ---------------- session helpers ---------------- */
const SESSION_PAGE_SIZE_KEY = "storage.pageSize";
const readSessionInt = (key, fallback) => {
  try {
    const raw = sessionStorage.getItem(key);
    const n = Number.parseInt(raw, 10);
    return Number.isFinite(n) ? n : fallback;
  } catch {
    return fallback;
  }
};
const clampInt = (v, min, max) => {
  const n = Number.parseInt(String(v || ""), 10);
  if (!Number.isFinite(n)) return min;
  return Math.max(min, Math.min(max, n));
};
const paginate = (arr, page, size) => {
  const total = Array.isArray(arr) ? arr.length : 0;
  const totalPages = Math.max(1, Math.ceil(total / size));
  const p = clampInt(page, 1, totalPages);
  const start = (p - 1) * size;
  const end = start + size;
  return { total, totalPages, page: p, items: (arr || []).slice(start, end) };
};

const getFriendlyError = (err, fallback = "عملیات ناموفق بود.") => {
  const d = err?.response?.data;
  if (!d) return fallback;
  if (typeof d === "string") return d;
  if (typeof d?.detail === "string") return d.detail;
  if (typeof d?.message === "string") return d.message;
  const firstKey = d && typeof d === "object" ? Object.keys(d)[0] : null;
  if (firstKey) {
    const v = d[firstKey];
    if (Array.isArray(v) && v[0]) return String(v[0]);
    if (typeof v === "string") return v;
  }
  return fallback;
};

export default function Star() {
  const toastApi = useToast();
  const toast = useMemo(() => {
    if (toastApi?.success && toastApi?.error && toastApi?.info) return toastApi;
    if (toastApi?.show) {
      return {
        success: (m) => toastApi.show({ type: "success", message: m }),
        error: (m) => toastApi.show({ type: "error", message: m }),
        info: (m) => toastApi.show({ type: "info", message: m }),
      };
    }
    if (toastApi?.addToast) {
      return {
        success: (m) => toastApi.addToast("success", m),
        error: (m) => toastApi.addToast("error", m),
        info: (m) => toastApi.addToast("info", m),
      };
    }
    return { success: () => {}, error: () => {}, info: () => {} };
  }, [toastApi]);

  // ✅ items (tree + files flattened) از هوک
  const {
    foldersTreeRaw, // tree
    files, // all files with folderPath
    loading,
    loadError,
    requestRefresh,
    setFiles,
  } = useStorageDashboardItems({ Axiosinstance, toast });

  // ✅ colors
  const { colorsCfg, colorOptions, colorsLoading } = useStorageColors({ Axiosinstance, toast });

  // view
  const [viewMode, setViewMode] = useState("grid"); // list | grid

  // navigation stack (folder objects from tree)
  const [folderStack, setFolderStack] = useState([]);
  const selectedFolder = folderStack.length ? folderStack[folderStack.length - 1] : null;

  const currentPathText = useMemo(() => {
    if (!folderStack.length) return "";
    return folderStack.map((f) => f?.name || "-").join(" / ");
  }, [folderStack]);

  const currentPathForFiles = useMemo(() => {
    if (!folderStack.length) return "";
    return folderStack.map((f) => f?.name || "بدون نام").join("/");
  }, [folderStack]);

  // ✅ visible folders/files
  const starredFoldersAtRoot = useMemo(() => {
    const walkCollect = (arr, out = []) => {
      (arr || []).forEach((f) => {
        if (f?.is_starred) out.push(f);
        if (f?.folders?.length) walkCollect(f.folders, out);
      });
      return out;
    };
    return walkCollect(foldersTreeRaw || [], []);
  }, [foldersTreeRaw]);

  const visibleFolders = useMemo(() => {
    if (!selectedFolder) return starredFoldersAtRoot;
    return selectedFolder?.folders || [];
  }, [selectedFolder, starredFoldersAtRoot]);

  const visibleFiles = useMemo(() => {
    if (!selectedFolder) {
      // root: فقط فایل‌های ستاره‌دار از کل سیستم
      return (files || []).filter((f) => !!f?.is_starred);
    }
    // داخل فولدر ستاره‌دار: همه فایل‌های اون فولدر (نه فقط ستاره‌دار)
    const list = Array.isArray(selectedFolder?.files) ? selectedFolder.files : [];
    return list.map((f) => ({ ...f, folderPath: currentPathForFiles || "ریشه" }));
  }, [selectedFolder, files, currentPathForFiles]);

  // folders flat for move/zip
  const allFoldersFlat = useMemo(() => flattenFolderTree(foldersTreeRaw || []), [foldersTreeRaw]);

  /* ===================== Pagination ===================== */
  const [pageSize, setPageSize] = useState(() => clampInt(readSessionInt(SESSION_PAGE_SIZE_KEY, 8), 1, 200));
  const [foldersPage, setFoldersPage] = useState(1);
  const [filesPage, setFilesPage] = useState(1);

  useEffect(() => {
    setFoldersPage(1);
    setFilesPage(1);
  }, [selectedFolder, viewMode, pageSize]);

  const pagedFolders = useMemo(
    () => paginate(visibleFolders, foldersPage, pageSize),
    [visibleFolders, foldersPage, pageSize]
  );

  const pagedFiles = useMemo(
    () => paginate(visibleFiles, filesPage, pageSize),
    [visibleFiles, filesPage, pageSize]
  );

  // portal menus
  const [fileMenu, setFileMenu] = useState({ id: null, rect: null });
  const [folderMenu, setFolderMenu] = useState({ id: null, rect: null });
  const closeFileMenu = () => setFileMenu({ id: null, rect: null });
  const closeFolderMenu = () => setFolderMenu({ id: null, rect: null });

  const toggleFileMenu = (id, e) => {
    e.preventDefault();
    e.stopPropagation();
    const rect = e.currentTarget.getBoundingClientRect();
    setFileMenu((prev) => (String(prev.id) === String(id) ? { id: null, rect: null } : { id, rect }));
    setFolderMenu({ id: null, rect: null });
  };

  const toggleFolderMenu = (id, e) => {
    e.preventDefault();
    e.stopPropagation();
    const rect = e.currentTarget.getBoundingClientRect();
    setFolderMenu((prev) => (String(prev.id) === String(id) ? { id: null, rect: null } : { id, rect }));
    setFileMenu({ id: null, rect: null });
  };

  // modals
  const [detailsModal, setDetailsModal] = useState({ open: false, type: null, item: null });
  const [renameModal, setRenameModal] = useState({ open: false, type: null, item: null, value: "" });
  const [moveModal, setMoveModal] = useState({
    open: false,
    item: null,
    target: "root",
    createName: "",
    creating: false,
    moving: false,
  });

  const [shareModal, setShareModal] = useState({
    open: false,
    file: null,
    data: null,
    downloadLink: "",
    copying: false,
    revoking: false,
    creating: false,
  });

  const [colorModal, setColorModal] = useState({ open: false, type: null, item: null });

  const [zipModal, setZipModal] = useState({
    open: false,
    items: [],
    name: "",
    folder_id: "root",
    picking: false,
    pickValue: "",
    zipping: false,
  });

  // helpers open modal
  const openDetails = (type, item) => {
    closeFileMenu();
    closeFolderMenu();
    setDetailsModal({ open: true, type, item });
  };

  const openRename = (type, item) => {
    closeFileMenu();
    closeFolderMenu();
    setRenameModal({ open: true, type, item, value: item?.name || "" });
  };

  const openMove = (file) => {
    closeFileMenu();
    closeFolderMenu();
    setMoveModal({ open: true, item: file, target: "root", createName: "", creating: false, moving: false });
  };

  const openShare = (file) => {
    closeFileMenu();
    setShareModal({ open: true, file, data: null, downloadLink: "", copying: false, revoking: false, creating: false });
  };

  /* ===================== Zip / Unzip (درست) ===================== */
  const openZipModalWith = (seed) => {
    closeFileMenu();
    closeFolderMenu();
    setZipModal((p) => {
      const exists = (p.items || []).some((it) => it.type === seed.type && String(it.id) === String(seed.id));
      const items = exists ? p.items : [seed];
      const suggestedName =
        seed?.type === "folder"
          ? `${String(seed?.name || "archive").replaceAll("/", "-")}.zip`
          : `${String(seed?.name || "archive").replaceAll("/", "-")}.zip`;

      return {
        open: true,
        items,
        name: p.open ? p.name : suggestedName,
        folder_id: p.folder_id || "root",
        picking: false,
        pickValue: "",
        zipping: false,
      };
    });
  };

  const handleCreateArchive = async () => {
    const name = String(zipModal.name || "").trim();
    if (!name) return toast.error("نام فایل زیپ را وارد کنید.");

    const items = Array.isArray(zipModal.items) ? zipModal.items : [];
    const file_ids = items.filter((x) => x.type === "file").map((x) => x.id).filter(Boolean);
    const folder_ids = items.filter((x) => x.type === "folder").map((x) => x.id).filter(Boolean);

    if (file_ids.length === 0 && folder_ids.length === 0) return toast.error("حداقل یک فایل یا پوشه انتخاب کنید.");

    const folder_id = zipModal.folder_id && zipModal.folder_id !== "root" ? zipModal.folder_id : null;

    try {
      setZipModal((p) => ({ ...p, zipping: true }));
      toast.info("در حال ساخت آرشیو...");

      await Axiosinstance.post("storage/archive/create/", {
        name,
        folder_id,
        file_ids,
        folder_ids,
      });

      toast.success("زیپ ساخته شد ✅");
      setZipModal({
        open: false,
        items: [],
        name: "",
        folder_id: "root",
        picking: false,
        pickValue: "",
        zipping: false,
      });

      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "زیپ کردن ناموفق بود."));
      setZipModal((p) => ({ ...p, zipping: false }));
    }
  };

  const handleExtractZip = async (file, opts = {}) => {
    const id = getFileId(file);
    if (!id) return toast.error("شناسه فایل پیدا نشد.");

    const payload = {
      zip_file_id: id,
      target_folder_id: opts?.target_folder_id ?? null,
      create_subfolder: opts?.create_subfolder ?? true,
      overwrite: opts?.overwrite ?? false,
    };

    try {
      toast.info("در حال Extract ...");
      await Axiosinstance.post("storage/archive/extract/", payload);
      toast.success("انزیپ انجام شد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "انزیپ ناموفق بود."));
    }
  };

  /* ===================== API actions ===================== */
  const handleCreateFolder = async (name, parent) => {
    try {
      const clean = String(name || "").trim();
      if (!clean) return toast.error("نام پوشه را وارد کنید.");
      const payload = parent === "root" ? { name: clean } : { name: clean, parent };
      await Axiosinstance.post("storage/folders/", payload);
      toast.success("پوشه ساخته شد ✅");
      await requestRefresh({ silent: true });
      return true;
    } catch (err) {
      toast.error(getFriendlyError(err, "ساخت پوشه ناموفق بود."));
      return false;
    }
  };

  const handleDownloadFile = async (file) => {
    try {
      const id = getFileId(file);
      const response = await Axiosinstance.get(`storage/files/${id}/download/`, { responseType: "blob" });
      const blobUrl = window.URL.createObjectURL(new Blob([response.data]));
      const link = document.createElement("a");
      link.href = blobUrl;
      link.download = file.name || "file";
      document.body.appendChild(link);
      link.click();
      link.remove();
      window.URL.revokeObjectURL(blobUrl);
      toast.success("دانلود شروع شد ✅");
    } catch (err) {
      toast.error(getFriendlyError(err, "دانلود فایل ناموفق بود."));
    }
  };

  const handleTrashFile = async (file) => {
    try {
      const id = getFileId(file);
      await Axiosinstance.post(`storage/files/${id}/trash/`);
      toast.info("فایل به سطل زباله منتقل شد.");
      setFiles((prev) => prev.map((f) => (String(getFileId(f)) === String(id) ? { ...f, in_trash: true } : f)));
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "انتقال به سطل زباله ناموفق بود."));
    }
  };

  const handleRestoreFile = async (file) => {
    try {
      const id = getFileId(file);
      await Axiosinstance.post(`storage/files/${id}/restore/`);
      toast.success("فایل بازیابی شد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "بازگردانی ناموفق بود."));
    }
  };

  const handleHardDeleteFile = async (file) => {
    try {
      const id = getFileId(file);
      await Axiosinstance.delete(`storage/files/${id}/hard-delete/`);
      toast.success("حذف دائمی فایل انجام شد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "حذف دائمی ناموفق بود."));
    }
  };

  const handleStarFile = async (file) => {
    try {
      const id = getFileId(file);
      const res = await Axiosinstance.post(`storage/files/${id}/star/`);
      const is_starred = typeof res.data?.is_starred === "boolean" ? res.data.is_starred : !file.is_starred;
      toast.success(is_starred ? "به ستاره‌دارها اضافه شد ⭐" : "از ستاره‌دارها حذف شد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "ستاره‌دار کردن ناموفق بود."));
    }
  };

  const handleRenameFile = async (file, name) => {
    try {
      const id = getFileId(file);
      await Axiosinstance.patch(`storage/files/${id}/rename/`, { name });
      toast.success("نام فایل تغییر کرد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "تغییر نام فایل ناموفق بود."));
    }
  };

  const handleMoveFile = async (file, destination_folder_id) => {
    try {
      const id = getFileId(file);
      await Axiosinstance.post(`storage/files/${id}/move/`, { destination_folder_id });
      toast.success("فایل منتقل شد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "انتقال فایل ناموفق بود."));
    }
  };

  const handleTrashFolder = async (folder) => {
    try {
      const id = getFolderId(folder);
      await Axiosinstance.post(`storage/folders/${id}/trash/`);
      toast.info("پوشه به سطل زباله منتقل شد.");
      setFolderStack((p) => (p.some((x) => String(getFolderId(x)) === String(id)) ? [] : p));
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "انتقال پوشه ناموفق بود."));
    }
  };

  const handleRestoreFolder = async (folder) => {
    try {
      const id = getFolderId(folder);
      await Axiosinstance.post(`storage/folders/${id}/restore/`);
      toast.success("پوشه بازیابی شد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "بازگردانی پوشه ناموفق بود."));
    }
  };

  const handleHardDeleteFolder = async (folder) => {
    try {
      const id = getFolderId(folder);
      await Axiosinstance.delete(`storage/folders/${id}/hard-delete/`);
      toast.success("حذف دائمی پوشه انجام شد ✅");
      setFolderStack((p) => p.filter((x) => String(getFolderId(x)) !== String(id)));
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "حذف دائمی پوشه ناموفق بود."));
    }
  };

  const handleStarFolder = async (folder) => {
    try {
      const id = getFolderId(folder);
      const res = await Axiosinstance.post(`storage/folders/${id}/star/`);
      const is_starred = typeof res.data?.is_starred === "boolean" ? res.data.is_starred : !folder.is_starred;
      toast.success(is_starred ? "پوشه ستاره‌دار شد ⭐" : "پوشه از ستاره‌دارها حذف شد ✅");
      if (!is_starred && selectedFolder && String(getFolderId(selectedFolder)) === String(id)) {
        setFolderStack([]);
      }
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "ستاره‌دار کردن پوشه ناموفق بود."));
    }
  };

  const handleRenameFolder = async (folder, name) => {
    try {
      const id = getFolderId(folder);
      await Axiosinstance.patch(`storage/folders/${id}/`, { name });
      toast.success("نام پوشه تغییر کرد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "تغییر نام پوشه ناموفق بود."));
    }
  };

  // share (مدل جدید)
  const handleCreateShare = async ({ permission, duration, file }) => {
    if (!file) return toast.error("فایل انتخاب نشده.");
    try {
      setShareModal((p) => ({ ...p, creating: true }));
      const id = getFileId(file);
      const res = await Axiosinstance.post(`storage/files/${id}/share/`, { permission, duration });
      setShareModal((p) => ({
        ...p,
        data: res.data,
        downloadLink: res.data?.download_url || res.data?.share_url || "",
        creating: false,
      }));
      toast.success("لینک اشتراک ساخته شد ✅");
    } catch (err) {
      toast.error(getFriendlyError(err, "ساخت لینک اشتراک ناموفق بود."));
      setShareModal((p) => ({ ...p, creating: false }));
    }
  };

  const handleRevokeShare = async () => {
    const token = shareModal?.data?.token;
    const file = shareModal?.file;
    if (!token || !file) return toast.error("توکن اشتراک پیدا نشد.");

    try {
      setShareModal((p) => ({ ...p, revoking: true }));
      const id = getFileId(file);
      await Axiosinstance.post(`storage/files/${id}/share/revoke/`, { token });
      toast.success("اشتراک لغو شد ✅");
      setShareModal({
        open: false,
        file: null,
        data: null,
        downloadLink: "",
        copying: false,
        revoking: false,
        creating: false,
      });
    } catch (err) {
      toast.error(getFriendlyError(err, "لغو اشتراک ناموفق بود."));
      setShareModal((p) => ({ ...p, revoking: false }));
    }
  };

  const handleSetColor = async (type, item, color_id) => {
    try {
      if (type === "file") {
        const id = getFileId(item);
        await Axiosinstance.patch(`storage/files/${id}/color/`, { color_id: color_id ?? null });
      } else {
        const id = getFolderId(item);
        await Axiosinstance.patch(`storage/folders/${id}/color/`, { color_id: color_id ?? null });
      }
      toast.success("رنگ تغییر کرد ✅");
      await requestRefresh({ silent: true });
    } catch (err) {
      toast.error(getFriendlyError(err, "تغییر رنگ ناموفق بود."));
    }
  };

  /* ===================== Menus render (ItemMenus) ===================== */
  const renderFileMenu = useCallback(
    (file) => (
      <FileMenu
        file={file}
        colorsCfg={colorsCfg}
        colorOptions={colorOptions}
        colorsLoading={colorsLoading}
        onDetails={(t, it) => openDetails(t, it)}
        onRename={(f) => openRename("file", f)}
        onShare={(f) => openShare(f)}
        onDownload={(f) => handleDownloadFile(f)}
        onMove={(f) => openMove(f)}
        onToggleStar={(f) => handleStarFile(f)}
        onTrashOrRestore={(f, mode) => (mode === "trash" ? handleTrashFile(f) : handleRestoreFile(f))}
        onHardDelete={(f) => handleHardDeleteFile(f)}
        onOpenColorModal={(f) => {
          closeFileMenu();
          setColorModal({ open: true, type: "file", item: f });
        }}
        onZip={(seed) => {
          // seed باید {type,id,name}
          openZipModalWith({ type: "file", id: String(getFileId(seed)), name: seed?.name || "file" });
          closeFileMenu();
        }}
        onUnzip={async (f) => {
          await handleExtractZip(f);
          closeFileMenu();
        }}
      />
    ),
    [colorsCfg, colorOptions, colorsLoading, pageSize]
  );

  const renderFolderMenu = useCallback(
    (folder) => (
      <FolderMenu
        folder={folder}
        colorsCfg={colorsCfg}
        colorOptions={colorOptions}
        colorsLoading={colorsLoading}
        onDetails={(t, it) => openDetails(t, it)}
        onRename={(fo) => openRename("folder", fo)}
        onToggleStar={(fo) => handleStarFolder(fo)}
        onTrashOrRestore={(fo, mode) => (mode === "trash" ? handleTrashFolder(fo) : handleRestoreFolder(fo))}
        onHardDelete={(fo) => handleHardDeleteFolder(fo)}
        onOpenColorModal={(fo) => {
          closeFolderMenu();
          setColorModal({ open: true, type: "folder", item: fo });
        }}
        onZip={(seed) => {
          openZipModalWith({ type: "folder", id: String(getFolderId(seed)), name: seed?.name || "folder" });
          closeFolderMenu();
        }}
      />
    ),
    [colorsCfg, colorOptions, colorsLoading, selectedFolder]
  );

  /* ===================== UI ===================== */
  const openFolder = (folder) => {
    closeFileMenu();
    closeFolderMenu();
    setFolderStack((prev) => [...prev, folder]);
  };

  const backOne = () => {
    closeFileMenu();
    closeFolderMenu();
    setFolderStack((prev) => prev.slice(0, -1));
  };

  return (
    <div
      className="w-full min-w-0 dark:text-white text-black"
      onClick={() => {
        closeFileMenu();
        closeFolderMenu();
      }}
    >
      {/* Zip Modal */}
      <ZipModal
        state={zipModal}
        setState={setZipModal}
        files={(visibleFiles || []).map((f) => ({ ...f, id: String(getFileId(f)) }))}
        allFoldersFlat={allFoldersFlat}
        onCreateArchive={handleCreateArchive}
      />

      {/* Modals */}
      <DetailsModal state={detailsModal} onClose={() => setDetailsModal({ open: false, type: null, item: null })} />

      <RenameModal
        state={renameModal}
        setState={setRenameModal}
        onSave={async () => {
          const item = renameModal.item;
          const name = String(renameModal.value || "").trim();
          if (!item || !name) return toast.error("نام جدید را وارد کنید.");

          if (renameModal.type === "file") await handleRenameFile(item, name);
          if (renameModal.type === "folder") await handleRenameFolder(item, name);

          setRenameModal({ open: false, type: null, item: null, value: "" });
        }}
      />

      <MoveModal
        state={moveModal}
        setState={setMoveModal}
        foldersFlat={allFoldersFlat}
        onCreateFolder={async (name, parentId) => handleCreateFolder(name, parentId)}
        onMove={async (file, dest) => {
          const finalDest = dest === "root" ? null : dest;
          await handleMoveFile(file, finalDest);
          setMoveModal({ open: false, item: null, target: "root", createName: "", creating: false, moving: false });
        }}
      />

      <ShareModal
        state={shareModal}
        onClose={() =>
          setShareModal({
            open: false,
            file: null,
            data: null,
            downloadLink: "",
            copying: false,
            revoking: false,
            creating: false,
          })
        }
        onCreate={handleCreateShare}
        onRevoke={handleRevokeShare}
      />

      <ColorPickerModal
        open={colorModal.open}
        onClose={() => setColorModal({ open: false, type: null, item: null })}
        title="تغییر رنگ"
        itemName={colorModal?.item?.name || ""}
        colorsCfg={colorsCfg}
        colorOptions={colorOptions}
        colorsLoading={colorsLoading}
        onPick={async (colorIdOrNull) => {
          const t = colorModal.type;
          const it = colorModal.item;
          if (!t || !it) return;
          await handleSetColor(t, it, colorIdOrNull);
          setColorModal({ open: false, type: null, item: null });
        }}
      />

      {/* Top bar */}
      <StarTopBar
        viewMode={viewMode}
        setViewMode={setViewMode}
        selectedFolderName={selectedFolder?.name || ""}
        foldersCount={visibleFolders.length}
        filesCount={visibleFiles.length}
      />

      {/* Path bar */}
      <StarPathBar canBack={!!selectedFolder} pathText={currentPathText} onBack={backOne} />

      {/* States */}
      {loading && (
        <div className="p-4 mb-4 rounded-2xl border border-black/10 dark:border-white/10 bg-white/60 dark:bg-[#16325b] text-sm">
          در حال دریافت اطلاعات...
        </div>
      )}
      {loadError && (
        <div className="p-4 mb-4 rounded-2xl border border-red-500/30 bg-red-500/10 text-sm text-red-600 dark:text-red-200">
          {loadError}
        </div>
      )}

      {/* Folders */}
      <div className="mb-6">
        <div className="flex justify-between flex-wrap items-center">
          <h2 className="dark:text-white text-black font-extrabold text-base sm:text-lg">
            {selectedFolder ? "پوشه‌های داخل این پوشه" : "پوشه‌های ستاره‌دار"}
          </h2>
        </div>

        {!loading && pagedFolders.total === 0 ? (
          <p className="dark:text-white/60 text-sm mt-4">
            {selectedFolder ? "پوشه‌ای داخل این پوشه وجود ندارد." : "پوشه ستاره‌داری برای نمایش وجود ندارد."}
          </p>
        ) : (
          <>
            <FoldersGrid
              folders={pagedFolders.items}
              onOpenFolder={openFolder}
              folderMenu={folderMenu}
              onToggleFolderMenu={toggleFolderMenu}
              onCloseFolderMenu={closeFolderMenu}
              renderFolderMenu={renderFolderMenu}
            />

            <div className="mt-3">
              <PaginationControls
                total={pagedFolders.total}
                page={pagedFolders.page}
                onPageChange={setFoldersPage}
                pageSize={pageSize}
                onPageSizeChange={setPageSize}
                sessionKey={SESSION_PAGE_SIZE_KEY}
                defaultPageSize={8}
                label="پوشه‌ها"
              />
            </div>
          </>
        )}
      </div>

      {/* Files */}
      <div className="flex items-center justify-between mb-3">
        <h2 className="dark:text-white text-black font-extrabold text-base sm:text-lg">
          {selectedFolder ? `فایل‌های داخل "${selectedFolder?.name || "-"}"` : "فایل‌های ستاره‌دار"}
        </h2>
      </div>

      {!loading && pagedFiles.total === 0 && (
        <div className="p-4 rounded-2xl border border-black/10 dark:border-white/10 bg-white/60 dark:bg-[#16325b] text-sm text-black/60 dark:text-white/70">
          {selectedFolder ? "فایلی در این پوشه وجود ندارد." : "فایل ستاره‌داری برای نمایش وجود ندارد."}
        </div>
      )}

      {pagedFiles.total > 0 && (
        <>
          {viewMode === "list" ? (
            <FilesList
              files={pagedFiles.items}
              fileMenu={fileMenu}
              onToggleFileMenu={toggleFileMenu}
              onCloseFileMenu={closeFileMenu}
              renderFileMenu={renderFileMenu}
            />
          ) : (
            <FilesGrid
              files={pagedFiles.items}
              baseURL={Axiosinstance.defaults.baseURL}
              Axiosinstance={Axiosinstance}
              fileMenu={fileMenu}
              onToggleFileMenu={toggleFileMenu}
              onCloseFileMenu={closeFileMenu}
              renderFileMenu={renderFileMenu}
            />
          )}

          <div className="mt-3">
            <PaginationControls
              total={pagedFiles.total}
              page={pagedFiles.page}
              onPageChange={setFilesPage}
              pageSize={pageSize}
              onPageSizeChange={setPageSize}
              sessionKey={SESSION_PAGE_SIZE_KEY}
              defaultPageSize={8}
              label="فایل‌ها"
            />
          </div>
        </>
      )}
    </div>
  );
}
