import { trpc } from '@/src/trpc-client';
import { Alert } from 'react-native';
import { useState, useEffect } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { StorageServiceCasual } from 'common-ui/src/services/StorageServiceCasual';

// Cart type definition
export type CartType = "regular" | "flash";

// const CART_MODE: 'remote' | 'local' = 'remote';
const CART_MODE: 'remote' | 'local' = 'local';

const getCartStorageKey = (cartType: CartType = "regular"): string => {
  return cartType === "flash" ? "flash_cart_items" : "cart_items";
};

interface LocalCartItem {
  id: number;
  productId: number;
  quantity: number;
  slotId: number;
  addedAt: string;
}

interface ProductSummary {
  id: number;
  name: string;
  shortDescription?: string | null;
  longDescription?: string | null;
  price: string;
  marketPrice?: string | null;
  unitNotation: string;
  images: string[];
  isOutOfStock: boolean;
  store?: { id: number; name: string; description?: string | null } | null;
  incrementStep: number;
  productQuantity: number;
  isFlashAvailable: boolean;
  flashPrice?: string | null;
  deliverySlots: Array<{ id: number; deliveryTime: Date; freezeTime: Date }>;
  specialDeals: Array<{ quantity: string; price: string; validTill: Date }>;
}

interface CartItem {
  id: number;
  productId: number;
  quantity: number;
  addedAt: string;
  product: ProductSummary;
  subtotal: number;
}

const getLocalCart = async (cartType: CartType = "regular"): Promise<LocalCartItem[]> => {
  const key = getCartStorageKey(cartType);
  const data = await StorageServiceCasual.getItem(key);
  return data ? JSON.parse(data) : [];
};

const saveLocalCart = async (items: LocalCartItem[], cartType: CartType = "regular"): Promise<void> => {
  const key = getCartStorageKey(cartType);
  await StorageServiceCasual.setItem(key, JSON.stringify(items));
  const fetchedItems = await getLocalCart(cartType);

};

const getNextCartItemId = (items: LocalCartItem[]): number => {
  const maxId = items.length > 0 ? Math.max(...items.map(item => item.id)) : 0;
  return maxId + 1;
};

const addToLocalCart = async (productId: number, quantity: number, slotId?: number, cartType: CartType = "regular"): Promise<LocalCartItem[]> => {
  
  const items = await getLocalCart(cartType);
  const existingIndex = items.findIndex(item => item.productId === productId);

  if (existingIndex >= 0) {
    items[existingIndex].quantity += quantity;
    if (slotId !== undefined) {
      items[existingIndex].slotId = slotId;
    }
  } else {
    const newId = getNextCartItemId(items);
    const cartItem = {
      id: newId,
      productId,
      quantity,
      slotId: slotId ?? 0, // Default to 0 if not provided
      addedAt: new Date().toISOString(),
    }

    items.push(cartItem);
  }
  
  await saveLocalCart(items, cartType);
  return items;
};

const updateLocalCartItem = async (itemId: number, quantity: number, cartType: CartType = "regular"): Promise<LocalCartItem[]> => {
  const items = await getLocalCart(cartType);
  const item = items.find(i => i.id === itemId);
  if (item) {
    item.quantity = quantity;
    await saveLocalCart(items, cartType);
  }
  return items;
};

const removeFromLocalCart = async (itemId: number, cartType: CartType = "regular"): Promise<LocalCartItem[]> => {
  const items = await getLocalCart(cartType);
  const filtered = items.filter(i => i.id !== itemId);
  await saveLocalCart(filtered, cartType);
  return filtered;
};

const clearLocalCart = async (cartType: CartType = "regular"): Promise<void> => {
  const key = getCartStorageKey(cartType);
  await StorageServiceCasual.setItem(key, JSON.stringify([]));
};

