"use client";

import { useState, useEffect, ChangeEvent, Suspense } from "react";
import { useRouter } from "next/navigation";
import Layout from "@/components/layout/layout";
import { Button } from "@/components/common/button";
import { Input } from "@/components/common/input";
import { Product } from "@/lib/models/products";
import { Plus, Upload, Search, RefreshCw, Package2 } from "lucide-react";
import { clientFetch } from "@/lib/api";
import { Category } from "@/lib/models/categories";
import { toast } from "sonner";
import dynamic from "next/dynamic";
import { Skeleton } from "@/components/common/skeleton";
import { Card, CardContent, CardHeader } from "@/components/common/card";

// Lazy load heavy components with error handling
const ProductTable = dynamic(() => import("@/components/tables/product-table").catch((err) => {
  console.error("Failed to load ProductTable:", err);
  throw err;
}), {
  loading: () => <ProductTableSkeleton />
});

const ProductModal = dynamic(() => import("@/components/modals/product-modal").then(mod => ({ default: mod.ProductModal })).catch((err) => {
  console.error("Failed to load ProductModal:", err);
  throw err;
}), {
  loading: () => <ModalSkeleton />
});

const ImportProductsModal = dynamic(() => import("@/components/modals/import-products-modal").catch((err) => {
  console.error("Failed to load ImportProductsModal:", err);
  throw err;
}), {
  loading: () => <ModalSkeleton />
});

const ProfitAnalysisModal = dynamic(() => import("@/components/modals/profit-analysis-modal").then(mod => ({ default: mod.ProfitAnalysisModal })).catch((err) => {
  console.error("Failed to load ProfitAnalysisModal:", err);
  throw err;
}), {
  loading: () => <ModalSkeleton />
});

function ProductTableSkeleton() {
  return (
    <Card className="animate-in fade-in duration-500 border-border/40 bg-background/50 backdrop-blur-sm shadow-sm">
      <CardHeader>
        <div className="flex items-center justify-between">
          <Skeleton className="h-6 w-32" />
          <div className="flex gap-2">
            <Skeleton className="h-9 w-24 rounded-md" />
            <Skeleton className="h-9 w-32 rounded-md" />
          </div>
        </div>
      </CardHeader>
      <CardContent>
        <div className="border rounded-lg">
          <div className="border-b p-4">
            <div className="flex items-center gap-4">
              {['Product', 'Category', 'Price', 'Stock', 'Status', 'Actions'].map((header, i) => (
                <Skeleton
                  key={i}
                  className="h-4 w-20 flex-1 animate-in fade-in"
                  style={{
                    animationDelay: `${i * 50}ms`,
                    animationDuration: '300ms',
                    animationFillMode: 'both',
                  }}
                />
              ))}
            </div>
          </div>

          {[...Array(8)].map((_, i) => (
            <div
              key={i}
              className="border-b last:border-b-0 p-4 animate-in fade-in"
              style={{
                animationDelay: `${300 + i * 50}ms`,
                animationDuration: '300ms',
                animationFillMode: 'both',
              }}
            >
              <div className="flex items-center gap-4">
                <div className="flex items-center gap-3 flex-1">
                  <Skeleton className="h-12 w-12 rounded-md" />
                  <div className="space-y-1">
                    <Skeleton className="h-4 w-32" />
                    <Skeleton className="h-3 w-24" />
                  </div>
                </div>
                <Skeleton className="h-4 w-24 flex-1" />
                <Skeleton className="h-4 w-16 flex-1" />
                <Skeleton className="h-4 w-16 flex-1" />
                <Skeleton className="h-6 w-20 flex-1 rounded-full" />
                <div className="flex gap-2 flex-1">
                  <Skeleton className="h-8 w-16 rounded-md" />
                  <Skeleton className="h-8 w-16 rounded-md" />
                </div>
              </div>
            </div>
          ))}
        </div>
      </CardContent>
    </Card>
  );
}

