"use client";

import { useEffect, useMemo, useRef, useState, useCallback } from "react";
import { createPortal } from "react-dom";
import { toast } from "sonner";
import { useAppDispatch, useAppSelector } from "@/state/hooks";
import {
  fetchUsedProducts,
  fetchProductById,
  deleteProductsAction,
  setPage,
  setLimit,
  setDetailsProduct,
  clearDetailsProduct,
  mapStatusToApi,
} from "@/state/product/productSlice";
import type { UsedProduct } from "@/types/product";
import { useClickOutside } from "@/hooks/useClickOutside";
import { getImageUrl } from "@/lib/imageUrl";
import { formatListingNo } from "@/lib/listingNo";
import DataTable, { type Column } from "../common/DataTable";
import ExportDropdown from "../common/ExportDropdown";
import FiltersDropdown from "../common/FiltersDropdown";
import ProductDetailsDrawer from "../common/ProductDetailsDrawer";
import ProductImage from "../common/ProductImage";
import StatusBadge from "../common/StatusBadge";
import type { ExportColumn } from "../common/export-utils";
import { EyeViewIcon, ExportArrowIcon, KebabIcon, LensThumb, TrashIcon } from "../dashboard/icons";
import DeleteProductModal from "../sellers/DeleteProductModal";

const statusColors: Record<string, { text: string; dot: string }> = {
  Active: { text: "#16A34A", dot: "#16A34A" },
  Inactive: { text: "#667085", dot: "#667085" },
  "Deal Locked": { text: "#7C3AED", dot: "#7C3AED" },
  "Sold Out": { text: "#DC2626", dot: "#DC2626" },
};

const exportColumns: ExportColumn<UsedProduct>[] = [
  { key: "listingNo", label: "Product No.", getValue: (p) => formatListingNo(p.listingNo) },
  { key: "product", label: "Product" },
  { key: "sellerName", label: "Seller" },
  { key: "sellerEmail", label: "Seller Email" },
  { key: "brand", label: "Brand" },
  { key: "category", label: "Category" },
  { key: "price", label: "Price (AUD)" },
  { key: "offers", label: "Offers" },
  { key: "status", label: "Status" },
];

