import { useState, useEffect, useRef } from "react";
import { Button } from "../ui/button";
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerFooter,
} from "../ui/drawer";
import { toast } from "../../hooks/use-toast";
import { ColorSelector } from "./ColorSelector";
import { SizeSelector } from "./SizeSelector";
import { useColorAttributes } from "~/requestHandler/use-product-hooks";
import AppInput from "../AppInput";

interface ProductVariant {
  color: string;
  size: string;
  quantity: number;
}

interface ProductVariantDrawerProps {
  isOpen: boolean;
  onClose: () => void;
  onSave: (variants: ProductVariant[]) => void;
  initialVariants?: ProductVariant[];
}

export const ProductVariantDrawer = ({
  isOpen,
  onClose,
  onSave,
  initialVariants = [],
}: ProductVariantDrawerProps) => {
  const { data: colorAttributes } = useColorAttributes();
  const [step, setStep] = useState<"attributes" | "quantities">("attributes");
  const [selectedColors, setSelectedColors] = useState<string[]>([]);
  const [selectedSizes, setSelectedSizes] = useState<string[]>([]);
  const [bulkQuantity, setBulkQuantity] = useState("1");
  const [customQuantities, setCustomQuantities] = useState<
    Record<string, number>
  >({});
  const [colorUnselectedMode, setColorUnselectedMode] = useState(false);

  const initializationDoneRef = useRef<boolean>(false);
  const prevIsOpenRef = useRef<boolean>(false);

  // Initialize state from initial variants when drawer opens
  useEffect(() => {
    // Only initialize when drawer opens for the first time (not on re-renders)
    if (isOpen && !prevIsOpenRef.current) {
      if (initialVariants.length > 0) {
        // Color still supports the "no color" escape hatch.
        const hasUnselectedColor = initialVariants.some(
          (v) => v.color === "unselected"
        );
        setColorUnselectedMode(hasUnselectedColor);

        // Extract unique colors and sizes from initial variants (excluding unselected).
        // Legacy variants with size="unselected" are dropped here so the seller is
        // forced to pick a real size (FreeSize covers one-size products).
        const colors = [
          ...new Set(
            initialVariants
              .map((v) => v.color)
              .filter((c) => c !== "unselected")
          ),
        ];
        const sizes = [
          ...new Set(
            initialVariants.map((v) => v.size).filter((s) => s !== "unselected")
          ),
        ];

        setSelectedColors(colors);
        setSelectedSizes(sizes);

        // Set individual quantities
        const quantities: Record<string, number> = {};
        initialVariants.forEach((variant) => {
          const key = `${variant.color}-${variant.size}`;
          quantities[key] = variant.quantity;
        });
        setCustomQuantities(quantities);

        // Set bulk quantity to the most common quantity or first quantity
        const quantityValues = initialVariants.map((v) => v.quantity);
        const mostCommonQuantity =
          quantityValues.length > 0 ? quantityValues[0] : 1;
        setBulkQuantity(mostCommonQuantity.toString());
      } else {
        // Reset state when opening without initial variants
        setStep("attributes");
        setSelectedColors([]);
        setSelectedSizes([]);
        setBulkQuantity("1");
        setCustomQuantities({});
        setColorUnselectedMode(false);
      }
      initializationDoneRef.current = true;
    }

    // Reset when drawer closes
    if (!isOpen && prevIsOpenRef.current) {
      setStep("attributes");
      setSelectedColors([]);
      setSelectedSizes([]);
      setBulkQuantity("1");
      setCustomQuantities({});
      setColorUnselectedMode(false);
      initializationDoneRef.current = false;
    }

    prevIsOpenRef.current = isOpen;
  }, [isOpen]);

  // Separate effect for initialVariants changes (when drawer is already open)
  useEffect(() => {
    if (isOpen && initializationDoneRef.current && initialVariants.length > 0) {
      // Only update if variants actually changed
      const currentVariantKeys = selectedColors
        .flatMap((color) => selectedSizes.map((size) => `${color}-${size}`))
        .sort();

      const newVariantKeys = initialVariants
        .map((v) => `${v.color}-${v.size}`)
        .sort();

      if (
        JSON.stringify(currentVariantKeys) !== JSON.stringify(newVariantKeys)
      ) {
        // Color still supports the "no color" escape hatch.
        const hasUnselectedColor = initialVariants.some(
          (v) => v.color === "unselected"
        );
        setColorUnselectedMode(hasUnselectedColor);

        // Extract unique colors and sizes from initial variants (excluding unselected).
        // Legacy "unselected" size variants are ignored so the seller must pick.
        const colors = [
          ...new Set(
            initialVariants
              .map((v) => v.color)
              .filter((c) => c !== "unselected")
          ),
        ];
        const sizes = [
          ...new Set(
            initialVariants.map((v) => v.size).filter((s) => s !== "unselected")
          ),
        ];

        setSelectedColors(colors);
        setSelectedSizes(sizes);

        // Set individual quantities
        const quantities: Record<string, number> = {};
        initialVariants.forEach((variant) => {
          const key = `${variant.color}-${variant.size}`;
          quantities[key] = variant.quantity;
        });
        setCustomQuantities(quantities);
      }
    }
  }, [initialVariants, isOpen]);

  // Generate all possible variants
  const generateVariants = (): ProductVariant[] => {
    const variants: ProductVariant[] = [];

    getQuantityVariants().forEach((variant) => {
      const { color, size, key } = variant;
      let quantity: number;

      if (key in customQuantities) {
        // Use custom quantity if exists
        quantity = customQuantities[key];
      } else {
        // Use bulk quantity for variants without custom quantity
        quantity = parseInt(bulkQuantity) || 0;
      }

      variants.push({ color, size, quantity });
    });

    return variants;
  };

  const toggleColor = (colorValue: string) => {
    setSelectedColors((prev) =>
      prev.includes(colorValue)
        ? prev.filter((c) => c !== colorValue)
        : [...prev, colorValue]
    );
  };

  const removeColor = (colorValue: string) => {
    setSelectedColors((prev) => prev.filter((c) => c !== colorValue));
  };

  const toggleSize = (size: string) => {
    setSelectedSizes((prev) =>
      prev.includes(size) ? prev.filter((s) => s !== size) : [...prev, size]
    );
  };

  const removeSize = (size: string) => {
    setSelectedSizes((prev) => prev.filter((s) => s !== size));
  };

  const handleQuantityChange = (
    color: string,
    size: string,
    quantity: string
  ) => {
    const key = `${color}-${size}`;
    // Allow empty string or parse to number (including 0)
    const quantityNumber = quantity === "" ? 0 : parseInt(quantity);

    setCustomQuantities((prev) => ({
      ...prev,
      [key]: isNaN(quantityNumber) ? 0 : quantityNumber,
    }));
  };

  const applyBulkQuantityToAll = () => {
    const bulkQuantityNumber = parseInt(bulkQuantity) || 0;
    const newQuantities: Record<string, number> = {};

    getQuantityVariants().forEach((variant) => {
      const { key } = variant;
      newQuantities[key] = bulkQuantityNumber;
    });

    setCustomQuantities((prev) => ({ ...prev, ...newQuantities }));
  };

  // Get variants for quantity display. Size is always required (FreeSize covers
  // one-size products); color still has an unselected escape hatch.
  const getQuantityVariants = () => {
    const variants: { color: string; size: string; key: string }[] = [];

    if (colorUnselectedMode) {
      selectedSizes.forEach((size) => {
        variants.push({
          color: "unselected",
          size: size,
          key: `unselected-${size}`,
        });
      });
    } else {
      selectedColors.forEach((color) => {
        selectedSizes.forEach((size) => {
          variants.push({
            color: color,
            size: size,
            key: `${color}-${size}`,
          });
        });
      });
    }

    return variants;
  };

  const handleNext = () => {
    // Size is always required; use "فری سایز" for one-size products.
    if (selectedSizes.length === 0) {
      toast({
        title: "خطا",
        description:
          "لطفاً حداقل یک سایز انتخاب کنید. اگر محصول تک‌سایز است، «فری سایز» را انتخاب کنید.",
      });
      return;
    }
    // Color is optional (colorUnselectedMode covers no-color products).
    if (!colorUnselectedMode && selectedColors.length === 0) {
      toast({
        title: "خطا",
        description: "لطفاً حداقل یک رنگ انتخاب کنید یا حالت بدون رنگ را فعال کنید",
      });
      return;
    }
    setStep("quantities");
  };

  const handleSave = () => {
    const variants = generateVariants();
    onSave(variants);
    onClose();
  };

  const handleClose = () => {
    onClose();
  };

  return (
    <Drawer open={isOpen} onOpenChange={onClose}>
      <DrawerContent className="h-[90vh]">
        <DrawerHeader>
          <DrawerTitle className="text-center">
            {step === "attributes" ? "انتخاب رنگ و سایز" : "تعیین موجودی"}
          </DrawerTitle>
        </DrawerHeader>

        <div className="flex-1 overflow-y-auto px-4">
          {step === "attributes" ? (
            <div className="space-y-6">
              {/* Color Selection */}
              <ColorSelector
                selectedColors={selectedColors}
                onToggleColor={toggleColor}
                onRemoveColor={removeColor}
                unselectedMode={colorUnselectedMode}
                onToggleUnselectedMode={setColorUnselectedMode}
              />

              {/* Size Selection */}
              <SizeSelector
                selectedSizes={selectedSizes}
                onToggleSize={toggleSize}
                onRemoveSize={removeSize}
              />
            </div>
          ) : (
            <div className="space-y-6">
              {/* Bulk Quantity Setting */}
              <div className="relative overflow-hidden rounded-xl border border-primary/20 bg-gradient-to-br from-primary/5 via-primary/10 to-transparent p-6 shadow-sm">
                <div className="absolute -right-6 -top-6 h-24 w-24 rounded-full bg-primary/10 blur-2xl" />
                <div className="relative space-y-4">
                  <div className="flex items-center gap-2 text-right">
                    <div className="flex-1">
                      <h4 className="font-semibold text-base text-foreground">تعیین موجودی عمومی</h4>
                      <p className="text-xs text-muted-foreground mt-1">این مقدار به تمام موارد اعمال می‌شود</p>
                    </div>
                    <div className="flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10">
                      <svg className="h-5 w-5 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
                      </svg>
                    </div>
                  </div>
                  <div className="flex items-center gap-3">
                    <Button
                      size="sm"
                      onClick={applyBulkQuantityToAll}
                      className="flex-1 gap-2 shadow-md hover:shadow-lg transition-all duration-200"
                    >
                      <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                      </svg>
                      اعمال به همه
                    </Button>
                    <div className="w-24">
                      <AppInput
                        inputTitle=""
                        inputValue={bulkQuantity}
                        inputOnChange={(e) => setBulkQuantity(e.target.value)}
                        inputPlaceholder="0"
                        type="number"
                        className="text-center font-semibold text-lg"
                      />
                    </div>
                  </div>
                </div>
              </div>

              {/* Individual Variant Quantities */}
              <div className="space-y-4">
                <h4 className="font-medium text-right">موجودی اختصاصی:</h4>
                <div className="space-y-3 overflow-y-auto">
                  {getQuantityVariants().map((variant) => {
                    const { color, size, key } = variant;
                    const quantity =
                      key in customQuantities
                        ? customQuantities[key]
                        : parseInt(bulkQuantity) || 0;
                    const colorInfo = colorAttributes?.find(
                      (c) => c.value === color
                    );

                    // Helper function to get display text — colorless variants
                    // roll up under the size label; sized/colored variants show
                    // both.
                    const getDisplayText = () => {
                      if (colorUnselectedMode) {
                        return `موجودی سایز ${size}`;
                      }
                      return null; // Normal mode — render color + size below
                    };

                    const displayText = getDisplayText();

                    return (
                      <div
                        key={key}
                        className="flex items-center justify-between p-3 bg-WHITE3 border rounded-lg"
                      >
                        <div className="flex items-center gap-3">
                          {displayText ? (
                            // Special unselected modes
                            <span className="text-sm font-medium">
                              {displayText}
                            </span>
                          ) : (
                            // Normal mode - show color and size
                            <>
                              <div className="flex items-center gap-2">
                                <div
                                  className="w-6 h-6 rounded border border-GRAY3"
                                  style={{ backgroundColor: color }}
                                />
                                <span className="text-sm">
                                  {colorInfo?.info.persian || color}
                                </span>
                              </div>
                              <div className="flex items-center gap-1">
                                <span className="text-xs text-GRAY">
                                  سایز:
                                </span>
                                <span className="text-sm font-medium">
                                  {size}
                                </span>
                              </div>
                            </>
                          )}
                        </div>
                        <div className="w-16">
                          <AppInput
                            inputTitle=""
                            inputValue={quantity.toString()}
                            inputOnChange={(e) =>
                              handleQuantityChange(
                                color,
                                size,
                                e.target.value
                              )
                            }
                            inputPlaceholder="0"
                            type="number"
                            className="text-center text-sm"
                          />
                        </div>
                      </div>
                    );
                  })}
                </div>
              </div>
            </div>
          )}
        </div>

        <DrawerFooter>
          <div className="flex gap-3 w-full">
            <Button
              variant="outline"
              size="lg"
              onClick={handleClose}
              className="flex-1"
            >
              لغو
            </Button>
            {step === "attributes" ? (
              <Button size="lg" onClick={handleNext} className="flex-1">
                مرحله بعد
              </Button>
            ) : (
              <>
                <Button
                  variant="outline"
                  size="lg"
                  onClick={() => setStep("attributes")}
                  className="flex-1"
                >
                  بازگشت
                </Button>
                <Button size="lg" onClick={handleSave} className="flex-1">
                  ذخیره
                </Button>
              </>
            )}
          </div>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  );
};