function ModalSkeleton() {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm">
      <Card className="w-full max-w-2xl m-4 animate-in fade-in zoom-in-95 duration-300">
        <CardHeader>
          <Skeleton className="h-6 w-48" />
          <Skeleton className="h-4 w-64 mt-2" />
        </CardHeader>
        <CardContent>
          <div className="space-y-4">
            {[...Array(5)].map((_, i) => (
              <div key={i} className="space-y-2">
                <Skeleton className="h-4 w-24" />
                <Skeleton className="h-10 w-full rounded-md" />
              </div>
            ))}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

export default function ProductsPage() {
  const router = useRouter();
  const [products, setProducts] = useState<Product[]>([]);
  const [categories, setCategories] = useState<Category[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [modalOpen, setModalOpen] = useState<boolean>(false);
  const [editing, setEditing] = useState<boolean>(false);
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const [searchTerm, setSearchTerm] = useState<string>("");
  const [productData, setProductData] = useState<Product>({
    name: "",
    description: "",
    unitType: "pcs",
    category: "",
    pricing: [{ minQuantity: 1, pricePerUnit: 0 }],
    image: null,
    costPerUnit: 0,
  });
  const [importModalOpen, setImportModalOpen] = useState(false);
  const [addProductOpen, setAddProductOpen] = useState(false);
  const [profitAnalysisOpen, setProfitAnalysisOpen] = useState(false);
  const [selectedProductForAnalysis, setSelectedProductForAnalysis] = useState<{ id: string, name: string } | null>(null);

  // Fetch products and categories
  useEffect(() => {
    const fetchDataAsync = async () => {
      try {
        setLoading(true);

        const [fetchedProducts, fetchedCategories] = await Promise.all([
          clientFetch('/products'),
          clientFetch('/categories'),
        ]);

        console.log("Fetched Products:", fetchedProducts);

        // Ensure all products have tieredPricing
        const processedProducts = fetchedProducts.map((product: Product) => ({
          ...product,
          pricing: product.pricing || [{ minQuantity: 1, pricePerUnit: 0 }],
        }));

        setProducts(processedProducts);
        setCategories(fetchedCategories);
        setLoading(false);
      } catch (error) {
        console.error("Error fetching data:", error);
        toast.error("Failed to load products");
        setLoading(false);
      }
    };

    fetchDataAsync();
  }, []);

  const handleAddTier = () => {
    setProductData((prev) => ({
      ...prev,
      pricing: [...prev.pricing, { minQuantity: 1, pricePerUnit: 0 }],
    }));
  };

  const handleRemoveTier = (index: number) => {
    setProductData((prev) => ({
      ...prev,
      pricing: prev.pricing.filter((_, i) => i !== index),
    }));
  };

  // Handle input changes
  const handleChange = (
    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => setProductData({ ...productData, [e.target.name]: e.target.value });

  // Handle tiered pricing changes
  const handleTieredPricingChange = (
    e: ChangeEvent<HTMLInputElement>,
    index: number
  ) => {
    const updatedPricing = [...productData.pricing];
    const name = e.target.name as "minQuantity" | "pricePerUnit";
    updatedPricing[index][name] = e.target.valueAsNumber || 0;
    setProductData({ ...productData, pricing: updatedPricing });
  };


  const handleSaveProduct = async (data: Product, file?: File | null) => {
    try {
      setLoading(true);

      if (editing && !data._id) {
        throw new Error("Cannot update product without an ID");
      }

      // Prepare the product data with stock management fields
      const productData = {
        ...data,
        stockTracking: data.stockTracking ?? true,
        currentStock: data.currentStock ?? 0,
        lowStockThreshold: data.lowStockThreshold ?? 10,
        stockStatus: data.stockStatus ?? 'out_of_stock'
      };

      // Save the product data
      const endpoint = editing ? `/products/${data._id}` : "/products";
      const method = editing ? "PUT" : "POST";

      const productResponse = await clientFetch(endpoint, {
        method,
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(productData),
      });

      // If there's a new image to upload
      if (file) {
        const imageEndpoint = `/products/${productResponse._id || data._id}/image`;

        const formData = new FormData();
        formData.append("file", file);

        await fetch(`${process.env.NEXT_PUBLIC_API_URL}${imageEndpoint}`, {
          method: "PUT",
          headers: {
            Authorization: `Bearer ${document.cookie
              .split("; ")
              .find((row) => row.startsWith("Authorization="))
              ?.split("=")[1]}`,
          },
          body: formData,
          credentials: "include",
        });
      }

      // Refresh products list
      const fetchedProducts = await clientFetch('/products');
      setProducts(fetchedProducts);

      setModalOpen(false);
      setLoading(false);

      toast.success(
        editing ? "Product updated successfully" : "Product added successfully"
      );
    } catch (error) {
      console.error(error);
      setLoading(false);
      toast.error("Failed to save product");
    }
  };

  // Handle delete product
  const handleDeleteProduct = async (productId: string) => {
    if (!confirm("Are you sure you want to delete this product?")) return;

    try {
      setLoading(true);

      await clientFetch(`/products/${productId}`, {
        method: "DELETE",
      });

      // Refresh products list
      const fetchedProducts = await clientFetch('/products');
      setProducts(fetchedProducts);

      toast.success("Product deleted successfully");
      setLoading(false);
    } catch (error) {
      console.error(error);
      toast.error("Failed to delete product");
      setLoading(false);
    }
  };

  // Edit product
  const handleEditProduct = (product: Product) => {
    setProductData({
      ...product,
      pricing: product.pricing
        ? product.pricing.map((tier) => ({
          minQuantity: tier.minQuantity,
          pricePerUnit: tier.pricePerUnit,
        }))
        : [{ minQuantity: 1, pricePerUnit: 0 }],
      costPerUnit: product.costPerUnit || 0,
    });
    setEditing(true);
    setAddProductOpen(true);
  };

  // Clone product - opens modal with product data but as a new product
  const handleCloneProduct = (product: Product) => {
    // Clone the product but remove _id and image to make it a new product
    const clonedProduct: Product = {
      ...product,
      _id: undefined, // Remove ID so it's treated as a new product
      name: `${product.name} (Copy)`, // Add "(Copy)" to the name
      image: null, // Clear image so user can upload a new one
      pricing: product.pricing
        ? product.pricing.map((tier) => ({
          minQuantity: tier.minQuantity,
          pricePerUnit: tier.pricePerUnit,
        }))
        : [{ minQuantity: 1, pricePerUnit: 0 }],
      costPerUnit: product.costPerUnit || 0,
      // Reset stock to defaults for cloned product
      currentStock: 0,
      stockStatus: 'out_of_stock' as const,
    };

    setProductData(clonedProduct);
    setEditing(false); // Set to false so it creates a new product
    setAddProductOpen(true);
  };

  // Reset product data when adding a new product
  const handleAddNewProduct = () => {
    setProductData({
      name: "",
      description: "",
      unitType: "pcs",
      category: "",
      stockTracking: true,
      currentStock: 0,
      lowStockThreshold: 10,
      pricing: [{ minQuantity: 1, pricePerUnit: 0 }],
      image: null,
      costPerUnit: 0,
    });
    setEditing(false);
    setModalOpen(true);
  };

  // Get category name by ID
  const getCategoryNameById = (categoryId: string): string => {
    const category = categories.find((cat) => cat._id === categoryId);
    if (!category) return "Unknown Category";
    if (category.parentId) {
      const parent = categories.find((cat) => cat._id === category.parentId);
      return parent ? `${parent.name} > ${category.name}` : category.name;
    }
    return category.name;
  };

  // Filter products based on search term
  const filteredProducts = products.filter(product => {
    if (!searchTerm) return true;

    const searchLower = searchTerm.toLowerCase();

    // Search in product name
    if (product.name.toLowerCase().includes(searchLower)) return true;

    // Search in product description if it exists
    if (product.description && product.description.toLowerCase().includes(searchLower)) return true;

    // Search in category name
    const categoryName = getCategoryNameById(product.category).toLowerCase();
    if (categoryName.includes(searchLower)) return true;

    return false;
  });

  const handleModalClose = () => {
    setAddProductOpen(false);
    setEditing(false);
    setProductData({
      name: "",
      description: "",
      unitType: "pcs",
      category: "",
      pricing: [{ minQuantity: 1, pricePerUnit: 0 }],
      image: null,
      costPerUnit: 0,
    });
    if (setImagePreview) {
      setImagePreview(null);
    }
  };

  const handleProfitAnalysis = (productId: string, productName: string) => {
    setSelectedProductForAnalysis({ id: productId, name: productName });
    setProfitAnalysisOpen(true);
  };

  const handleProfitAnalysisClose = () => {
    setProfitAnalysisOpen(false);
    setSelectedProductForAnalysis(null);
  };

  // Handle toggle product enabled status
  const handleToggleEnabled = async (productId: string, enabled: boolean) => {
    try {
      setLoading(true);

      await clientFetch(`/products/${productId}`, {
        method: "PATCH",
        body: JSON.stringify({ enabled }),
      });

      // Update the local state
      setProducts(products.map(product =>
        product._id === productId
          ? { ...product, enabled }
          : product
      ));

      toast.success(`Product ${enabled ? 'enabled' : 'disabled'} successfully`);
      setLoading(false);
    } catch (error) {
      console.error(error);
      toast.error("Failed to update product status");
      setLoading(false);
    }
  };

  return (
    <Layout>
      <div className="space-y-6">
        <div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">
          <h1 className="text-2xl font-semibold text-gray-900 dark:text-white flex items-center">
            <Package2 className="mr-2 h-6 w-6" />
            Products
          </h1>
          <div className="flex flex-col sm:flex-row items-stretch sm:items-center gap-3">
            <div className="relative">
              <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
              <Input
                type="search"
                placeholder="Search products..."
                className="w-full sm:w-64 pl-8"
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
              />
              {searchTerm && (
                <Button
                  variant="ghost"
                  size="icon"
                  className="absolute right-0 top-0 h-9 w-9"
                  onClick={() => setSearchTerm("")}
                >
                  <RefreshCw className="h-4 w-4" />
                </Button>
              )}
            </div>
            <div className="flex gap-2">
              <Button
                onClick={() => setImportModalOpen(true)}
                variant="outline"
                className="gap-2 flex-1 sm:flex-none"
              >
                <Upload className="h-4 w-4" />
                <span className="hidden sm:inline">Import Products</span>
                <span className="sm:hidden">Import</span>
              </Button>
              <Button onClick={() => setAddProductOpen(true)} className="gap-2 flex-1 sm:flex-none">
                <Plus className="h-4 w-4" />
                <span className="hidden sm:inline">Add Product</span>
                <span className="sm:hidden">Add</span>
              </Button>
            </div>
          </div>
        </div>

        <ProductTable
          products={filteredProducts}
          loading={loading}
          onEdit={handleEditProduct}
          onClone={handleCloneProduct}
          onDelete={handleDeleteProduct}
          onToggleEnabled={handleToggleEnabled}
          onProfitAnalysis={handleProfitAnalysis}
          getCategoryNameById={getCategoryNameById}
        />

        <ProductModal
          open={addProductOpen}
          onClose={handleModalClose}
          onSave={handleSaveProduct}
          productData={productData}
          categories={categories}
          editing={editing}
          handleChange={handleChange}
          handleTieredPricingChange={handleTieredPricingChange}
          handleAddTier={handleAddTier}
          handleRemoveTier={handleRemoveTier}
          setProductData={setProductData}
        />

        <ImportProductsModal
          open={importModalOpen}
          setOpen={setImportModalOpen}
          onImportComplete={() => {
            setProducts(products);
          }}
        />

        {selectedProductForAnalysis && (
          <ProfitAnalysisModal
            open={profitAnalysisOpen}
            onClose={handleProfitAnalysisClose}
            productId={selectedProductForAnalysis.id}
            productName={selectedProductForAnalysis.name}
          />
        )}
      </div>
    </Layout>
  );
}


