import * as React from "react";
import { useQuery } from "@tanstack/react-query";
import { useSearchParams } from "react-router-dom";
import { Loader2 } from "lucide-react";
import { ProductFilterOptions, ProductMetric, ProductMetricColumnKey } from "@/types/products";
import { ProductTable } from "./ProductTable";
import { ProductFilters } from "./ProductFilters";
import { ProductDetail } from "./ProductDetail";
import config from "@/config";
import { getProductStatus } from "@/utils/productUtils";

export function Products() {
  const [searchParams, setSearchParams] = useSearchParams();
  const [selectedProductId, setSelectedProductId] = React.useState<number | null>(null);
  
  // Get current filter values from URL params
  const currentPage = Number(searchParams.get("page") || "1");
  const pageSize = Number(searchParams.get("pageSize") || "25");
  const sortBy = searchParams.get("sortBy") || "title";
  const sortDirection = searchParams.get("sortDirection") || "asc";
  const filterType = searchParams.get("filterType") || "";
  const filterValue = searchParams.get("filterValue") || "";
  const searchQuery = searchParams.get("search") || "";
  const statusFilter = searchParams.get("status") || "";

  // Fetch filter options
  const { 
    data: filterOptions, 
    isLoading: isLoadingOptions 
  } = useQuery<ProductFilterOptions>({
    queryKey: ["productFilterOptions"],
    queryFn: async () => {
      const response = await fetch(`${config.apiUrl}/metrics/filter-options`, {
        credentials: 'include',
      });
      
      if (!response.ok) {
        return { vendors: [], brands: [], abcClasses: [] };
      }
      
      return await response.json();
    },
    initialData: { vendors: [], brands: [], abcClasses: [] }, // Provide initial data to prevent undefined
  });

  // Fetch products with metrics data
  const { 
    data, 
    isLoading, 
    error 
  } = useQuery<{ products: ProductMetric[], total: number }>({
    queryKey: ["products", currentPage, pageSize, sortBy, sortDirection, filterType, filterValue, searchQuery, statusFilter],
    queryFn: async () => {
      // Build query parameters
      const params = new URLSearchParams();
      params.append("page", currentPage.toString());
      params.append("limit", pageSize.toString());
      
      if (sortBy) params.append("sortBy", sortBy);
      if (sortDirection) params.append("sortDirection", sortDirection);
      if (filterType && filterValue) {
        params.append("filterType", filterType);
        params.append("filterValue", filterValue);
      }
      if (searchQuery) params.append("search", searchQuery);
      if (statusFilter) params.append("status", statusFilter);

      const response = await fetch(`${config.apiUrl}/metrics?${params.toString()}`, {
        credentials: 'include',
      });
      
      if (!response.ok) {
        const errorData = await response.json().catch(() => ({}));
        throw new Error(errorData.error || `Failed to fetch products (${response.status})`);
      }
      
      const data = await response.json();

      // Calculate status for each product
      const productsWithStatus = data.products.map((product: ProductMetric) => ({
        ...product,
        status: getProductStatus(product)
      }));
      
      return {
        products: productsWithStatus,
        total: data.total
      };
    },
  });


  const handleSortChange = (field: string, direction: "asc" | "desc") => {
    searchParams.set("sortBy", field);
    searchParams.set("sortDirection", direction);
    setSearchParams(searchParams);
  };

  const handleSort = (column: ProductMetricColumnKey) => {
    // Toggle sort direction if same column, otherwise default to asc
    const newDirection = sortBy === column && sortDirection === "asc" ? "desc" : "asc";
    handleSortChange(column, newDirection as "asc" | "desc");
  };

  const handleViewProduct = (id: number) => {
    setSelectedProductId(id);
  };

  const handleCloseProductDetail = () => {
    setSelectedProductId(null);
  };

  // Create a wrapper function to handle all filter changes
  const handleFiltersChange = (filters: Record<string, any>) => {
    // Reset to first page when applying filters
    searchParams.set("page", "1");
    
    // Update searchParams with all filters
    Object.entries(filters).forEach(([key, value]) => {
      if (value) {
        searchParams.set(key, String(value));
      } else {
        searchParams.delete(key);
      }
    });
    
    setSearchParams(searchParams);
  };

  // Clear all filters
  const handleClearFilters = () => {
    // Keep only pagination and sorting params
    const newParams = new URLSearchParams();
    newParams.set("page", "1");
    newParams.set("pageSize", pageSize.toString());
    newParams.set("sortBy", sortBy);
    newParams.set("sortDirection", sortDirection);
    setSearchParams(newParams);
  };

  // Current active filters
  const activeFilters = React.useMemo(() => {
    const filters: Record<string, any> = {};
    
    if (filterType && filterValue) {
      filters[filterType] = filterValue;
    }
    
    if (searchQuery) {
      filters.search = searchQuery;
    }
    
    if (statusFilter) {
      filters.status = statusFilter;
    }
    
    return filters;
  }, [filterType, filterValue, searchQuery, statusFilter]);

  return (
    <div className="flex-1 space-y-4 p-4 md:p-8 pt-6">
      <div className="flex items-center justify-between">
        <h2 className="text-3xl font-bold tracking-tight">Products</h2>
      </div>
      
      <ProductFilters
        filterOptions={filterOptions || { vendors: [], brands: [], abcClasses: [] }}
        isLoadingOptions={isLoadingOptions}
        onFilterChange={handleFiltersChange}
        onClearFilters={handleClearFilters}
        activeFilters={activeFilters}
      />

      {isLoading ? (
        <div className="flex justify-center items-center min-h-[300px]">
          <div className="flex items-center gap-2">
            <Loader2 className="h-6 w-6 animate-spin" />
            <span>Loading products...</span>
          </div>
        </div>
      ) : error ? (
        <div className="bg-destructive/10 p-4 rounded-lg text-center text-destructive border border-destructive">
          Error loading products: {(error as Error).message}
        </div>
      ) : (
        <ProductTable
          products={data?.products || []}
          onViewProduct={handleViewProduct}
          isLoading={isLoading}
          onSort={handleSort}
          sortColumn={sortBy as ProductMetricColumnKey}
          sortDirection={sortDirection as "asc" | "desc"}
          columnDefs={[
            { key: 'title', label: 'Name', group: 'Product' },
            { key: 'brand', label: 'Brand', group: 'Product' },
            { key: 'sku', label: 'SKU', group: 'Product' },
            { key: 'currentStock', label: 'Stock', group: 'Inventory' },
            { key: 'currentPrice', label: 'Price', group: 'Pricing' },
            { key: 'status', label: 'Status', group: 'Product' }
          ]}
        />
      )}

      <ProductDetail 
        productId={selectedProductId} 
        onClose={handleCloseProductDetail} 
      />
    </div>
  );
} 