import React, { createContext, useContext, useState, useCallback, type ReactNode } from 'react'
import Taro from '@tarojs/taro'
import { listShopCart, addToCart, updateCartNum, removeShopCart, removeBatchShopCart, updateCartAllChecked } from '@/api/shop/shopCart'
import type { ShopGoods, ShopGoodsSku } from '@/api/shop/shopGoods/model'

export interface CartItem {
  id?: number
  goodsId: number
  skuId?: number
  quantity: number
  product?: ShopGoods
  sku?: ShopGoodsSku
  checked?: boolean
  // 后端返回的字段
  goodsName?: string
  goodsImage?: string
  skuPrice?: string
  skuSpec?: string
  stock?: number
}

interface CartContextType {
  items: CartItem[]
  totalCount: number
  totalPrice: string
  selectedItems: CartItem[]
  selectedCount: number
  selectedPrice: string
  loading: boolean
  refresh: () => Promise<void>
  addItem: (product: ShopGoods, sku?: ShopGoodsSku, quantity?: number) => Promise<void>
  removeItem: (goodsId: number, skuId?: number) => Promise<void>
  updateQuantity: (goodsId: number, skuId: number | undefined, quantity: number) => Promise<void>
  toggleSelect: (goodsId: number, skuId: number | undefined) => Promise<void>
  selectAll: (checked: boolean) => Promise<void>
  clearCart: () => Promise<void>
  getItemQuantity: (goodsId: number, skuId?: number) => number
  // 删除选中的商品
  removeSelected: () => Promise<void>
}

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

export const CartProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [items, setItems] = useState<CartItem[]>([])
  const [loading, setLoading] = useState(false)

  // 刷新购物车数据
  const refresh = useCallback(async () => {
    setLoading(true)
    try {
      const data = await listShopCart()
      // 防御性检查：确保返回的是数组
      const safeData = Array.isArray(data) ? data : []
      // 转换为前端格式，默认都选中
      const mappedItems: CartItem[] = safeData.map(item => ({
        id: item.id,
        goodsId: item.goodsId!,
        skuId: item.skuId,
        quantity: item.num || 1,
        goodsName: item.goodsName,
        goodsImage: item.goodsImage,
        skuPrice: item.skuPrice,
        skuSpec: item.skuSpec,
        stock: item.stock,
        checked: true,
      }))
      setItems(mappedItems)
    } catch (err) {
      console.error('刷新购物车失败', err)
      setItems([])
    } finally {
      setLoading(false)
    }
  }, [])

  // 添加商品到购物车
  const addItem = useCallback(async (product: ShopGoods, sku?: ShopGoodsSku, quantity = 1) => {
    try {
      const params = {
        goodsId: product.goodsId!,
        num: quantity,
      } as Record<string, unknown>
      // 只有多规格商品才传 skuId，且不能为 0
      if (sku?.id && sku.id > 0) {
        params.skuId = sku.id
      }
      await addToCart(params)
      Taro.showToast({ title: '已加入购物车', icon: 'success' })
      // 刷新购物车
      await refresh()
    } catch (err: any) {
      console.error('[CartContext] 添加失败:', err)
      Taro.showToast({ title: err.message || '添加失败', icon: 'none' })
      throw err
    }
  }, [refresh])

  // 删除商品
  const removeItem = useCallback(async (goodsId: number, skuId?: number) => {
    const item = items.find(i => i.goodsId === goodsId && i.skuId === skuId)
    if (!item?.id) return

    try {
      await removeShopCart(item.id)
      // 本地更新
      setItems(prev => prev.filter(i => !(i.goodsId === goodsId && i.skuId === skuId)))
    } catch (err: any) {
      Taro.showToast({ title: err.message || '删除失败', icon: 'none' })
    }
  }, [items])

  // 更新数量
  const updateQuantity = useCallback(async (goodsId: number, skuId: number | undefined, quantity: number) => {
    if (quantity <= 0) {
      await removeItem(goodsId, skuId)
      return
    }

    const item = items.find(i => i.goodsId === goodsId && i.skuId === skuId)
    if (!item?.id) return

    try {
      await updateCartNum({ id: item.id, num: quantity })
      // 本地更新
      setItems(prev => prev.map(i =>
        (i.goodsId === goodsId && i.skuId === skuId) ? { ...i, quantity } : i
      ))
    } catch (err: any) {
      Taro.showToast({ title: err.message || '更新失败', icon: 'none' })
    }
  }, [items, removeItem])

  // 切换选中状态
  const toggleSelect = useCallback(async (goodsId: number, skuId: number | undefined) => {
    const item = items.find(i => i.goodsId === goodsId && i.skuId === skuId)
    if (!item || !item.id) return

    const newChecked = !item.checked
    // 本地立即更新
    setItems(prev => prev.map(i =>
      (i.goodsId === goodsId && i.skuId === skuId) ? { ...i, checked: newChecked } : i
    ))
    
    // 同步到后端
    try {
      await updateCartChecked(item.id, newChecked)
    } catch (err) {
      // API失败时回滚本地状态
      setItems(prev => prev.map(i =>
        (i.goodsId === goodsId && i.skuId === skuId) ? { ...i, checked: !newChecked } : i
      ))
      console.error('更新选中状态失败', err)
    }
  }, [items])

  // 全选/取消全选
  const selectAll = useCallback(async (checked: boolean) => {
    // 本地立即更新
    setItems(prev => prev.map(i => ({ ...i, checked })))
    // 尝试调用API
    try {
      await updateCartAllChecked(checked)
    } catch (err) {
      // API失败时静默处理，本地状态已更新
    }
  }, [])

  // 清空购物车
  const clearCart = useCallback(async () => {
    try {
      await removeBatchShopCart(items.map(i => i.id!).filter(Boolean))
      setItems([])
    } catch (err: any) {
      Taro.showToast({ title: err.message || '清空失败', icon: 'none' })
    }
  }, [items])

  // 删除选中的商品
  const removeSelected = useCallback(async () => {
    const selected = items.filter(i => i.checked && i.id)
    if (selected.length === 0) return

    try {
      await removeBatchShopCart(selected.map(i => i.id!))
      setItems(prev => prev.filter(i => !i.checked))
      Taro.showToast({ title: `已删除${selected.length}件商品`, icon: 'success' })
    } catch (err: any) {
      Taro.showToast({ title: err.message || '删除失败', icon: 'none' })
    }
  }, [items])

  const getItemQuantity = useCallback((goodsId: number, skuId?: number): number => {
    return items.find(i => i.goodsId === goodsId && i.skuId === skuId)?.quantity || 0
  }, [items])

  const calcPrice = (list: CartItem[]) =>
    list.reduce((sum, i) => sum + Number(i.skuPrice || i.sku?.price || i.product?.salePrice || i.product?.price || 0) * i.quantity, 0).toFixed(2)

  const selectedItems = items.filter(i => i.checked)
  const selectedCount = selectedItems.reduce((s, i) => s + i.quantity, 0)

  return (
    <CartContext.Provider
      value={{
        items,
        totalCount: items.reduce((s, i) => s + i.quantity, 0),
        totalPrice: calcPrice(items),
        selectedItems,
        selectedCount,
        selectedPrice: calcPrice(selectedItems),
        loading,
        refresh,
        addItem,
        removeItem,
        updateQuantity,
        toggleSelect,
        selectAll,
        clearCart,
        getItemQuantity,
        removeSelected,
      }}
    >
      {children}
    </CartContext.Provider>
  )
}

export const useCartContext = (): CartContextType => {
  const context = useContext(CartContext)
  if (!context) throw new Error('useCartContext must be used within CartProvider')
  return context
}
