"use client";

import React, { useEffect, useState, useCallback } from "react";
import Link from "next/link";
import { purchaseOrderService } from "../../../services/api";
import {
  PurchaseOrder,
  PurchaseOrderStatus,
} from "../../../types/purchase-order";
import { MdAdd, MdSearch, MdFilterList, MdEvent } from "react-icons/md";
import PurchaseTable from "./components/PurchaseTable";
import ConfirmationModal from "../../../components/ui/ConfirmationModal";
import toast from "react-hot-toast";
import { toastMessages } from "../../../utils/toast";
import { useRouter, useSearchParams } from "next/navigation";
import { debounce } from "lodash";
import FilterPopover from "./components/FilterPopover";
import DateFilterPopover from "./components/DateFilterPopover";
import { PaginationMeta } from "@/types/pagination";

export default function PurchaseOrdersPage() {
  const router = useRouter();
  const searchParams = useSearchParams();

  // Get initial values from URL query params
  const initialPage = Number(searchParams.get("page")) || 1;
  const initialLimit = Number(searchParams.get("limit")) || 10;
  const initialSearch = searchParams.get("search") || "";
  const initialStatus = searchParams.get("status") || null;
  const initialProducts = searchParams.get("products")
    ? searchParams.get("products")!.split(",").map(Number)
    : [];
  const initialStartDate = searchParams.get("startDate") || null;
  const initialEndDate = searchParams.get("endDate") || null;
  const initialSortBy = searchParams.get("sortBy") || "createdAt";
  const initialSortOrder =
    (searchParams.get("sortOrder") as "ASC" | "DESC") || "DESC";

  const [purchaseOrders, setPurchaseOrders] = useState<PurchaseOrder[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(initialPage);
  const [itemsPerPage, setItemsPerPage] = useState(initialLimit);
  const [searchQuery, setSearchQuery] = useState(initialSearch);
  const [filterStatus, setFilterStatus] = useState<string | null>(
    initialStatus
  );
  const [filterProducts, setFilterProducts] =
    useState<number[]>(initialProducts);
  const [startDate, setStartDate] = useState<string | null>(initialStartDate);
  const [endDate, setEndDate] = useState<string | null>(initialEndDate);
  const [sortBy, setSortBy] = useState<string>(initialSortBy);
  const [sortOrder, setSortOrder] = useState<"ASC" | "DESC">(initialSortOrder);
  const [isFilterOpen, setIsFilterOpen] = useState(false);
  const [isDateFilterOpen, setIsDateFilterOpen] = useState(false);

  const [paginationMeta, setPaginationMeta] = useState<PaginationMeta>({
    currentPage: initialPage,
    itemsPerPage: initialLimit,
    totalItems: 0,
    totalPages: 1,
    hasNextPage: false,
    hasPreviousPage: false,
  });
  const [deleteModalOpen, setDeleteModalOpen] = useState(false);
  const [orderToDelete, setOrderToDelete] = useState<number | null>(null);
  const [orderDetails, setOrderDetails] = useState<{
    orderNumber: string;
    products: string;
  }>({
    orderNumber: "",
    products: "",
  });

  // Update URL with current pagination and filter state
  const updateUrlParams = useCallback(() => {
    const params = new URLSearchParams();
    params.set("page", currentPage.toString());
    params.set("limit", itemsPerPage.toString());
    if (searchQuery) params.set("search", searchQuery);
    if (filterStatus) params.set("status", filterStatus);
    if (filterProducts.length > 0)
      params.set("products", filterProducts.join(","));
    if (startDate) params.set("startDate", startDate);
    if (endDate) params.set("endDate", endDate);
    if (sortBy) params.set("sortBy", sortBy);
    if (sortOrder) params.set("sortOrder", sortOrder);

    // Update URL without refreshing the page
    router.push(`?${params.toString()}`, { scroll: false });
  }, [
    currentPage,
    itemsPerPage,
    searchQuery,
    filterStatus,
    filterProducts,
    startDate,
    endDate,
    sortBy,
    sortOrder,
    router,
  ]);

  // Fetch purchase orders with filters
  const fetchPurchaseOrders = useCallback(async () => {
    try {
      setLoading(true);

      const response = await purchaseOrderService.getAllPurchaseOrders({
        page: currentPage,
        limit: itemsPerPage,
        search: searchQuery,
        status: filterStatus || undefined,
        products: filterProducts.length > 0 ? filterProducts : undefined,
        startDate: startDate || undefined,
        endDate: endDate || undefined,
        sortBy,
        sortOrder,
      });

      setPurchaseOrders(response.data.data);
      setPaginationMeta(response.data.meta);
      setError(null);

      // Update URL after successful fetch
      updateUrlParams();
    } catch (err) {
      console.error("Failed to fetch purchase orders:", err);
      setError("Failed to load purchase orders. Please try again.");
    } finally {
      setLoading(false);
    }
  }, [
    currentPage,
    itemsPerPage,
    searchQuery,
    filterStatus,
    filterProducts,
    startDate,
    endDate,
    sortBy,
    sortOrder,
    updateUrlParams,
  ]);

  // Debounced search handler
  const debouncedSearch = useCallback(
    debounce((value: string) => {
      setSearchQuery(value);
      setCurrentPage(1); // Reset to first page on new search
    }, 500),
    []
  );

  useEffect(() => {
    return () => {
      debouncedSearch.cancel();
    };
  }, [debouncedSearch]);

  // Handle search input change
  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    debouncedSearch(value);
  };

  // Handle filter toggle
  const handleFilterToggle = () => {
    setIsFilterOpen(!isFilterOpen);
  };

  // Handle date filter toggle
  const handleDateFilterToggle = () => {
    setIsDateFilterOpen(!isDateFilterOpen);
  };

  // Handle filter apply
  const handleFilterApply = ({
    status,
    products,
  }: {
    status: string | null;
    products: number[];
  }) => {
    setFilterStatus(status);
    setFilterProducts(products);
    setCurrentPage(1); // Reset to first page when applying filters
  };

  // Handle date filter apply
  const handleDateFilterApply = (start: string | null, end: string | null) => {
    setStartDate(start);
    setEndDate(end);
    setCurrentPage(1); // Reset to first page when applying date filters
  };

  // Handle sorting
  const handleSort = (field: string) => {
    if (sortBy === field) {
      // Toggle sort order if same field
      setSortOrder(sortOrder === "ASC" ? "DESC" : "ASC");
    } else {
      // Set new field with default DESC order
      setSortBy(field);
      setSortOrder("DESC");
    }
    setCurrentPage(1); // Reset to first page when sorting
  };

  // Set up page change handlers
  const handlePageChange = (page: number) => {
    setCurrentPage(page);
  };

  const handleItemsPerPageChange = (size: number) => {
    setItemsPerPage(size);
    setCurrentPage(1); // Reset to first page when changing items per page
  };

  // Fetch data on initial load and whenever dependencies change
  useEffect(() => {
    fetchPurchaseOrders();
  }, [fetchPurchaseOrders]);

  const handleDeleteOrder = async (id: string | number) => {
    // Clear any previous delete errors and success messages
    toast.remove();

    // Convert id to number if it's a string
    const orderId = typeof id === "string" ? parseInt(id, 10) : id;

    // Find the order details before opening the modal
    const orderToDeleteDetails = purchaseOrders.find(
      (order) => order.id === orderId
    );

    // Prepare the details for the modal
    if (orderToDeleteDetails) {
      const orderNumber = orderToDeleteDetails.orderNumber || "Unknown";

      let productsList = "with no products";
      if (orderToDeleteDetails.items && orderToDeleteDetails.items.length > 0) {
        productsList = `with products: ${orderToDeleteDetails.items
          .map((item) => item?.product?.name || "Unknown Product")
          .join(", ")}`;
      }

      setOrderDetails({
        orderNumber,
        products: productsList,
      });
    } else {
      // If we can't find the order, try to get it from the API directly
      try {
        const response = await purchaseOrderService.getPurchaseOrder(orderId);
        const fetchedOrder = response.data;

        if (fetchedOrder) {
          const orderNumber = fetchedOrder.orderNumber || "Unknown";

          let productsList = "with no products";
          if (fetchedOrder.items && fetchedOrder.items.length > 0) {
            productsList = `with products: ${fetchedOrder.items
              .map((item: any) => item?.product?.name || "Unknown Product")
              .join(", ")}`;
          }

          setOrderDetails({
            orderNumber,
            products: productsList,
          });
        } else {
          setOrderDetails({
            orderNumber: "Unknown",
            products: "with unknown products",
          });
        }
      } catch (fetchErr) {
        console.error("Failed to fetch individual order:", fetchErr);
        setOrderDetails({
          orderNumber: "Unknown",
          products: "with unknown products",
        });
      }
    }

    // Set the ID and open the modal
    setOrderToDelete(orderId);
    setDeleteModalOpen(true);
  };

  // Handle confirm button click - prevent modal auto-close
  const handleConfirmDelete = async () => {
    if (orderToDelete === null) return;

    try {
      await purchaseOrderService.deletePurchaseOrder(orderToDelete);
      // Refresh the list after deletion
      fetchPurchaseOrders();
      // Show success message
      toast.success(toastMessages.delete.success("Purchase order"));
      // Close modal on successful deletion but keep the success message
      closeDeleteModalOnSuccess();
    } catch (err: any) {
      console.error("Failed to delete purchase order:", err);

      // Extract specific error message from the response
      let errorMessage = toastMessages.delete.error("purchase order");

      if (err.response?.data?.message) {
        errorMessage = err.response.data.message;
      } else if (err.response?.status === 400) {
        errorMessage =
          "Cannot delete this purchase order. Purchase orders with 'fulfilled' status cannot be deleted.";
      } else if (err.message) {
        errorMessage = err.message;
      }

      toast.error(errorMessage);
      // Close modal but don't clear the error - let the toast show
      closeDeleteModalOnly();
    }
  };

  // Close delete modal only (without clearing errors)
  const closeDeleteModalOnly = () => {
    setDeleteModalOpen(false);
    setOrderToDelete(null);
  };

  // Close delete modal after successful deletion (keep success message)
  const closeDeleteModalOnSuccess = () => {
    setDeleteModalOpen(false);
    setOrderToDelete(null);
    // Don't clear toast - let the success message show
  };

  // Close delete modal and clear all states (including errors and success)
  const closeDeleteModal = () => {
    setDeleteModalOpen(false);
    toast.remove();
    setOrderToDelete(null);
  };

  // Prepare the modal description
  const getModalDescription = () => {
    return `Order #${orderDetails.orderNumber}\n${orderDetails.products}`;
  };

  // Get filter badge count
  const getFilterCount = () => {
    let count = 0;
    if (filterStatus) count++;
    if (filterProducts.length > 0) count++;
    return count;
  };

  // Get date filter badge count
  const getDateFilterCount = () => {
    return startDate || endDate ? 1 : 0;
  };

  return (
    <div className="purchase-orders-page">
      {/* Sticky Header */}
      <div className="sticky top-0 z-30 bg-gradient-to-l from-white to-[#DFF9FF] shadow-sm border-b border-gray-200 backdrop-blur-sm">
        <div className="px-4 md:px-6 py-4">
          <div className="flex flex-col sm:flex-row sm:justify-between sm:items-center space-y-4 sm:space-y-0">
            <div>
              <h1 className="text-xl md:text-2xl font-bold text-gray-800">
                Manage Purchase
              </h1>
            </div>
            <Link
              href="/purchase-orders/create"
              className="bg-[#3997E0] text-white py-2 px-4 rounded-xl hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 flex items-center justify-center sm:justify-start w-full sm:w-auto"
            >
              <MdAdd size={20} className="mr-2" />
              Create Purchase
            </Link>
          </div>
        </div>
      </div>

      {/* Main Content */}
      <div className="m-4 md:m-6">
        {/* Single Card for Purchase List, Search/Filters, Table, and Pagination */}
        <div className="bg-white rounded-lg shadow-[0px_4px_34px_0px_rgba(0,59,113,0.16)]">
          {/* Purchase List Title */}
          <div className="px-6 py-4 border-b border-gray-200">
            <h2 className="text-lg font-bold text-gray-800">Purchase List</h2>
          </div>

          {/* Search and Filters */}
          <div className="p-4 md:p-6 flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0 md:space-x-4">
            <div className="flex items-center bg-gray-100 p-2 rounded-md w-full md:w-1/3">
              <MdSearch size={20} color="#6B7280" className="mr-2" />
              <input
                type="text"
                placeholder="Search..."
                defaultValue={searchQuery}
                onChange={handleSearchChange}
                className="bg-transparent outline-none w-full text-sm text-gray-700 placeholder-gray-500"
              />
            </div>
            <div className="flex items-center space-x-4">
              <button
                className="flex items-center text-gray-600 hover:text-gray-800 text-sm bg-gray-100 p-2 rounded-md relative"
                onClick={handleFilterToggle}
              >
                <MdFilterList size={20} className="mr-2" />
                Filters
                {getFilterCount() > 0 && (
                  <span className="absolute -top-2 -right-2 bg-blue-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center">
                    {getFilterCount()}
                  </span>
                )}
              </button>
              <button
                className="flex items-center text-gray-600 hover:text-gray-800 text-sm bg-gray-100 p-2 rounded-md relative"
                onClick={handleDateFilterToggle}
              >
                <MdEvent size={20} className="mr-2" />
                Date Filter
                {getDateFilterCount() > 0 && (
                  <span className="absolute -top-2 -right-2 bg-blue-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center">
                    {getDateFilterCount()}
                  </span>
                )}
              </button>
            </div>
          </div>

          {loading ? (
            <div className="flex justify-center items-center h-40">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mr-3"></div>
              <span>Loading purchase orders...</span>
            </div>
          ) : error ? (
            <div className="p-6 bg-red-100 text-red-700">
              <p className="font-medium">Error</p>
              <p>{error}</p>
            </div>
          ) : purchaseOrders.length === 0 ? (
            <div className="p-6 text-center">
              <p className="text-gray-500">No purchase orders found.</p>
              <Link
                href="/purchase-orders/create"
                className="mt-4 inline-block text-blue-600 hover:text-blue-800 font-medium"
              >
                Create your first purchase order
              </Link>
            </div>
          ) : (
            <PurchaseTable
              data={purchaseOrders}
              currentPage={currentPage}
              setCurrentPage={handlePageChange}
              pageSize={itemsPerPage}
              setPageSize={handleItemsPerPageChange}
              onDeleteOrder={handleDeleteOrder}
              totalItems={paginationMeta.totalItems}
              totalPages={paginationMeta.totalPages}
              sortBy={sortBy}
              sortOrder={sortOrder}
              onSort={handleSort}
            />
          )}
        </div>
      </div>

      {/* Filter Popover */}
      <FilterPopover
        isOpen={isFilterOpen}
        onClose={() => setIsFilterOpen(false)}
        onApply={handleFilterApply}
        initialFilters={{
          status: filterStatus,
          products: filterProducts,
        }}
      />

      {/* Date Filter Popover */}
      <DateFilterPopover
        isOpen={isDateFilterOpen}
        onClose={() => setIsDateFilterOpen(false)}
        onApply={handleDateFilterApply}
        initialStartDate={startDate}
        initialEndDate={endDate}
      />

      {/* Delete Confirmation Modal */}
      <ConfirmationModal
        isOpen={deleteModalOpen}
        onClose={closeDeleteModal}
        onConfirm={handleConfirmDelete}
        title="Delete Purchase Order?"
        description={getModalDescription()}
        iconContainerColor="#FFE5E5"
        iconColor="#0F2851"
        confirmText="Yes"
        cancelText="No"
      />
    </div>
  );
}
