"use client";

import React, { createContext, useContext, useReducer, useEffect } from 'react';
import { Cart, CartItem, CartContextType } from '@/types/cart';
import { cartService } from '@/services/cartService';
import { useAuth } from '@/context/AuthContext';

// Product type for cart operations
interface CartProduct {
  id: string;
  title: string;
  price: number | string;
  imageSrc: string;
  slug?: string;
}

// Cart reducer actions
type CartAction =
  | { type: 'ADD_TO_CART'; payload: { product: CartProduct; quantity: number } }
  | { type: 'REMOVE_FROM_CART'; payload: { productId: string } }
  | { type: 'UPDATE_QUANTITY'; payload: { productId: string; quantity: number } }
  | { type: 'CLEAR_CART' }
  | { type: 'LOAD_CART'; payload: { cart: Cart } }
  | { type: 'SET_LOADING'; payload: { loading: boolean } };

// Initial cart state
const initialCart: Cart = {
  items: [],
  totalItems: 0,
  totalPrice: 0,
};

interface CartState extends Cart {
  loading: boolean;
}

const initialState: CartState = {
  ...initialCart,
  loading: false,
};

// Cart reducer function
const cartReducer = (state: CartState, action: CartAction): CartState => {
  console.log('CartReducer action:', action.type);
  
  switch (action.type) {
    case 'SET_LOADING':
      return {
        ...state,
        loading: action.payload.loading,
      };
      
    case 'ADD_TO_CART': {
      console.log('Processing ADD_TO_CART action', action.payload);
      
      // For localStorage fallback (non-authenticated users)
      const { product, quantity } = action.payload;
      const existingItemIndex = state.items.findIndex(item => item.productId === product.id);
      
      let newItems: CartItem[];
      
      if (existingItemIndex >= 0) {
        // Update existing item quantity
        newItems = state.items.map((item, index) =>
          index === existingItemIndex
            ? { ...item, quantity: item.quantity + quantity }
            : item
        );
        console.log('Updated existing item, new items:', newItems);
      } else {
        // Add new item
        const newItem: CartItem = {
          id: `${product.id}-${Date.now()}`,
          productId: product.id,
          title: product.title,
          price: typeof product.price === 'string' ? parseFloat(product.price) : product.price,
          imageSrc: product.imageSrc,
          quantity,
          slug: product.slug,
        };
        newItems = [...state.items, newItem];
        console.log('Added new item:', newItem, 'all items:', newItems);
      }
      
      const totalItems = newItems.reduce((sum, item) => sum + item.quantity, 0);
      const totalPrice = newItems.reduce((sum, item) => sum + (item.price * item.quantity), 0);
      
      const newState = {
        ...state,
        items: newItems,
        totalItems,
        totalPrice,
      };
      
      console.log('New cart state:', newState);
      return newState;
    }
    
    case 'REMOVE_FROM_CART': {
      // For localStorage fallback (non-authenticated users)
      const newItems = state.items.filter(item => item.productId !== action.payload.productId);
      const totalItems = newItems.reduce((sum, item) => sum + item.quantity, 0);
      const totalPrice = newItems.reduce((sum, item) => sum + (item.price * item.quantity), 0);
      
      return {
        ...state,
        items: newItems,
        totalItems,
        totalPrice,
      };
    }
    
    case 'UPDATE_QUANTITY': {
      // For localStorage fallback (non-authenticated users)
      const { productId, quantity } = action.payload;
      
      if (quantity <= 0) {
        // Remove item if quantity is 0 or less
        return cartReducer(state, { type: 'REMOVE_FROM_CART', payload: { productId } });
      }
      
      const newItems = state.items.map(item =>
        item.productId === productId ? { ...item, quantity } : item
      );
      
      const totalItems = newItems.reduce((sum, item) => sum + item.quantity, 0);
      const totalPrice = newItems.reduce((sum, item) => sum + (item.price * item.quantity), 0);
      
      return {
        ...state,
        items: newItems,
        totalItems,
        totalPrice,
      };
    }
    
    case 'CLEAR_CART':
      return {
        ...initialState,
        loading: state.loading,
      };
    
    case 'LOAD_CART':
      return {
        ...action.payload.cart,
        loading: state.loading,
      };
    
    default:
      return state;
  }
};