export default function UsedProductsTable() {
  const dispatch = useAppDispatch();
  const {
    items: products,
    loading,
    page,
    limit: pageSize,
    totalPages,
    totalResults,
    detailsProduct,
    deleteLoading,
  } = useAppSelector((state) => state.product);

  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [openMenu, setOpenMenu] = useState<string | null>(null);
  const [exportOpen, setExportOpen] = useState(false);
  const [bulkExportOpen, setBulkExportOpen] = useState(false);
  const [filtersOpen, setFiltersOpen] = useState(false);
  const [deleteIds, setDeleteIds] = useState<string[] | null>(null);

  // Search & filter states
  const [search, setSearch] = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState<string>("All");
  const [filterValues, setFilterValues] = useState<{
    minPrice?: number;
    maxPrice?: number;
    minOffers?: number;
    maxOffers?: number;
  }>({});

  // Debounce search input (350ms)
  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedSearch(search.trim());
      dispatch(setPage(1));
    }, 350);
    return () => clearTimeout(handler);
  }, [search, dispatch]);

  // Load products when page, pageSize, debouncedSearch, or filters change
  const loadData = useCallback(() => {
    dispatch(
      fetchUsedProducts({
        page,
        limit: pageSize,
        search: debouncedSearch || undefined,
        status: mapStatusToApi(statusFilter),
        minPrice: filterValues.minPrice,
        maxPrice: filterValues.maxPrice,
        minOffers: filterValues.minOffers,
        maxOffers: filterValues.maxOffers,
      })
    );
  }, [dispatch, page, pageSize, debouncedSearch, statusFilter, filterValues]);

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

  const selectedProducts = useMemo(
    () => products.filter((product) => selected.has(product.id)),
    [products, selected]
  );

  const handleDeleteConfirm = async () => {
    if (!deleteIds || deleteIds.length === 0) return;
    try {
      await dispatch(deleteProductsAction(deleteIds)).unwrap();
      toast.success(
        deleteIds.length > 1
          ? `${deleteIds.length} products deleted successfully`
          : "Product deleted successfully"
      );
      setSelected((prev) => {
        const next = new Set(prev);
        deleteIds.forEach((id) => next.delete(id));
        return next;
      });
      setDeleteIds(null);
      loadData();
    } catch (err: any) {
      toast.error(err || "Failed to delete product(s)");
    }
  };

  const handleApplyFilters = (
    statusSet: Set<string>,
    ranges: Record<string, { min: number; max: number }>
  ) => {
    const chosenStatus = Array.from(statusSet)[0] || "All";
    setStatusFilter(chosenStatus);
    setFilterValues({
      minPrice: ranges.price?.min,
      maxPrice: ranges.price?.max,
      minOffers: ranges.offers?.min,
      maxOffers: ranges.offers?.max,
    });
    dispatch(setPage(1));
    setFiltersOpen(false);
  };

  const handleClearFilters = () => {
    setStatusFilter("All");
    setFilterValues({});
    dispatch(setPage(1));
    setFiltersOpen(false);
  };

  const handleViewDetails = (product: UsedProduct) => {
    setOpenMenu(null);
    dispatch(setDetailsProduct(product));
    // Fetch complete listing details from backend to ensure all fields/specs are loaded
    dispatch(fetchProductById(product.id));
  };

  const columns: Column<UsedProduct>[] = [
    {
      key: "id",
      label: "ID",
      sortable: true,
      sortValue: (product) => Number(product.listingNo) || 0,
      render: (product) => (
        <span className="text-[14px] font-medium text-[#1657D9]">{formatListingNo(product.listingNo)}</span>
      ),
    },
    {
      key: "product",
      label: "Product",
      render: (product) => {
        return (
          <div className="flex items-center gap-2.5">
            <ProductImage
              src={product.images?.[0]}
              alt={product.product}
              className="h-8 w-8 shrink-0 rounded-lg object-cover border border-[#E4E7EC]"
            />
            <span className="max-w-[200px] truncate text-[14px] font-medium text-[#101828]" title={product.product}>
              {product.product}
            </span>
          </div>
        );
      },
    },
    {
      key: "sellerName",
      label: "Seller",
      sortable: true,
      render: (product) => (
        <div>
          <p className="whitespace-nowrap text-[13px] font-medium text-[#101828]">
            {product.sellerName && product.sellerName !== "Unknown Seller"
              ? product.sellerName
              : "-"}
          </p>
          {product.sellerEmail && product.sellerEmail !== "-" && (
            <p className="whitespace-nowrap text-[12px] text-[#1657D9]">{product.sellerEmail}</p>
          )}
        </div>
      ),
    },
    {
      key: "brand",
      label: "Brand",
      sortable: true,
      render: (product) => <span className="whitespace-nowrap text-[13px] text-[#475467]">{product.brand}</span>,
    },
    {
      key: "category",
      label: "Category",
      sortable: true,
      render: (product) => <span className="whitespace-nowrap text-[13px] text-[#475467]">{product.category}</span>,
    },
    {
      key: "price",
      label: "Price (AUD)",
      sortable: true,
      render: (product) => (
        <span className="whitespace-nowrap text-[13px] font-medium text-[#101828]">{product.price}</span>
      ),
    },
    {
      key: "offers",
      label: "Offers",
      sortable: true,
      render: (product) => <span className="whitespace-nowrap text-[13px] text-[#475467]">{product.offers ?? "-"}</span>,
    },
    {
      key: "status",
      label: "Status",
      sortable: true,
      render: (product) => <StatusBadge status={product.status} colorMap={statusColors} />,
    },
  ];

  return (
    <div className="min-w-0">
      <div>
        <h1 className="text-[20px] font-bold text-[#101828]">Products Management</h1>
        <p className="mt-1 text-[13px] text-[#667085]">
          Manage sellers-listed used products ({totalResults} total)
        </p>
      </div>

      <div className="mt-6">
        <DataTable<UsedProduct>
          columns={columns}
          data={products}
          rowKey={(product) => product.id}
          searchValue={search}
          onSearchChange={setSearch}
          searchPlaceholder="Search by product, brand, seller, or #listing..."
          showFilters
          onFiltersClick={() => setFiltersOpen((prev) => !prev)}
          filtersSlot={
            <FiltersDropdown
              open={filtersOpen}
              onClose={() => setFiltersOpen(false)}
              statusOptions={["All", "Active", "Deal Locked"]}
              initialStatus={new Set([statusFilter])}
              ranges={[
                {
                  key: "price",
                  label: "Price Range",
                  min: 0,
                  max: 10000,
                  initialMin: filterValues.minPrice ?? 0,
                  initialMax: filterValues.maxPrice ?? 10000,
                  format: (value) => `$${value.toFixed(0)}`,
                },
                {
                  key: "offers",
                  label: "Offers Range",
                  min: 0,
                  max: 100,
                  initialMin: filterValues.minOffers ?? 0,
                  initialMax: filterValues.maxOffers ?? 100,
                },
              ]}
              onApply={handleApplyFilters}
              onClear={handleClearFilters}
            />
          }
          showExport
          onExportClick={() => setExportOpen((prev) => !prev)}
          exportSlot={
            <ExportDropdown<UsedProduct>
              open={exportOpen}
              onClose={() => setExportOpen(false)}
              allRows={products}
              selectedRows={selectedProducts}
              columns={exportColumns}
              fileName="used-products"
              title="Used Products Management"
            />
          }
          selectedIds={selected}
          onSelectionChange={setSelected}
          pageSize={pageSize}
          onPageSizeChange={(size) => {
            dispatch(setLimit(size));
          }}
          externalPagination={{
            currentPage: page,
            totalPages: Math.max(1, totalPages),
            onPageChange: (newPage) => dispatch(setPage(newPage)),
          }}
          renderRowActions={(product, index) => (
            <RowActionMenu
              open={openMenu === product.id}
              onToggle={() => setOpenMenu(openMenu === product.id ? null : product.id)}
              onClose={() => setOpenMenu(null)}
              onViewDetails={() => handleViewDetails(product)}
              onDelete={() => {
                setOpenMenu(null);
                setDeleteIds([product.id]);
              }}
              isNearBottom={index >= Math.max(0, products.length - 2)}
            />
          )}
          renderBulkActionBar={() => (
            <>
              <button
                type="button"
                onClick={() => setDeleteIds(Array.from(selected))}
                className="flex h-9 items-center gap-2 rounded-lg border border-[#DC2626] bg-white px-4 text-[13px] font-medium text-[#DC2626] transition-colors hover:bg-red-50"
              >
                <TrashIcon />
                Delete Products ({selected.size})
              </button>
              <div className="relative">
                <button
                  type="button"
                  onClick={() => setBulkExportOpen((prev) => !prev)}
                  className="flex h-9 items-center gap-2 rounded-lg border border-[#1657D9] bg-white px-4 text-[13px] font-medium text-[#1657D9] transition-colors hover:bg-blue-50"
                >
                  <ExportArrowIcon />
                  Export Selection
                </button>
                <ExportDropdown<UsedProduct>
                  open={bulkExportOpen}
                  onClose={() => setBulkExportOpen(false)}
                  allRows={products}
                  selectedRows={selectedProducts}
                  columns={exportColumns}
                  fileName="used-products-selection"
                  title="Products Management"
                />
              </div>
            </>
          )}
        />
      </div>

      <ProductDetailsDrawer
        product={detailsProduct}
        open={detailsProduct !== null}
        onClose={() => dispatch(clearDetailsProduct())}
        footer={
          <div className="flex items-center justify-end gap-4">
            <button
              type="button"
              onClick={() => dispatch(clearDetailsProduct())}
              className="text-[13px] font-medium text-[#344054] hover:text-[#101828]"
            >
              Close
            </button>
            <button
              type="button"
              onClick={() => {
                if (detailsProduct) {
                  setDeleteIds([detailsProduct.id]);
                }
              }}
              className="rounded-lg bg-[#DC2626] px-5 py-2.5 text-[13px] font-medium text-white transition-colors hover:bg-[#B91C1C]"
            >
              Delete Ad
            </button>
          </div>
        }
      />

      <DeleteProductModal
        open={deleteIds !== null}
        count={deleteIds?.length ?? 0}
        loading={deleteLoading}
        onClose={() => setDeleteIds(null)}
        onConfirm={handleDeleteConfirm}
        noun="Ad"
      />
    </div>
  );
}

