'use client'

import { createContext, useContext, useReducer, useState, ReactNode, useEffect } from 'react'
import { CartItem, CartState } from '@/lib/shop'

type CartAction =
  | { type: 'ADD_ITEM'; payload: Omit<CartItem, 'lineTotal'> }
  | { type: 'REMOVE_ITEM'; payload: string }
  | { type: 'UPDATE_QUANTITY'; payload: { productId: string; quantity: number } }
  | { type: 'CLEAR_CART' }
  | { type: 'LOAD_CART'; payload: CartState }

const CART_STORAGE_KEY = 'imbaraga_cart'

function recalc(items: CartItem[]): CartState {
  return {
    items,
    subtotal: items.reduce((sum, i) => sum + i.lineTotal, 0),
    itemCount: items.reduce((sum, i) => sum + i.quantity, 0),
  }
}

function cartReducer(state: CartState, action: CartAction): CartState {
  switch (action.type) {
    case 'ADD_ITEM': {
      const existingIndex = state.items.findIndex(item => item.productId === action.payload.productId)
      if (existingIndex >= 0) {
        const newItems = [...state.items]
        const newQuantity = newItems[existingIndex].quantity + action.payload.quantity
        newItems[existingIndex] = {
          ...newItems[existingIndex],
          quantity: newQuantity,
          lineTotal: newItems[existingIndex].unitPrice * newQuantity,
        }
        return recalc(newItems)
      }
      return recalc([
        ...state.items,
        { ...action.payload, lineTotal: action.payload.unitPrice * action.payload.quantity },
      ])
    }
    case 'REMOVE_ITEM':
      return recalc(state.items.filter(item => item.productId !== action.payload))
    case 'UPDATE_QUANTITY': {
      if (action.payload.quantity <= 0) {
        return recalc(state.items.filter(item => item.productId !== action.payload.productId))
      }
      return recalc(
        state.items.map(item =>
          item.productId === action.payload.productId
            ? { ...item, quantity: action.payload.quantity, lineTotal: item.unitPrice * action.payload.quantity }
            : item
        ),
      )
    }
    case 'CLEAR_CART':
      return { items: [], subtotal: 0, itemCount: 0 }
    case 'LOAD_CART':
      return recalc(action.payload.items)
    default:
      return state
  }
}

interface CartContextType {
  state: CartState
  itemCount: number
  addItem: (item: Omit<CartItem, 'lineTotal'>) => void
  removeItem: (productId: string) => void
  updateQuantity: (productId: string, quantity: number) => void
  clearCart: () => void
}

const CartContext = createContext<CartContextType | undefined>(undefined)

function calculateSubtotal(items: CartItem[]): number {
  return items.reduce((sum, item) => sum + item.lineTotal, 0)
}

function calculateItemCount(items: CartItem[]): number {
  return items.reduce((sum, item) => sum + item.quantity, 0)
}

function loadCartFromStorage(): CartState {
  if (typeof window === 'undefined') return { items: [], subtotal: 0, itemCount: 0 }
  try {
    const stored = localStorage.getItem(CART_STORAGE_KEY)
    if (stored) {
      const parsed = JSON.parse(stored)
      return recalc(parsed.items || [])
    }
  } catch {}
  return { items: [], subtotal: 0, itemCount: 0 }
}

function saveCartToStorage(state: CartState) {
  if (typeof window === 'undefined') return
  try {
    localStorage.setItem(CART_STORAGE_KEY, JSON.stringify(state))
  } catch {}
}

export function CartProvider({ children }: { children: ReactNode }) {
  const [state, dispatch] = useReducer(cartReducer, { items: [], subtotal: 0, itemCount: 0 })
  const [hydrated, setHydrated] = useState(false)

  useEffect(() => {
    const loaded = loadCartFromStorage()
    if (loaded.items.length > 0) {
      dispatch({ type: 'LOAD_CART', payload: loaded })
    }
    setHydrated(true)
  }, [])

  useEffect(() => {
    if (hydrated) saveCartToStorage(state)
  }, [state, hydrated])

  const addItem = (item: Omit<CartItem, 'lineTotal'>) => {
    dispatch({ type: 'ADD_ITEM', payload: item })
  }

  const removeItem = (productId: string) => {
    dispatch({ type: 'REMOVE_ITEM', payload: productId })
  }

  const updateQuantity = (productId: string, quantity: number) => {
    dispatch({ type: 'UPDATE_QUANTITY', payload: { productId, quantity } })
  }

  const clearCart = () => {
    dispatch({ type: 'CLEAR_CART' })
  }

  const itemCount = state.items.reduce((sum, i) => sum + i.quantity, 0)

  return (
    <CartContext.Provider
      value={{
        state,
        itemCount,
        addItem,
        removeItem,
        updateQuantity,
        clearCart,
      }}
    >
      {children}
    </CartContext.Provider>
  )
}

export function useCart() {
  const context = useContext(CartContext)
  if (!context) {
    throw new Error('useCart must be used within a CartProvider')
  }
  return context
}