// Create cart context
const CartContext = createContext<CartContextType | undefined>(undefined);

// Cart provider component
export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [state, dispatch] = useReducer(cartReducer, initialState);
  const { isAuthenticated } = useAuth();

  // Load cart from API when user is authenticated
  useEffect(() => {
    const loadCartFromAPI = async () => {
      try {
        dispatch({ type: 'SET_LOADING', payload: { loading: true } });
        const apiCart = await cartService.getCart();
        const cart = cartService.convertApiCartToCart(apiCart);
        dispatch({ type: 'LOAD_CART', payload: { cart } });
      } catch (error) {
        console.error('Error loading cart from API:', error);
      } finally {
        dispatch({ type: 'SET_LOADING', payload: { loading: false } });
      }
    };

    if (isAuthenticated) {
      loadCartFromAPI();
    } else {
      // Load from localStorage for non-authenticated users
      const savedCart = localStorage.getItem('shopping-cart');
      if (savedCart) {
        try {
          const parsedCart = JSON.parse(savedCart);
          dispatch({ type: 'LOAD_CART', payload: { cart: parsedCart } });
        } catch (error) {
          console.error('Error loading cart from localStorage:', error);
        }
      }
    }
  }, [isAuthenticated]);

  // Save cart to localStorage for non-authenticated users
  useEffect(() => {
    if (!isAuthenticated && state.items.length > 0) {
      const cartData = {
        items: state.items,
        totalItems: state.totalItems,
        totalPrice: state.totalPrice,
      };
      localStorage.setItem('shopping-cart', JSON.stringify(cartData));
    }
  }, [state, isAuthenticated]);

  const loadCartFromAPI = async () => {
    console.log('loadCartFromAPI called, isAuthenticated:', isAuthenticated);
    if (!isAuthenticated) return;
    
    try {
      dispatch({ type: 'SET_LOADING', payload: { loading: true } });
      console.log('Fetching cart from API...');
      const apiCart = await cartService.getCart();
      console.log('API cart response:', apiCart);
      const cart = cartService.convertApiCartToCart(apiCart);
      console.log('Converted cart:', cart);
      dispatch({ type: 'LOAD_CART', payload: { cart } });
      console.log('Cart loaded successfully');
    } catch (error) {
      console.error('Error loading cart from API:', error);
    } finally {
      dispatch({ type: 'SET_LOADING', payload: { loading: false } });
    }
  };

  // Cart actions
  const addToCart = async (product: CartProduct, quantity: number = 1) => {
    console.log('Adding to cart:', { product, quantity, isAuthenticated });
    
    if (isAuthenticated) {
      try {
        dispatch({ type: 'SET_LOADING', payload: { loading: true } });
        const response = await cartService.addToCart(product.id, quantity);
        console.log('Authenticated user response:', response);
        
        // For authenticated users, reload cart from API
        if (response.cart_item) {
          console.log('Found cart_item, reloading from API...');
          await loadCartFromAPI();
        } else {
          console.log('No cart_item in response, reloading anyway...');
          await loadCartFromAPI();
        }
      } catch (error) {
        console.error('Error adding to cart:', error);
        throw error;
      } finally {
        dispatch({ type: 'SET_LOADING', payload: { loading: false } });
      }
    } else {
      try {
        // For guests, try API first to get product details, then store locally
        const response = await cartService.addToCart(product.id, quantity);
        console.log('Guest user API response:', response);
        
        if (response.guest_cart_item) {
          // Convert API response to local cart item and add to local state
          const apiItem = response.guest_cart_item;
          console.log('Processing guest cart item:', apiItem);
          
          const cartItem: CartItem = {
            id: apiItem.id,
            productId: apiItem.product.id,
            title: apiItem.product.title,
            price: apiItem.product.price,
            imageSrc: apiItem.product.image_src,
            quantity: apiItem.quantity,
            slug: apiItem.product.slug,
          };
          
          console.log('Converted cart item:', cartItem);
          
          // Add to local state using the existing ADD_TO_CART action
          dispatch({ type: 'ADD_TO_CART', payload: { 
            product: {
              id: cartItem.productId,
              title: cartItem.title,
              price: cartItem.price,
              imageSrc: cartItem.imageSrc,
              slug: cartItem.slug,
            }, 
            quantity: cartItem.quantity 
          }});
          
          console.log('Dispatched ADD_TO_CART action');
        } else {
          console.log('No guest_cart_item in response, using fallback');
          // Fallback to localStorage for non-authenticated users
          dispatch({ type: 'ADD_TO_CART', payload: { product, quantity } });
        }
      } catch (error) {
        console.error('Error adding to guest cart:', error);
        // Fallback to localStorage for non-authenticated users
        dispatch({ type: 'ADD_TO_CART', payload: { product, quantity } });
      }
    }
  };

  const removeFromCart = async (productId: string) => {
    if (isAuthenticated) {
      try {
        const cartItem = state.items.find(item => item.productId === productId);
        if (cartItem) {
          dispatch({ type: 'SET_LOADING', payload: { loading: true } });
          await cartService.removeFromCart(cartItem.id);
          await loadCartFromAPI(); // Reload cart from API
        }
      } catch (error) {
        console.error('Error removing from cart:', error);
        throw error;
      } finally {
        dispatch({ type: 'SET_LOADING', payload: { loading: false } });
      }
    } else {
      // Fallback to localStorage for non-authenticated users
      dispatch({ type: 'REMOVE_FROM_CART', payload: { productId } });
    }
  };

  const updateQuantity = async (productId: string, quantity: number) => {
    if (isAuthenticated) {
      try {
        const cartItem = state.items.find(item => item.productId === productId);
        if (cartItem) {
          dispatch({ type: 'SET_LOADING', payload: { loading: true } });
          if (quantity <= 0) {
            await cartService.removeFromCart(cartItem.id);
          } else {
            await cartService.updateCartItem(cartItem.id, quantity);
          }
          await loadCartFromAPI(); // Reload cart from API
        }
      } catch (error) {
        console.error('Error updating cart quantity:', error);
        throw error;
      } finally {
        dispatch({ type: 'SET_LOADING', payload: { loading: false } });
      }
    } else {
      // Fallback to localStorage for non-authenticated users
      dispatch({ type: 'UPDATE_QUANTITY', payload: { productId, quantity } });
    }
  };

  const clearCart = async () => {
    if (isAuthenticated) {
      try {
        dispatch({ type: 'SET_LOADING', payload: { loading: true } });
        await cartService.clearCart();
        dispatch({ type: 'CLEAR_CART' });
      } catch (error) {
        console.error('Error clearing cart:', error);
        throw error;
      } finally {
        dispatch({ type: 'SET_LOADING', payload: { loading: false } });
      }
    } else {
      // Fallback to localStorage for non-authenticated users
      dispatch({ type: 'CLEAR_CART' });
      localStorage.removeItem('shopping-cart');
    }
  };

  const getItemQuantity = (productId: string): number => {
    const item = state.items.find(item => item.productId === productId);
    return item ? item.quantity : 0;
  };

  const cart: Cart = {
    items: state.items,
    totalItems: state.totalItems,
    totalPrice: state.totalPrice,
  };

  const value: CartContextType = {
    cart,
    addToCart,
    removeFromCart,
    updateQuantity,
    clearCart,
    getItemQuantity,
  };

  return (
    <CartContext.Provider value={value}>
      {children}
    </CartContext.Provider>
  );
};

// Custom hook to use cart context
export const useCart = (): CartContextType => {
  const context = useContext(CartContext);
  if (context === undefined) {
    throw new Error('useCart must be used within a CartProvider');
  }
  return context;
};