export function useGetCart(options?: {
  refetchOnWindowFocus?: boolean;
  enabled?: boolean;
}, cartType: CartType = "regular") {
  if (CART_MODE === 'remote') {
    const query = trpc.user.cart.getCart.useQuery(undefined, {
      refetchOnWindowFocus: options?.refetchOnWindowFocus ?? true,
      enabled: options?.enabled ?? true,
      ...options
    });

    return {
      // Original tRPC returns
      data: query.data,
      isLoading: query.isLoading,
      error: query.error,
      refetch: query.refetch,

      // Computed properties
      cartItems: query.data?.items || [],
      totalItems: query.data?.totalItems || 0,
      totalPrice: query.data?.totalAmount || 0,

      // Helper methods
      isEmpty: !query.data?.items?.length,
      hasItems: Boolean(query.data?.items?.length),
    };
  } else {
    
    const { data: products } = trpc.user.product.getAllProductsSummary.useQuery();
    const query = useQuery({
      queryKey: [`local-cart-${cartType}`],
      queryFn: async () => {

        const cartItems = await getLocalCart(cartType);
        
        // const productMap = Object.fromEntries(products?.map((p: ProductSummary) => [p.id, p]) || []);
        const productMap = Object.fromEntries(products?.map((p) => [p.id, p]) || []);
        
        const items: CartItem[] = cartItems.map(cartItem => {
          const product = productMap[cartItem.productId];
          
          if (!product) return null as any;
          return {
            id: cartItem.id,
            productId: cartItem.productId,
            quantity: cartItem.quantity,
            addedAt: cartItem.addedAt,
            product,
            incrementStep: product.incrementStep,
            subtotal: Number(product.price) * cartItem.quantity,
            slotId: cartItem.slotId,
          };
        }).filter(Boolean) as CartItem[];
        const totalAmount = items.reduce((sum, item) => sum + item.subtotal, 0);
        
        return {
          items,
          totalItems: items.length,
          totalAmount,
        };
      },
      refetchOnWindowFocus: options?.refetchOnWindowFocus ?? true,
      enabled: (options?.enabled ?? true) && !!products,
    });
    
    return {
      data: query.data,
      isLoading: query.isLoading,
      error: query.error,
      refetch: query.refetch,

      // Computed properties
      cartItems: query.data?.items || [],
      totalItems: query.data?.totalItems || 0,
      totalPrice: query.data?.totalAmount || 0,

      // Helper methods
      isEmpty: !query.data?.items?.length,
      hasItems: Boolean(query.data?.items?.length),
    };
  }
}

interface UseAddToCartReturn {
  mutate: any;
  mutateAsync: any;
  isLoading: boolean;
  error: any;
  data: any;
  addToCart: (productId: number, quantity?: number, slotId?: number, onSettled?: (data: any, error: any) => void) => void;
  addToCartAsync: (productId: number, quantity?: number, slotId?: number) => Promise<any>;
}

