"use client";
import { useEffect, useState } from "react";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Button } from "@/components/ui/button";
import { DownloadIcon, EyeOpenIcon, TrashIcon } from "@radix-ui/react-icons";
import { ChevronLeft, ChevronRight, Loader2 } from "lucide-react";
import { formatDatetime } from "@/utils/formatDatetime";
import { createClient } from "@/utils/supabase/client";
import { toast } from "@/hooks/use-toast";

interface FileTableProps {
  fetchData: () => Promise<void>;
  ragData: any[];
}

export default function FileTable({ fetchData, ragData }: FileTableProps) {
  const supabase = createClient();
  const [loadingMap, setLoadingMap] = useState<Record<string, boolean>>({});
  const [currentPage, setCurrentPage] = useState(1);
  const [sortedData, setSortedData] = useState<any[]>([]);
  const itemsPerPage = 10; // Adjust as needed
  const pagesToShow = 2; // Number of page buttons to display at once

  useEffect(() => {
    // Sort data by created_at in descending order (newest first)
    if (ragData && ragData.length > 0) {
      const sorted = [...ragData].sort((a, b) => {
        return (
          new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
        );
      });
      setSortedData(sorted);
    } else {
      setSortedData([]);
    }
  }, [ragData]);

  const downloadAllFiles = async () => {
    try {
      const res = await fetch("/api/download-all");
      if (!res.ok) {
        throw new Error("Gagal mengunduh file ZIP");
      }

      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = "all-files.zip";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    } catch (error) {
      toast({
        title: "Gagal",
        description: "Tidak dapat mengunduh semua file.",
        variant: "destructive",
      });
    }
  };

  const deleteAllFiles = async () => {
    const confirmed = window.confirm("Yakin ingin menghapus SEMUA file?");
    if (!confirmed) return;

    try {
      const fileNames = sortedData.map((item) => item.name);
      setLoadingMap(
        fileNames.reduce((acc, name) => ({ ...acc, [name]: true }), {}),
      );

      const { error } = await supabase.storage
        .from("pnp-bot-storage")
        .remove(fileNames);

      if (error) {
        toast({
          title: "Gagal menghapus semua file",
          description: error.message,
          variant: "destructive",
        });
      } else {
        toast({
          title: "Semua file berhasil dihapus",
          description: `${fileNames.length} file telah dihapus.`,
        });
        fetchData(); // refresh data
      }
    } catch (err) {
      console.error("Gagal menghapus semua file:", err);
      toast({
        title: "Terjadi kesalahan",
        description: "Tidak dapat menghapus semua file.",
        variant: "destructive",
      });
    } finally {
      setLoadingMap({});
    }
  };

  const deleteItem = async (fileName: string) => {
    const confirmed = window.confirm(
      `Yakin ingin menghapus file "${fileName}"?`,
    );
    if (!confirmed) return;

    try {
      setLoadingMap((prev) => ({ ...prev, [fileName]: true }));

      const { error } = await supabase.storage
        .from("pnp-bot-storage")
        .remove([fileName]);

      if (error) {
        toast({
          title: "Gagal menghapus file",
          description: error.message,
          variant: "destructive",
        });
      } else {
        toast({
          title: "File berhasil dihapus",
          description: `File "${fileName}" telah dihapus.`,
        });
        fetchData(); // refresh daftar file
      }
    } catch (err) {
      console.error("Gagal menghapus:", err);
      toast({
        title: "Terjadi kesalahan",
        description: "Tidak dapat menghapus file.",
        variant: "destructive",
      });
    } finally {
      setLoadingMap((prev) => ({ ...prev, [fileName]: false }));
    }
  };

  // Lihat File (Open in New Tab)
  const inspectItem = (fileName: string) => {
    const { data } = supabase.storage
      .from("pnp-bot-storage")
      .getPublicUrl(fileName);

    if (!data?.publicUrl) {
      toast({
        title: "Gagal membuka file",
        description: `File "${fileName}" tidak memiliki URL publik.`,
        variant: "destructive",
      });
      return;
    }

    window.open(data.publicUrl, "_blank");
  };

  // Unduh File
  const downloadItem = async (fileName: string) => {
    try {
      // Retrieve the file as a blob using the download method
      const { data, error } = await supabase.storage
        .from("pnp-bot-storage") // Use your bucket name
        .download(fileName);

      if (error) {
        toast({
          title: "Gagal mengunduh file",
          description: error.message || "Terjadi kesalahan saat mengunduh.",
          variant: "destructive",
        });
        return;
      }

      // Create a link element to download the file
      const url = URL.createObjectURL(data);
      const link = document.createElement("a");
      link.href = url;
      link.download = fileName;

      // Programmatically trigger the download
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

      // Clean up the object URL
      URL.revokeObjectURL(url);

      toast({
        title: "Unduh berhasil",
        description: `File "${fileName}" berhasil diunduh.`,
        duration: 2000,
      });
    } catch (err) {
      console.error("Gagal mengunduh:", err);
      toast({
        title: "Terjadi kesalahan",
        description: "Tidak dapat mengunduh file.",
        variant: "destructive",
      });
    }
  };

  // Calculate pagination
  const totalPages = Math.ceil(sortedData.length / itemsPerPage);
  const paginatedData = sortedData.slice(
    (currentPage - 1) * itemsPerPage,
    currentPage * itemsPerPage,
  );

  const goToNextPage = () => {
    if (currentPage < totalPages) {
      setCurrentPage(currentPage + 1);
    }
  };

  const goToPrevPage = () => {
    if (currentPage > 1) {
      setCurrentPage(currentPage - 1);
    }
  };

  const goToPage = (page: number) => {
    setCurrentPage(page);
  };

  // Calculate the range of page numbers to display
  const startPage = Math.max(1, currentPage - Math.floor(pagesToShow / 2));
  const endPage = Math.min(totalPages, startPage + pagesToShow - 1);
  const pageNumbers = Array.from(
    { length: endPage - startPage + 1 },
    (_, index) => startPage + index,
  );

  return (
    <div className="space-y-4">
      <Table>
        <TableHeader className="bg-slate-100">
          <TableRow>
            <TableHead className="text-center">#</TableHead>
            <TableHead className="min-w-[240px]">Name</TableHead>
            <TableHead>Uploaded At</TableHead>
            <TableHead>File Size</TableHead>
            <TableHead className="text-center">
              <div className="flex justify-center gap-2">
                <Button
                  size="sm"
                  variant="outline"
                  className="hover:bg-blue-600 hover:text-white"
                  onClick={downloadAllFiles}
                >
                  <DownloadIcon className="mr-1 h-4 w-4" />
                  All
                </Button>
                <Button
                  size="sm"
                  variant="destructive"
                  className="hover:bg-red-800"
                  onClick={deleteAllFiles}
                >
                  <TrashIcon className="mr-1 h-4 w-4" />
                  All
                </Button>
              </div>
            </TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {paginatedData && paginatedData.length > 0 ? (
            paginatedData.map((item: any, index: number) => (
              <TableRow key={index}>
                <TableCell className="text-center">
                  {(currentPage - 1) * itemsPerPage + index + 1}
                </TableCell>
                <TableCell className="min-w-[240px] font-medium">
                  {item.name}
                </TableCell>
                <TableCell>{formatDatetime(item.created_at)}</TableCell>
                <TableCell>{item.metadata.size}</TableCell>
                <TableCell className="flex justify-center gap-2">
                  <Button
                    variant={"secondary"}
                    className="hover:bg-neutral-500 hover:text-white"
                    onClick={() => inspectItem(item.name)}
                  >
                    <EyeOpenIcon className="h-4 w-4" />
                  </Button>
                  <Button
                    variant="outline"
                    className="hover:bg-blue-600 hover:text-white"
                    onClick={() => downloadItem(item.name)}
                  >
                    <DownloadIcon className="h-4 w-4" />
                  </Button>
                  <Button
                    variant={"destructive"}
                    className="hover:bg-red-800"
                    onClick={() => deleteItem(item.name)}
                  >
                    {loadingMap[item.name] ? (
                      <Loader2 className="h-4 w-4 animate-spin" />
                    ) : (
                      <TrashIcon className="h-4 w-4" />
                    )}
                  </Button>
                </TableCell>
              </TableRow>
            ))
          ) : (
            <TableRow>
              <TableCell colSpan={5} className="py-4 text-center">
                No Data Available
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>

      {/* Pagination Controls */}
      {sortedData.length > 0 && (
        <div className="flex items-center justify-between px-4 py-3">
          <div className="text-sm text-muted-foreground">
            Showing{" "}
            <span className="font-medium">
              {(currentPage - 1) * itemsPerPage + 1}
            </span>{" "}
            to{" "}
            <span className="font-medium">
              {Math.min(currentPage * itemsPerPage, sortedData.length)}
            </span>{" "}
            of <span className="font-medium">{sortedData.length}</span> files
          </div>
          <div className="flex items-center space-x-2">
            <Button
              variant="outline"
              size="sm"
              onClick={goToPrevPage}
              disabled={currentPage === 1}
              className="px-3"
            >
              <ChevronLeft className="h-4 w-4" />
            </Button>

            {/* Always show first page */}
            <Button
              variant="outline"
              size="sm"
              onClick={() => goToPage(1)}
              className={currentPage === 1 ? "bg-blue-500 text-white" : ""}
              disabled={currentPage === 1}
            >
              1
            </Button>

            {/* Show "..." if current page is far from start */}
            {currentPage > 3 && <span className="px-2">...</span>}

            {/* Dynamic page numbers (middle range) */}
            <div className="flex space-x-1">
              {Array.from({ length: Math.min(3, totalPages - 2) }, (_, i) => {
                let page;
                if (currentPage <= 2)
                  page = i + 2; // Near start: 2, 3, 4
                else if (currentPage >= totalPages - 1)
                  page = totalPages - 2 + i; // Near end
                else page = currentPage - 1 + i; // Middle range

                if (page > 1 && page < totalPages) {
                  return (
                    <Button
                      key={page}
                      variant="outline"
                      size="sm"
                      className={
                        currentPage === page ? "bg-blue-500 text-white" : ""
                      }
                      onClick={() => goToPage(page)}
                    >
                      {page}
                    </Button>
                  );
                }
                return null;
              })}
            </div>

            {/* Show "..." if current page is far from end */}
            {currentPage < totalPages - 2 && <span className="px-2">...</span>}

            {/* Always show last page (if different from first) */}
            {totalPages > 1 && (
              <Button
                variant="outline"
                size="sm"
                onClick={() => goToPage(totalPages)}
                disabled={currentPage === totalPages}
                className={
                  currentPage === totalPages ? "bg-blue-500 text-white" : ""
                }
              >
                {totalPages}
              </Button>
            )}

            <Button
              variant="outline"
              size="sm"
              onClick={goToNextPage}
              disabled={currentPage === totalPages || totalPages === 0}
              className="px-3"
            >
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
