import { useState, useCallback, useRef, useEffect } from "react";
import { QuantityControl } from "./QuantityControl";
import { Loader2 } from "lucide-react";

interface ThrottledQuantityControlProps {
  initialQuantity: number;
  maxQuantity: number;
  onQuantityUpdate: (quantity: number) => void;
  isPending?: boolean;
  allowManualEdit?: boolean;
  onRemove?: () => void;
  throttleDelay?: number;
}

export const ThrottledQuantityControl = ({
  initialQuantity,
  maxQuantity,
  onQuantityUpdate,
  isPending: externalIsPending = false,
  allowManualEdit = false,
  onRemove,
  throttleDelay = 1000,
}: ThrottledQuantityControlProps) => {
  const [quantity, setQuantity] = useState(initialQuantity);
  const [isUpdating, setIsUpdating] = useState(false);
  const throttleTimerRef = useRef<NodeJS.Timeout | null>(null);
  const isMountedRef = useRef(true);

  useEffect(() => {
    return () => {
      isMountedRef.current = false;
      if (throttleTimerRef.current) {
        clearTimeout(throttleTimerRef.current);
      }
    };
  }, []);

  useEffect(() => {
    setQuantity(initialQuantity);
  }, [initialQuantity]);

  const performUpdate = useCallback(
    async (newQuantity: number) => {
      try {
        setIsUpdating(true);
        await onQuantityUpdate(newQuantity);
      } catch (error) {
        // Revert quantity on error
        if (isMountedRef.current) {
          setQuantity(initialQuantity);
        }
      } finally {
        if (isMountedRef.current) {
          setIsUpdating(false);
        }
      }
    },
    [onQuantityUpdate, initialQuantity]
  );

  const scheduleUpdate = useCallback(
    (newQuantity: number) => {
      // Update local state immediately for responsive UI
      setQuantity(newQuantity);

      // Clear existing timer
      if (throttleTimerRef.current) {
        clearTimeout(throttleTimerRef.current);
      }

      // Schedule the API call after throttle delay
      throttleTimerRef.current = setTimeout(() => {
        performUpdate(newQuantity);
      }, throttleDelay);
    },
    [performUpdate, throttleDelay]
  );

  const handleIncrease = useCallback(() => {
    if (quantity < maxQuantity && !isUpdating && !externalIsPending) {
      const newQuantity = quantity + 1;
      scheduleUpdate(newQuantity);
    }
  }, [quantity, maxQuantity, isUpdating, externalIsPending, scheduleUpdate]);

  const handleDecrease = useCallback(() => {
    if (quantity > 0 && !isUpdating && !externalIsPending) {
      const newQuantity = quantity - 1;
      scheduleUpdate(newQuantity);
    }
  }, [quantity, isUpdating, externalIsPending, scheduleUpdate]);

  const handleQuantityChange = useCallback(
    (newQuantity: number) => {
      if (
        newQuantity >= 0 &&
        newQuantity <= maxQuantity &&
        !isUpdating &&
        !externalIsPending
      ) {
        scheduleUpdate(newQuantity);
      }
    },
    [maxQuantity, isUpdating, externalIsPending, scheduleUpdate]
  );

  const isLoading = isUpdating || externalIsPending;

  // Custom wrapper to show loading on entire component
  return (
    <div
      className={`relative ${isLoading ? "opacity-50 pointer-events-none" : ""}`}
    >
      <QuantityControl
        quantity={quantity}
        maxQuantity={maxQuantity}
        onIncrease={handleIncrease}
        onDecrease={handleDecrease}
        onRemove={onRemove}
        isPending={isLoading}
        allowManualEdit={allowManualEdit && !isLoading}
        onQuantityChange={handleQuantityChange}
      />

      {/* Loading overlay for entire component */}
      {isLoading && (
        <div className="absolute inset-0 flex items-center justify-center">
          <Loader2 className="h-5 w-5 animate-spin text-gray-600" />
        </div>
      )}
    </div>
  );
};