export function useAddToCart(options?: {
  onSuccess?: (data: any, variables: any) => void;
  onError?: (error: any) => void;
  showSuccessAlert?: boolean;
  showErrorAlert?: boolean;
  refetchCart?: boolean;
}, cartType: CartType = "regular"): UseAddToCartReturn {
  if (CART_MODE === 'remote') {
    const utils = trpc.useUtils();

    const mutation = trpc.user.cart.addToCart.useMutation({
      onSuccess: (data, variables) => {
        // Default success handling
        if (options?.showSuccessAlert !== false) {
          Alert.alert("Success", "Item added to cart!");
        }

        // Auto-refetch cart if requested
        if (options?.refetchCart) {
          utils.user.cart.getCart.invalidate();
        }

        // Custom success callback
        options?.onSuccess?.(data, variables);
      },
      onError: (error) => {
        // Default error handling
        if (options?.showErrorAlert !== false) {
          Alert.alert("Error", error.message || "Failed to add item to cart");
        }

        // Custom error callback
        options?.onError?.(error);
      },
    }) as any;

    const addToCart = (productId: number, quantity = 1, slotId?: number, onSettled?: (data: any, error: any) => void) => {
      
      if (slotId == null) {
        throw new Error('slotId is required for adding to cart');
      }
      return mutation.mutate({ productId, quantity, slotId }, {
        onSettled: (data: any, error: any) => {
          onSettled?.(data, error);
        }
      });
    };

    return {
      // Original mutation returns
      mutate: mutation.mutate,
      mutateAsync: mutation.mutateAsync,
      isLoading: mutation.isPending,
      error: mutation.error,
      data: mutation.data,

      addToCart,

      addToCartAsync: (productId: number, quantity = 1, slotId?: number) => {
        if (slotId == null) {
          throw new Error('slotId is required for adding to cart');
        }
        return mutation.mutateAsync({ productId, quantity, slotId });
      },
    };
  } else {
    
    const queryClient = useQueryClient();

    const mutation = useMutation({
      mutationFn: async ({ productId, quantity, slotId }: { productId: number, quantity: number, slotId: number }) => {
        return await addToLocalCart(productId, quantity, slotId, cartType);
      },
      onSuccess: (data, variables) => {
        queryClient.invalidateQueries({ queryKey: [`local-cart-${cartType}`] });
        if (options?.showSuccessAlert !== false) {
          Alert.alert("Success", "Item added to cart!");
        }
        options?.onSuccess?.(data, variables);
      },
      onError: (error) => {
        if (options?.showErrorAlert !== false) {
          Alert.alert("Error", error.message || "Failed to add item to cart");
        }
        options?.onError?.(error);
      },
    });

    const addToCart = (productId: number, quantity = 1, slotId?: number, onSettled?: (data: any, error: any) => void) => {

      // console.log({productId, quantity, slotId})
      
      if (slotId == null) {
        throw new Error('slotId is required for adding to cart');
      }
      return mutation.mutate({ productId, quantity, slotId }, {
        onSettled: (data: any, error: any) => {
          onSettled?.(data, error);
        }
      });
    };

    return {
      mutate: mutation.mutate,
      mutateAsync: mutation.mutateAsync,
      isLoading: mutation.isPending,
      error: mutation.error,
      data: mutation.data,
      addToCart,
      addToCartAsync: (productId: number, quantity = 1, slotId?: number) => {
        if (slotId == null) {
          throw new Error('slotId is required for adding to cart');
        }
        return mutation.mutateAsync({ productId, quantity, slotId });
      },
    };
  }
}

export function useUpdateCartItem(options?: {
  onSuccess?: (data: any, variables: any) => void;
  onError?: (error: any) => void;
  showSuccessAlert?: boolean;
  showErrorAlert?: boolean;
  refetchCart?: boolean;
}, cartType: CartType = "regular") {
  if (CART_MODE === 'remote') {
    const utils = trpc.useUtils();

    const mutation = trpc.user.cart.updateCartItem.useMutation({
      onSuccess: (data, variables) => {
        // Default success handling
        if (options?.showSuccessAlert !== false) {
          Alert.alert("Success", "Cart item updated!");
        }

        // Auto-refetch cart if requested
        if (options?.refetchCart) {
          utils.user.cart.getCart.invalidate();
        }

        // Custom success callback
        options?.onSuccess?.(data, variables);
      },
      onError: (error) => {
        // Default error handling
        if (options?.showErrorAlert !== false) {
          Alert.alert("Error", error.message || "Failed to update cart item");
        }

        // Custom error callback
        options?.onError?.(error);
      },
    });

    return {
      // Original mutation returns
      mutate: mutation.mutate,
      mutateAsync: mutation.mutateAsync,
      isLoading: mutation.isPending,
      error: mutation.error,
      data: mutation.data,

      // Helper methods
      updateCartItem: (itemId: number, quantity: number) =>
        mutation.mutate({ itemId, quantity }),

      updateCartItemAsync: (itemId: number, quantity: number) =>
        mutation.mutateAsync({ itemId, quantity }),
    };
  } else {
    const queryClient = useQueryClient();

    const mutation = useMutation({
      mutationFn: async ({ itemId, quantity }: { itemId: number, quantity: number }) => {
        return await updateLocalCartItem(itemId, quantity, cartType);
      },
      onSuccess: (data, variables) => {
        queryClient.invalidateQueries({ queryKey: [`local-cart-${cartType}`] });
        if (options?.showSuccessAlert !== false) {
          Alert.alert("Success", "Cart item updated!");
        }
        options?.onSuccess?.(data, variables);
      },
      onError: (error) => {
        if (options?.showErrorAlert !== false) {
          Alert.alert("Error", error.message || "Failed to update cart item");
        }
        options?.onError?.(error);
      },
    });

    return {
      mutate: mutation.mutate,
      mutateAsync: mutation.mutateAsync,
      isLoading: mutation.isPending,
      error: mutation.error,
      data: mutation.data,

      updateCartItem: (itemId: number, quantity: number) =>
        mutation.mutate({ itemId, quantity }),

      updateCartItemAsync: (itemId: number, quantity: number) =>
        mutation.mutateAsync({ itemId, quantity }),
    };
  }
}

