import { store } from "@/store";
import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket";
import orderApi from "@/api/order/order";
import { useUserStoreHook } from "@/store/modules/user";
const shopUser = useUserStoreHook();

import { customTruncateToTwoDecimals } from '@/utils/tools'
import productApi from "@/api/product/index";

export interface CartsState {
  id: string | number;
  [property: string]: any;
}

export const useCartsStore = defineStore("carts", () => {
  //选择用户
  const vipUser = ref<{ id?: string | number, isVip?: boolean }>({});
  function changeUser(user: any) {
    vipUser.value = user;
  }

  //就餐类型 dine-in take-out
  let dinnerType = ref<string>('dine-in');



  //是否启用会员价
  const useVipPrice = computed(() => {
    return (shopUser.userInfo.isMemberPrice && vipUser.value.id && vipUser.value.isVip) ? true : false
  })

  //台桌id
  // const table_code = useStorage('Instead_table_code', '');
  const table_code = ref('')

  //购物车是否初始化连接加载完成
  const isLinkFinshed = ref(false)
  //当前购物车数据
  const list = useStorage<any[]>("carts", []);
  //历史订单数据
  const oldOrder = useStorage<any>("Instead_olold_order", {
    detailMap: [],
    originAmount: 0
  });

  //代客下单页面商品缓存
  const goods = useStorage<any[]>("Instead_goods", []);
  async function getGoods(query: any) {
    const res = await productApi.getPage({
      page: 1,
      size: 999,
      status: "on_sale",
      ...query,
    });
    goods.value = res.records;
    setGoodsMap(goods.value)
  }

  function setGoodsMap(goods: any[]) {
    for (let item of goods) {
      goodsMap[item.id] = item;
    }

  }

  //赠菜
  const giftList = useStorage<any[]>("giftList", []);
  let goodsMap: { [key: string]: any } = useStorage('Instead_goods_map', {});
  //当前选中cart
  let selListIndex = ref(-1);

  //当前选中商品是否是赠菜
  const isSelGift = ref(false);
  //当前选中是否是历史订单
  const isOldOrder = ref(false);
  //选中历史订单中的第几次下单
  const selPlaceNum = ref(-1);
  const defaultCart = {
    id: '',
    number: 0,
  }
  //购物车是否为空
  const isEmpty = computed(() => {
    return list.value.length === 0 && giftList.value.length === 0
  })
  //当前购物车选中数据
  const selCart = computed(() => {
    if (isOldOrder.value && selPlaceNum.value >= 0) {
      return oldOrder.value.detailMap[selPlaceNum.value][selListIndex.value]
    }
    if (isSelGift.value) {
      return giftList.value[selListIndex.value] || defaultCart
    }
    return list.value[selListIndex.value] || defaultCart
  })
  //当前购物车选中对应商品数据
  const selGoods = computed(() => {
    return goodsMap[selCart.value.product_id]
  })
  //当前选中购物车数据是否是可选套餐商品
  const isCanSelectGroup = computed(() => {
    if (!selGoods.value) {
      return false
    }
    return selGoods.value.type == 'package' && selGoods.value.groupType == 1
  })
  function returnOneGoodsTotalMoney(cur: any) {
    const memberPrice = cur.memberPrice || cur.salePrice
    const total = cur.number * (useVipPrice.value ? memberPrice : cur.salePrice)
    if (cur.type == 'weight') {
      return customTruncateToTwoDecimals(total)
    } else {
      return total
    }
  }
  //赠菜总价
  const giftMoney = computed(() => {
    let oldGiftMoney = 0
    for (let i in oldOrder.value.detailMap) {
      oldGiftMoney += oldOrder.value.detailMap[i].filter((v: any) => v.isGift).reduce((prve: number, cur: any) => {
        const memberPrice = cur.memberPrice || cur.salePrice
        return prve + cur.number * (useVipPrice.value ? memberPrice : cur.salePrice)
      }, 0)
    }
    const nowTotal = giftList.value.reduce((acc: number, cur: any) => {
      const memberPrice = cur.memberPrice || cur.salePrice
      return acc + cur.number * (useVipPrice.value ? memberPrice : cur.salePrice)
    }, 0)
    return (nowTotal + oldGiftMoney)
  })
  //返回打包数量（称重商品打包数量最大为1）
  function returnCartPackNumber(cur: any) {
    console.log(cur)
    let pack_number = (dinnerType.value == 'take-out' ? cur.number : cur.pack_number * 1)
    pack_number = (cur.product_type == 'weight' && pack_number > 1) ? 1 : pack_number;
    return pack_number * 1
  }
  //打包数量
  const packNum = computed(() => {
    const nowCartNumber = list.value.reduce((acc: number, cur: any) => {
      return acc + returnCartPackNumber(cur)
    }, 0)
    const giftNumber = giftList.value.reduce((acc: number, cur: any) => {
      return acc + returnCartPackNumber(cur)
    }, 0)
    let oldNumber = 0
    for (let i in oldOrder.value.detailMap) {
      oldNumber += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
        return prve + returnCartPackNumber(cur)
      }, 0)
    }
    return nowCartNumber + giftNumber + oldNumber
  })

  //打包费
  const packFee = computed(() => {
    const nowPackFee = list.value.reduce((acc: number, cur: any) => {
      return acc + (cur.packFee || 0) * returnCartPackNumber(cur)
    }, 0)
    const giftPackFee = giftList.value.reduce((acc: number, cur: any) => {
      return acc + (cur.packFee || 0) * returnCartPackNumber(cur)
    }, 0)
    let oldPackfee = 0;
    for (let i in oldOrder.value.detailMap) {
      oldPackfee += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
        return prve + (cur.packFee || 0) * returnCartPackNumber(cur)
      }, 0)
    }
    return nowPackFee + giftPackFee + oldPackfee
  })
  //会员优惠
  const vipDiscount = computed(() => {
    if (!useVipPrice.value) {
      return 0
    }
    const listTotal = list.value.reduce((acc: number, cur: any) => {
      const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number
      return acc + (n <= 0 ? 0 : n)
    }, 0)
    const giftTotal = giftList.value.reduce((acc: number, cur: any) => {
      const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number
      return acc + (n <= 0 ? 0 : n)
    }, 0)
    let oldTotal = 0;
    for (let i in oldOrder.value.detailMap) {
      oldTotal += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
        const n = (cur.salePrice * 1 - cur.memberPrice * 1) * cur.number
        return prve + (n <= 0 ? 0 : n)
      }, 0)
    }
    return listTotal + giftTotal + oldTotal
  })
  //单品改价优惠
  const singleDiscount = computed(() => {
    const listTotal = list.value.reduce((acc: number, cur: any) => {
      if (cur.discount_sale_amount * 1 <= 0) {
        return acc + 0
      }
      const originPrice = useVipPrice.value ? (cur.memberPrice || cur.salePrice) : cur.salePrice
      const n = (originPrice * 1 - cur.discount_sale_amount * 1) * cur.number
      return acc + (n <= 0 ? 0 : n)
    }, 0)
    return listTotal
  })


  // 优惠
  const yiyouhui = computed(() => {
    const youhui = giftMoney.value * 1 + vipDiscount.value * 1 + singleDiscount.value * 1
    if (youhui > 0) {
      return '已优惠￥' + youhui.toFixed(2)
    }
    return ''
  })

  //历史订单价格
  const oldOrderMoney = computed(() => {
    let total = 0
    for (let i in oldOrder.value.detailMap) {
      total += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
        if (cur.isGift) {
          return prve + 0
        }
        const discount_sale_amount = cur.discount_sale_amount * 1 || 0
        const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
        const price = (discount_sale_amount || cur.salePrice || 0)
        const number = (cur.number - cur.returnNum)
        return prve + (number <= 0 ? 0 : number) * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
      }, 0)
    }
    return total
  })


  //支付总价
  const payMoney = computed(() => {
    const money = list.value.reduce((acc: number, cur: any) => {
      const discount_sale_amount = cur.discount_sale_amount * 1 || 0
      const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
      const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
      return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
    }, 0)
    return (money + packFee.value + oldOrderMoney.value * 1).toFixed(2)
  })
  //只算商品的总价
  const goodsTotal = computed(() => {
    const money = list.value.reduce((acc: number, cur: any) => {
      const discount_sale_amount = cur.discount_sale_amount * 1 || 0
      const memberPrice = cur.skuData ? (cur.skuData.memberPrice || cur.skuData.salePrice) : 0
      const price = (cur.discount_sale_amount * 1 || cur.salePrice || 0)
      return acc + cur.number * (discount_sale_amount || (useVipPrice.value ? memberPrice : price))
    }, 0)
    return (money + oldOrderMoney.value * 1).toFixed(2)
  })
  //总计数量
  const totalNumber = computed(() => {
    const cartNumber = list.value.reduce((acc: number, cur: any) => {
      return acc + cur.number * 1
    }, 0)
    const giftNumber = list.value.reduce((acc: number, cur: any) => {
      return acc + cur.number * 1
    }, 0)
    let oldNumber = 0

    for (let i in oldOrder.value.detailMap) {
      oldNumber += oldOrder.value.detailMap[i].reduce((prve: number, cur: any) => {
        return prve + cur.number * 1
      }, 0)
    }
    return cartNumber + giftNumber + oldNumber
  })


  function changeNumber(step: number, item: CartsState) {
    if (item.number * 1 + step <= 0) {
      del(item);
      return;
    }
    const newNumber = item.number * 1 + step * 1;
    let pack_number = newNumber < item.pack_number ? (item.pack_number * 1 + step * 1) : item.pack_number;
    if (dinnerType.value == 'take-out') {
      pack_number = newNumber
    }
    if (item.product_type == 'weight') {
      pack_number = 1
    }
    update({ ...item, number: newNumber, pack_number });
  }

  function changeSelCart(cart: CartsState) {
    console.log(cart)
    if (!cart.id) {
      return
    }
    if (cart.placeNum) {
      selPlaceNum.value = cart.placeNum
      isOldOrder.value = true
      console.log(oldOrder.value.detailMap[cart.placeNum])
      selListIndex.value = oldOrder.value.detailMap[cart.placeNum].findIndex((item: CartsState) => {
        return item.id == cart.id
      })
      return
    }
    if (cart.is_gift) {
      isSelGift.value = true
    } else {
      isSelGift.value = false
    }

    if (cart.is_gift) {
      isSelGift.value = true
      selListIndex.value = giftList.value.findIndex((item: CartsState) => item.id === cart.id);
      console.log(selListIndex.value)

    } else {
      isSelGift.value = false
      selListIndex.value = list.value.findIndex((item: CartsState) => item.id === cart.id);
    }
  }


  const basic_msg = {
    number: 1,
    is_gift: 0,
    is_temporary: 0,
    discount_sale_amount: 0,
    discount_sale_note: "",
    is_print: 1,
    pro_group_info: '',
    is_wait_call: 0,
    product_name: "",
    remark: "",
    sku_id: '',
    product_type: ''
  }
  //当前购物车直接添加
  function cartsPush(data: any) {
    sendMessage('add', {
      ...basic_msg,
      ...data
    });
  }

  function add(data: any) {
    const msg = {
      ...basic_msg,
      ...data
    }
    const hasCart = list.value.find((cartItem) => {
      return cartItem.product_id == msg.product_id && cartItem.sku_id == msg.sku_id;
    });
    if (hasCart) {
      update({ ...hasCart, ...msg, number: hasCart.number * 1 + msg.number * 1 })
    } else {
      console.log(msg);
      sendMessage('add', msg);
    }
  }

  // 换桌
  function changeTable(newVal: string | undefined) {
    table_code.value = `${newVal}`;
    $initParams.table_code = newVal
    concocatSocket()
  }
  //转桌
  function rotTable(newVal: string | number, cart_id = []) {
    sendMessage('rottable', {
      new_table_code: newVal,
      table_code: table_code.value,
      cart_id
    });
  }


  function del(data: any) {
    sendMessage('del', { id: data.id });
  }

  function update(data: any) {
    console.log(data);
    const suitNum = data.skuData ? (data.skuData.suitNum || 1) : 1;
    if (data.number * 1 < suitNum * 1) {
      return sendMessage('del', data);
    }
    const pack_number = dinnerType.value == 'take-out' ? data.number : data.pack_number
    sendMessage('edit', { ...data, pack_number });
  }
  function updateTag(key: string, val: any, cart: CartsState = selCart.value) {
    const skuData = cart.skuData || { suitNum: 1 }
    if (cart.number * 1 < skuData.suitNum * 1) {
      return sendMessage('del', cart);
    }
    console.log(key, val)
    if (key == 'discount_sale_amount' && val * 1 <= 0) {
      return ElMessage.error('价格不能为0！')
    }
    const msg = { ...cart, [key]: val }
    if (key == 'number' && dinnerType.value == 'take-out') {
      msg.pack_number == val
    }

    sendMessage('edit', msg);
  }
  // 更改全部商品打包状态
  function changePack(is_pack: number | string) {
    if (!isEmpty.value) {
      sendMessage('batch', { is_pack });
    }
  }

  function clear() {
    sendMessage('cleanup', {});
  }
  function dataReset() {
    selListIndex.value = -1;
    selPlaceNum.value = 1
    isOldOrder.value = false
    isSelGift.value = false
    list.value = [];
    giftList.value = [];
    oldOrder.value = {
      detailMap: [],
      originAmount: 0
    }
    vipUser.value = {}
  }

  function nowCartsClear() {
    if (selPlaceNum.value == 1) {
      selListIndex.value = -1;
    }
    list.value = [];
    giftList.value = [];
  }

  // 寻找套餐商品sku
  interface GroupSnap {
    goods: { [key: string]: any }[];
  }

  function findInGroupSnapSku(groupSnap: GroupSnap[], sku_id: string | number) {
    for (let i in groupSnap) {
      const sku = groupSnap[i].goods.find(v => v.sku_id == sku_id)
      if (sku) {
        return sku
      }
    }
  }

  //获取历史订单
  async function getOldOrder(table_code: string | number) {
    const res = await orderApi.getHistoryList({ tableCode: table_code })
    if (res) {
      setOldOrder(res)
    }
  }

  function getProductDetails(v: { product_id: string, sku_id: string }) {
    const goods = goodsMap[v.product_id]
    if (!goods) {
      return undefined
    }
    let skuData = undefined;
    skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => sku.id == v.sku_id);

    // if (goods.type == 'package') {
    //   //套餐商品
    //   const SnapSku = findInGroupSnapSku(goods.groupSnap, v.sku_id)
    //   skuData = { ...SnapSku, salePrice: SnapSku ? SnapSku.price : 0 }
    // } else {
    //   skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => sku.id == v.sku_id);
    // }
    skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => sku.id == v.sku_id);

    if (skuData) {
      return {
        salePrice: skuData ? skuData.salePrice : 0,
        memberPrice: skuData ? skuData.memberPrice : 0,
        coverImg: goods.coverImg,
        name: goods.name,
        specInfo: skuData.specInfo,
        packFee: goods.packFee || 0,
        type: goods.type,
        skuData
      }
    } else {
      return undefined
    }
  }

  function returnDetailMap(data: any) {
    const newData: { [key: string]: any } = {}
    for (let i in data) {
      newData[i] = data[i].map((v: any) => {
        const skuData = getProductDetails({ product_id: v.productId, sku_id: v.skuId })
        return {
          ...v,
          ...skuData,
          placeNum: v.placeNum,
          number: v.num,
          id: v.id,
          pack_number: v.packNumber,
          discount_sale_amount: v.discountSaleAmount * 1 || 0,
          is_print: v.isPrint,
          is_wait_call: v.isWaitCall,
          is_gift: v.isGift,
          is_temporary: v.isTemporary,
          discount_sale_note: v.discountSaleNote,
          product_name: v.productName,
          sku_name: v.skuName,
          sku_id: v.skuId,
          product_type: v.productType
        }
      })
    }
    return newData
  }

  function setOldOrder(data: any) {
    oldOrder.value = {
      ...data,
      detailMap: returnDetailMap(data.detailMap)
    }
  }

  let $initParams = {} as ApifoxModel


  /**
   * 
   * @param initParams 购物车初始化参数
   * @param $goodsMap 商品id对应的map
   * @param oldOrder 历史订单数据
   */



  async function init(initParams: ApifoxModel, $oldOrder: any | undefined) {
    // 商品id对应的数据map
    await getGoods({})

    if ($oldOrder) {
      setOldOrder($oldOrder)
    } else {
      oldOrder.value = { detailMap: [] }
    }

    // console.log('oldOrder.detailMap', oldOrder.value.detailMap)
    // const cache_table_code = localStorage.getItem('cache_table_code');
    // const randomTableCode = cache_table_code ? cache_table_code : ('APC' + (1000 + Math.floor(Math.random() * 9000)))
    if (initParams) {
      initParams.table_code = initParams.table_code ? initParams.table_code : ''
      table_code.value = initParams.table_code
      $initParams = initParams;
    }
    console.log($initParams)
    // localStorage.setItem('cache_table_code', table_code.value);
    concocatSocket($initParams)
  }

  function concocatSocket(initParams = $initParams) {
    console.log("初始化参数", initParams);
    WebSocketManager.subscribeToTopic(initParams, (msg) => {
      console.log("收到消息：", msg);
      if (msg.hasOwnProperty('status') && msg.status != 1) {
        return ElMessage.error(msg.message || '操作失败')
      }
      if (msg && msg.data) {
        if (Array.isArray(msg.data) && msg.data.length && msg.data[0].table_code) {
          table_code.value = msg.data[0].table_code
        }
        if (msg.data.table_code) {
          table_code.value = table_code.value ? table_code.value : msg.data.table_code
        }
        if (msg.table_code) {
          table_code.value = table_code.value ? table_code.value : msg.table_code

        }

      }


      // 初始化
      if (msg.operate_type === "manage_init") {
        isLinkFinshed.value = true
        // 设置单价
        list.value = msg.data.filter((v: Record<string, any>) => {
          if (v.is_temporary) {
            return v
          }
          const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id })
          if (skuData) {
            (Object.keys(skuData) as (keyof typeof skuData)[]).forEach((key) => {
              v[key] = skuData[key];
            });
          } else {
            del({ id: v.id })
            return false
          }
          return !v.is_gift
        })
        giftList.value = msg.data.filter((v: Record<string, any>) => {
          if (v.is_temporary) {
            return v && v.is_gift
          }
          const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id })
          if (skuData) {
            (Object.keys(skuData) as (keyof typeof skuData)[]).forEach((key) => {
              v[key] = skuData[key];
            });
          } else {
            del({ id: v.id })
            return false
          }
          return v.is_gift
        })
      }
      //广播
      if (msg.type === "bc") {
        msg.operate_type = 'manage_' + msg.operate_type
      }
      if (msg.operate_type === "manage_add") {
        if (list.value.find(v => v.id == msg.data.id)) {
          return ElMessage.warning(msg.message || '该商品已存在')
        }
        const skuData = getProductDetails({ product_id: msg.data.product_id, sku_id: msg.data.sku_id })
        const newGoods = { ...skuData, ...msg.data }
        console.log('newGoods', newGoods)
        list.value.push(newGoods)
        return ElMessage.success(msg.message || '添加成功')

      }
      if (msg.operate_type === "manage_edit") {
        const newCart = msg.data
        const index = list.value.findIndex((item) => item.id === newCart.id)
        const giftIndex = giftList.value.findIndex((item) => item.id === newCart.id)
        const cartItem = list.value[index] || { is_gift: false };
        const giftItem = giftList.value[giftIndex];

        if (giftItem) {
          //操作赠菜
          if (!newCart.is_gift) {
            giftList.value.splice(giftIndex, 1)
            list.value.push({ ...giftItem, ...newCart })
            selListIndex.value = -1
          } else {
            giftList.value[giftIndex] = { ...giftItem, ...newCart }
          }
        }
        if (cartItem) {
          //操作非赠菜
          if (newCart.is_gift) {
            list.value.splice(index, 1)
            giftList.value.push({ ...cartItem, ...newCart })
            selListIndex.value = -1
          } else {
            list.value[index] = { ...cartItem, ...newCart }
          }
        }
        ElMessage.success(msg.message || '修改成功')
      }
      if (msg.operate_type === "manage_del") {
        const cartId = Array.isArray(msg.data) ? msg.data[0].id : msg.data.id
        const listIndex = list.value.findIndex((item) => item.id == cartId)
        if (listIndex > -1) {
          list.value.splice(listIndex, 1)
        }
        const giftIndex = giftList.value.findIndex((item) => item.id == cartId)
        if (giftIndex > -1) {
          giftList.value.splice(giftIndex, 1)
        }
        return ElMessage.success(msg.message || '删除成功')
      }
      if (msg.operate_type === "manage_cleanup") {
        nowCartsClear()
        getOldOrder(msg.data.table_code)
      }
      if (msg.operate_type === "batch") {
        concocatSocket({ ...$initParams, table_code: table_code.value })
      }
      if (msg.operate_type === "product_update") {
        console.log('商品更新')
        init($initParams, oldOrder.value)
      }
    });
  }

  function disconnect() {
    sendMessage('disconnect', undefined)
  }

  const delArr = ['skuData', 'coverImg', 'specInfo', 'placeNum', 'update_time', 'create_time', 'packFee', 'memberPrice', 'type']
  function sendMessage(operate_type: msgType, message: any) {
    const msg = { ...message, operate_type: operate_type, table_code: table_code.value }
    for (let i in delArr) {
      delete msg[delArr[i]]
    }
    console.log('send msg', msg)
    WebSocketManager.sendMessage(msg);
  }
  return {
    disconnect,
    dinnerType,
    changePack,
    giftMoney,
    goodsTotal,
    isLinkFinshed,
    setOldOrder,
    singleDiscount,
    vipDiscount,
    dataReset,
    useVipPrice,
    changeUser,
    packNum, packFee,
    isOldOrder,
    oldOrder,
    isCanSelectGroup,
    goods,
    selGoods,
    cartsPush,
    table_code,
    updateTag,
    list,
    add,
    del,
    update,
    init,
    changeNumber, isEmpty,
    selCart, totalNumber,
    changeSelCart, payMoney,
    clear, yiyouhui, giftList,
    changeTable,
    rotTable,
    getGoods,
    setGoodsMap
  };
});

export function useCartsStoreHook() {
  return useCartsStore(store);
}