function RowActionMenu({
  open,
  onToggle,
  onClose,
  onViewDetails,
  onDelete,
}: {
  open: boolean;
  onToggle: () => void;
  onClose: () => void;
  onViewDetails: () => void;
  onDelete: () => void;
  isNearBottom?: boolean;
}) {
  const triggerRef = useRef<HTMLButtonElement | null>(null);
  const menuRef = useRef<HTMLDivElement | null>(null);
  const [mounted, setMounted] = useState(false);
  const [coords, setCoords] = useState<{ top: number; left: number } | null>(null);

  useEffect(() => {
    setMounted(true);
  }, []);

  const updatePosition = useCallback(() => {
    if (!triggerRef.current) return;
    const rect = triggerRef.current.getBoundingClientRect();
    const menuHeight = 90;
    const menuWidth = 170;

    const spaceBelow = window.innerHeight - rect.bottom;
    const spaceAbove = rect.top;

    let top: number;
    if (spaceBelow < menuHeight + 10 && spaceAbove >= menuHeight) {
      top = rect.top - menuHeight - 4;
    } else {
      top = rect.bottom + 4;
    }

    let left = rect.right - menuWidth;
    if (left < 10) left = 10;
    if (left + menuWidth > window.innerWidth - 10) {
      left = window.innerWidth - menuWidth - 10;
    }

    setCoords({ top, left });
  }, []);

  useEffect(() => {
    if (open) {
      updatePosition();

      const handlePointerDown = (event: MouseEvent) => {
        const target = event.target as Node;
        if (
          triggerRef.current?.contains(target) ||
          menuRef.current?.contains(target)
        ) {
          return;
        }
        onClose();
      };

      const handleScroll = (event: Event) => {
        if (menuRef.current?.contains(event.target as Node)) return;
        onClose();
      };

      document.addEventListener("mousedown", handlePointerDown);
      window.addEventListener("scroll", handleScroll, true);
      window.addEventListener("resize", onClose);

      return () => {
        document.removeEventListener("mousedown", handlePointerDown);
        window.removeEventListener("scroll", handleScroll, true);
        window.removeEventListener("resize", onClose);
      };
    }
  }, [open, onClose, updatePosition]);

  return (
    <>
      <button
        ref={triggerRef}
        type="button"
        onClick={onToggle}
        className="flex h-7 w-7 items-center justify-center rounded-full text-[#667085] transition-colors hover:bg-[#F2F4F7] cursor-pointer"
      >
        <KebabIcon />
      </button>
      {open && mounted && coords && createPortal(
        <div
          ref={menuRef}
          style={{
            position: "fixed",
            top: `${coords.top}px`,
            left: `${coords.left}px`,
            zIndex: 9999,
          }}
          className="min-w-[170px] rounded-lg border border-[#E4E7EC] bg-white py-1.5 shadow-[0_10px_24px_rgba(15,23,42,0.18)]"
        >
          <button
            type="button"
            onClick={onViewDetails}
            className="flex w-full items-center gap-2.5 whitespace-nowrap px-3.5 py-2 text-left text-[13px] font-medium text-[#344054] hover:bg-[#F5F7F9] cursor-pointer"
          >
            <EyeViewIcon />
            View Details
          </button>
          <button
            type="button"
            onClick={onDelete}
            className="flex w-full items-center gap-2.5 whitespace-nowrap px-3.5 py-2 text-left text-[13px] font-medium text-[#DC2626] hover:bg-[#F5F7F9] cursor-pointer"
          >
            <TrashIcon />
            Delete Ad
          </button>
        </div>,
        document.body
      )}
    </>
  );
}