export function useRemoveFromCart(options?: {
  onSuccess?: (data: any, variables: any) => void;
  onError?: (error: any) => void;
  showSuccessAlert?: boolean;
  showErrorAlert?: boolean;
  refetchCart?: boolean;
}, cartType: CartType = "regular") {
  if (CART_MODE === 'remote') {
    const utils = trpc.useUtils();

    const mutation = trpc.user.cart.removeFromCart.useMutation({
      onSuccess: (data, variables) => {
        // Default success handling
        if (options?.showSuccessAlert !== false) {
          Alert.alert("Success", "Item removed from cart!");
        }

        // Auto-refetch cart if requested
        if (options?.refetchCart) {
          utils.user.cart.getCart.invalidate();
        }

        // Custom success callback
        options?.onSuccess?.(data, variables);
      },
      onError: (error) => {
        // Default error handling
        if (options?.showErrorAlert !== false) {
          Alert.alert("Error", error.message || "Failed to remove item from cart");
        }

        // Custom error callback
        options?.onError?.(error);
      },
    });

    return {
      // Original mutation returns
      mutate: mutation.mutate,
      mutateAsync: mutation.mutateAsync,
      isLoading: mutation.isPending,
      error: mutation.error,
      data: mutation.data,

      // Helper methods
      removeFromCart: (itemId: number) =>
        mutation.mutate({ itemId }),

      removeFromCartAsync: (itemId: number) =>
        mutation.mutateAsync({ itemId }),
    };
  } else {
    const queryClient = useQueryClient();

    const mutation = useMutation({
      mutationFn: async ({ itemId }: { itemId: number }) => {
        return await removeFromLocalCart(itemId, cartType);
      },
      onSuccess: (data, variables) => {
        queryClient.invalidateQueries({ queryKey: [`local-cart-${cartType}`] });
        if (options?.showSuccessAlert !== false) {
          Alert.alert("Success", "Item removed from cart!");
        }
        options?.onSuccess?.(data, variables);
      },
      onError: (error) => {
        if (options?.showErrorAlert !== false) {
          Alert.alert("Error", error.message || "Failed to remove item from cart");
        }
        options?.onError?.(error);
      },
    });

    return {
      mutate: mutation.mutate,
      mutateAsync: mutation.mutateAsync,
      isLoading: mutation.isPending,
      error: mutation.error,
      data: mutation.data,

      removeFromCart: (itemId: number) =>
        mutation.mutate({ itemId }),

      removeFromCartAsync: (itemId: number) =>
        mutation.mutateAsync({ itemId }),
    };
  }
}

// Export clear cart function for direct use
export { clearLocalCart };