import React, { useCallback, useEffect, useMemo, useRef, 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 ShareModal from "../components/storage/ShareModal";
import PaginationControls from "../components/storage/PaginationControls";

import { IoGrid, IoList } from "react-icons/io5";
import { LuCornerUpLeft, LuDownload, LuShare2, LuTrash2, LuInfo } from "react-icons/lu";

/* -------------------- helpers -------------------- */
const getFileId = (f) => f?.id ?? f?.file_id ?? f?.uuid ?? f?.pk;
const getFolderId = (f) => f?.id ?? f?.folder_id ?? f?.uuid ?? f?.pk;

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;
};

/* ---------------- Pagination 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 MenuBtn = ({ onAction, danger = false, children }) => (
  <button
    type="button"
    className={`w-full flex gap-2 items-center text-right rounded-xl text-sm font-semibold px-3 py-2
      ${
        danger
          ? "text-red-600 dark:text-red-300 hover:bg-red-500/10"
          : "dark:text-white text-black hover:bg-[#A1E3F980] dark:hover:bg-white/10"
      }`}
    onPointerDown={(e) => {
      e.preventDefault();
      e.stopPropagation();
    }}
    onClick={(e) => {
      e.preventDefault();
      e.stopPropagation();
      onAction?.();
    }}
  >
    {children}
  </button>
);

export default function Trash() {
  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]);

  const [files, setFiles] = useState([]);
  const [folders, setFolders] = useState([]);
  const [loading, setLoading] = useState(false);
  const [loadError, setLoadError] = useState(null);

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

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

  // reset pages when size/view changes
  useEffect(() => {
    setFoldersPage(1);
    setFilesPage(1);
  }, [pageSize, viewMode]);

  // reset pages when data changes
  useEffect(() => setFoldersPage(1), [folders.length]);
  useEffect(() => setFilesPage(1), [files.length]);

  const pagedFolders = useMemo(() => paginate(folders, foldersPage, pageSize), [folders, foldersPage, pageSize]);
  const pagedFiles = useMemo(() => paginate(files, filesPage, pageSize), [files, filesPage, pageSize]);

  /* -------------------- menus (portal state for your components) -------------------- */
  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 });

  // ShareModal مدل Star.jsx
  const [shareModal, setShareModal] = useState({
    open: false,
    file: null,
    data: null,
    downloadLink: "",
    copying: false,
    revoking: false,
    creating: false,
  });

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

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

  /* -------------------- fetch trash (strictmode safe) -------------------- */
  const mountedRef = useRef(false);
  const inFlightRef = useRef(false);

  const fetchTrash = useCallback(async () => {
    if (inFlightRef.current) return;
    inFlightRef.current = true;

    try {
      setLoading(true);
      setLoadError(null);

      const res = await Axiosinstance.get("storage/trash/");
      const data = res.data || {};

      const trashFiles = Array.isArray(data.files)
        ? data.files
        : Array.isArray(data?.results?.files)
        ? data.results.files
        : [];

      const trashFolders = Array.isArray(data.folders)
        ? data.folders
        : Array.isArray(data?.results?.folders)
        ? data.results.folders
        : [];

      setFiles(trashFiles);
      setFolders(trashFolders);
    } catch (err) {
      const msg = getFriendlyError(err, "خطا در دریافت سطل زباله.");
      setLoadError(msg);
      toast.error(msg);
    } finally {
      setLoading(false);
      inFlightRef.current = false;
    }
  }, [toast]);

  useEffect(() => {
    if (mountedRef.current) return;
    mountedRef.current = true;
    fetchTrash();
  }, [fetchTrash]);

  /* -------------------- actions (FILES) -------------------- */
  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, "دانلود فایل ناموفق بود."));
    } finally {
      closeFileMenu();
    }
  };

  const handleRestoreFile = async (file) => {
    try {
      const id = getFileId(file);
      await Axiosinstance.post(`storage/files/${id}/restore/`);
      setFiles((prev) => prev.filter((x) => String(getFileId(x)) !== String(id)));
      toast.success("فایل بازگردانی شد ✅");
    } catch (err) {
      toast.error(getFriendlyError(err, "بازگردانی فایل ناموفق بود."));
    } finally {
      closeFileMenu();
    }
  };

  const handleHardDeleteFile = async (file) => {
    try {
      const id = getFileId(file);
      await Axiosinstance.delete(`storage/files/${id}/hard-delete/`);
      setFiles((prev) => prev.filter((x) => String(getFileId(x)) !== String(id)));
      toast.success("فایل حذف دائمی شد ✅");
    } catch (err) {
      toast.error(getFriendlyError(err, "حذف دائمی فایل ناموفق بود."));
    } finally {
      closeFileMenu();
    }
  };

  // ShareModal مدل Star: POST storage/files/:id/share/ {permission,duration}
  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 }));
    }
  };

  /* -------------------- actions (FOLDERS) -------------------- */
  const handleRestoreFolder = async (folder) => {
    try {
      const id = getFolderId(folder);
      await Axiosinstance.post(`storage/folders/${id}/restore/`);
      setFolders((prev) => prev.filter((x) => String(getFolderId(x)) !== String(id)));
      toast.success("پوشه بازگردانی شد ✅");
    } catch (err) {
      toast.error(getFriendlyError(err, "بازگردانی پوشه ناموفق بود."));
    } finally {
      closeFolderMenu();
    }
  };

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

  /* -------------------- menu contents ONLY (NO ActionMenuPortal here) -------------------- */
  const renderFileMenu = useCallback(
    (file) => (
      <div className="flex flex-col gap-1">
        <MenuBtn onAction={() => openDetails("file", file)}>
          <LuInfo className="text-[#43BEFF]" />
          جزئیات
        </MenuBtn>

        <MenuBtn onAction={() => handleDownloadFile(file)}>
          <LuDownload className="text-[#43BEFF]" />
          دانلود
        </MenuBtn>

        <MenuBtn onAction={() => handleRestoreFile(file)}>
          <LuCornerUpLeft className="text-[#43BEFF]" />
          بازگردانی
        </MenuBtn>

        <MenuBtn danger onAction={() => handleHardDeleteFile(file)}>
          <LuTrash2 />
          حذف دائمی
        </MenuBtn>
      </div>
    ),
    [handleDownloadFile]
  );

  const renderFolderMenu = useCallback(
    (folder) => (
      <div className="flex flex-col gap-1">
        <MenuBtn onAction={() => openDetails("folder", folder)}>
          <LuInfo className="text-[#43BEFF]" />
          جزئیات
        </MenuBtn>

        <MenuBtn onAction={() => handleRestoreFolder(folder)}>
          <LuCornerUpLeft className="text-[#43BEFF]" />
          بازگردانی پوشه
        </MenuBtn>

        <MenuBtn danger onAction={() => handleHardDeleteFolder(folder)}>
          <LuTrash2 />
          حذف دائمی پوشه
        </MenuBtn>
      </div>
    ),
    []
  );

  /* -------------------- UI -------------------- */
  const totalCount = folders.length + files.length;

  return (
    <div
      className="w-full min-w-0 dark:text-white text-black"
      onClick={() => {
        closeFileMenu();
        closeFolderMenu();
      }}
    >
      {/* Details (project component) */}
      <DetailsModal
        state={detailsModal}
        onClose={() => setDetailsModal({ open: false, type: null, item: null })}
      />

      {/* Share (project component like Star.jsx) */}
      <ShareModal
        state={shareModal}
        onClose={() =>
          setShareModal({ open: false, file: null, data: null, downloadLink: "", copying: false, revoking: false, creating: false })
        }
        onCreate={handleCreateShare}
        onRevoke={handleRevokeShare}
      />

      {/* Header */}
      <div className="mb-5 rounded-2xl border border-black/10 dark:border-white/10 bg-[#A1E3F910] shadow p-3 sm:p-4">
        <div className="flex flex-col lg:flex-row gap-3 lg:items-center lg:justify-between min-w-0">
          <div className="min-w-0">
            <h1 className="text-lg sm:text-xl font-extrabold">سطل زباله</h1>
            <p className="text-xs sm:text-sm text-black/60 dark:text-white/70 truncate">
              کل: {totalCount} • پوشه‌ها: {folders.length} • فایل‌ها: {files.length}
            </p>
          </div>

          <div className="flex items-center gap-2 w-full lg:w-auto">
            <button
              onClick={() => setViewMode("grid")}
              className={`flex-1 lg:flex-none border rounded-xl px-3 py-2 inline-flex items-center justify-center gap-2 transition
                ${
                  viewMode === "grid"
                    ? "dark:bg-[#A1E3F919] bg-[#A1E3F980] dark:text-[#43BEFF] shadow text-black border-[#A1E3F919]"
                    : "border-[#A1E3F919] hover:bg-black/5 dark:text-white text-[#43BEFF] dark:hover:bg-white/10"
                }`}
            >
              <IoGrid className="h-5 w-5" />
              <span className="text-sm">گرید</span>
            </button>

            <button
              onClick={() => setViewMode("list")}
              className={`flex-1 lg:flex-none border rounded-xl px-3 py-2 inline-flex items-center justify-center gap-2 transition
                ${
                  viewMode === "list"
                    ? "dark:bg-[#A1E3F919] bg-[#A1E3F980] dark:text-[#43BEFF] shadow text-black border-[#A1E3F919]"
                    : "border-[#A1E3F919] hover:bg-black/5 dark:text-white text-[#43BEFF] dark:hover:bg-white/10"
                }`}
            >
              <IoList className="h-5 w-5" />
              <span className="text-sm">لیست</span>
            </button>
          </div>
        </div>
      </div>

      {/* 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>
      )}

      {!loading && !loadError && totalCount === 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">
          آیتمی در سطل زباله وجود ندارد.
        </div>
      )}

      {/* -------- Folders -------- */}
      {pagedFolders.total > 0 && (
        <div className="mb-6">
          <div className="flex items-center justify-between mb-3">
            <h2 className="font-extrabold text-base sm:text-lg">پوشه‌ها</h2>
          </div>

          <FoldersGrid
            folders={pagedFolders.items}
            onOpenFolder={() => {}}
            folderMenu={folderMenu}
            onToggleFolderMenu={toggleFolderMenu}
            onCloseFolderMenu={closeFolderMenu}
            renderFolderMenu={renderFolderMenu} // ✅ فقط content
          />

          <div className="mt-3">
            <PaginationControls
              total={pagedFolders.total}
              page={pagedFolders.page}
              onPageChange={setFoldersPage}
              pageSize={pageSize}
              onPageSizeChange={(n) => {
                const v = clampInt(n, 1, 200);
                setPageSize(v);
                try {
                  sessionStorage.setItem(SESSION_PAGE_SIZE_KEY, String(v));
                } catch {}
              }}
              label="پوشه‌ها"
            />
          </div>
        </div>
      )}

      {/* -------- Files -------- */}
      {pagedFiles.total > 0 && (
        <div className="mt-2">
          <div className="flex items-center justify-between mb-3">
            <h2 className="font-extrabold text-base sm:text-lg">فایل‌ها</h2>
          </div>

          {viewMode === "list" ? (
            <FilesList
              files={pagedFiles.items}
              fileMenu={fileMenu}
              onToggleFileMenu={toggleFileMenu}
              onCloseFileMenu={closeFileMenu}
              renderFileMenu={renderFileMenu} // ✅ فقط content
            />
          ) : (
            <FilesGrid
              files={pagedFiles.items}
              baseURL={Axiosinstance.defaults.baseURL}
              Axiosinstance={Axiosinstance}
              fileMenu={fileMenu}
              onToggleFileMenu={toggleFileMenu}
              onCloseFileMenu={closeFileMenu}
              renderFileMenu={renderFileMenu} // ✅ فقط content
            />
          )}

          <div className="mt-3">
            <PaginationControls
              total={pagedFiles.total}
              page={pagedFiles.page}
              onPageChange={setFilesPage}
              pageSize={pageSize}
              onPageSizeChange={(n) => {
                const v = clampInt(n, 1, 200);
                setPageSize(v);
                try {
                  sessionStorage.setItem(SESSION_PAGE_SIZE_KEY, String(v));
                } catch {}
              }}
              label="فایل‌ها"
            />
          </div>
        </div>
      )}
    </div>
  );
}
