<template>
  <view class="u-wrap">
    <view
      class="u-fixed position-all"
      style="z-index: 999"
      v-if="!canXiadan"
      @click="xiadanClick"
    ></view>
    <view class="top bg-fff w-full">
      <template v-if="option.type != 'add'">
        <view class="u-flex u-row-between choose-user" @tap="chooseTable">
          <view>
            <view v-if="!data.table.id">选择桌台</view>
            <view class="u-flex" v-else>
              <view class="u-m-l-20">{{ data.table.name }}</view>
            </view>
          </view>
          <view class="u-flex">
            <uni-icons type="right" size="20" color="#999"></uni-icons>
          </view>
        </view>
      </template>

      <view class="search u-flex u-col-center">
        <view class="u-flex-1">
          <uni-search-bar
            bgColor="#F9F9F9"
            cancelButton="none"
            placeholder="搜索店内商品"
            @confirm="search"
            @clear="clearSearch"
            v-model="searchValue"
          ></uni-search-bar>
        </view>
        <view class="u-flex" @click="scanCode">
          <image
            src="/pagesCreateOrder/static/images/icon-saoma.svg"
            class="icon-saoma"
            mode=""
          ></image>
        </view>
      </view>
    </view>
    <template v-if="!isSearch">
      <view class="u-menu-wrap">
        <scroll-view
          scroll-y
          scroll-with-animation
          class="u-tab-view menu-scroll-view"
          :scroll-top="data.scrollTop"
          :scroll-into-view="data.itemId"
        >
          <view
            v-for="(item, index) in data.tabbar"
            :key="index"
            class="u-tab-item"
            :class="[data.current == index ? 'u-tab-item-active' : '']"
            @tap.stop="swichMenu(index)"
          >
            <text class="u-line-3">{{ item.name }}</text>
          </view>
        </scroll-view>
        <scroll-view
          :scroll-top="data.scrollRightTop"
          scroll-y
          scroll-with-animation
          class="right-box"
          @scroll="rightScroll"
        >
          <view class="page-view u-p-l-24">
            <view class="list-tight-top">
              <template v-if="lingshi.show">
                <view id="lingshi" class="lingshi u-m-b-32" @tap="toLinshi">
                  <uni-icons
                    type="plus-filled"
                    size="24"
                    :color="$utils.ColorMain"
                  ></uni-icons>
                  <view class="u-m-t-24 color-main">临时菜</view>
                </view>
              </template>
              <template v-else>
                <view style="height: 24px"></view>
              </template>
            </view>
            <view
              class="class-item"
              :id="'item' + index"
              v-for="(item, index) in data.tabbar"
              :key="index"
            >
              <view
                class="item-title"
                :class="{ active: data.current == index }"
              >
                <text>{{ item.name }}</text>
              </view>
              <view class="item-container">
                <view
                  class="thumb-box"
                  v-for="(goodsItem, goodsIndex) in item.foods"
                  :key="goodsIndex"
                >
                  <list-goods-item
                    :limitTimeDiscount="data.limitTimeDiscount"
                    @chooseGuige="chooseGuige($event, index)"
                    @add="goodsUpdate($event, index, true)"
                    @reduce="goodsUpdate($event, index, false)"
                    @tapweigh="tapweigh($event, index)"
                    :index="goodsIndex"
                    :data="goodsItem"
                  ></list-goods-item>
                </view>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>
    </template>
    <template v-else>
      <view class="u-menu-wrap">
        <scroll-view class="u-flex-1" scroll-y scroll-with-animation>
          <view class="u-p-l-30 u-p-r-30">
            <view class="u-font-28 color-666">搜索</view>
            <view class="u-flex u-m-t-20 u-flex-wrap u-row-between">
              <view
                class="u-m-b-30"
                v-for="(goodsItem, goodsIndex) in searchResult"
                :key="goodsIndex"
              >
                <list-goods-item
                  :img="{ width: '330rpx', height: '330rpx' }"
                  :limitTimeDiscount="data.limitTimeDiscount"
                  @chooseGuige="
                    chooseGuige(goodsItem.goodsIndex, goodsItem.index)
                  "
                  @add="searchGoodsUpdate(goodsItem, goodsIndex, true)"
                  @reduce="searchGoodsUpdate(goodsItem, goodsIndex, false)"
                  @tapweigh="tapweigh(goodsItem.goodsIndex, goodsItem.index)"
                  :index="goodsItem.goodsIndex"
                  :data="goodsItem"
                ></list-goods-item>
              </view>
            </view>
            <my-img-empty
              v-if="!searchResult.length"
              tips="未搜索到相关商品"
            ></my-img-empty>
          </view>
        </scroll-view>
      </view>
    </template>

    <view class="bottom w-full">
      <my-car
        :isCreateOrderToDetail="isCreateOrderToDetail"
        @updateNumber="carsNumberChange"
        :table="data.table"
        :data="cars"
        :orderInfo="data.orderInfo"
        :limitTimeDiscount="data.limitTimeDiscount"
        @clear="cleaCart"
      ></my-car>
    </view>
    <!-- 套餐选择规格 -->
    <taocanModel
      ref="taocanModelRef"
      @confirm="taocanConfirm"
      :goodsData="selGoods"
    ></taocanModel>
    <!-- 选择规格 -->
    <guige-model
      @update-sku="updateSkuSel"
      :limitTimeDiscount="data.limitTimeDiscount"
      @confirm="guigeConfirm"
      ref="chooseGuigeModel"
      :goodsData="selGoods"
      :title="guigeModelData.title"
      :sku-map="guigeModelData.chooseGoods.skuMap"
      :skus="guigeModelData.chooseGoods.skus"
    ></guige-model>
    <!-- 称重 -->
    <weigh-item ref="refweighitem" @weighgoodsUpdate="goodsUpdate"></weigh-item>
    <!-- 历史订单按钮 -->
    <view
      class="history-button"
      v-if="data.historyOrderNum > 0 && data.table.id"
      @click="go.to('PAGES_ORDER_DETAIL', { id: data.orderInfo.id })"
    >
      <text>历史订单</text>
      <text class="num">{{ data.historyOrderNum }}</text>
    </view>
  </view>
</template>
<script setup>
import { onLoad, onReady, onShow, onUnload, onHide } from "@dcloudio/uni-app";
import {
  inject,
  computed,
  reactive,
  ref,
  nextTick,
  provide,
  watch,
  getCurrentInstance,
  onUnmounted,
  onBeforeUnmount,
} from "vue";

import guigeModel from "./components/guige";
import taocanModel from "./components/taocanModel.vue";
import weighItem from "./components/weigh.vue";
import listGoodsItem from "./components/list-goods-item.vue";
import myCar from "./components/car";

import util from "./util.js";
import go from "@/commons/utils/go.js";
import { getNowCart } from "@/pagesCreateOrder/util.js";
import storageManage from "@/commons/utils/storageManage.js";
import { hasPermission } from "@/commons/utils/hasPermission.js";
// import WebsocketUtil from '@/commons/utils/websocket.js';
import yskUtils from "ysk-utils";
import { getDiscountByUserId } from "@/http/api/market/consumeDiscount.js";
import { limitTimeDiscount } from "@/http/api/market/limitTimeDiscount.js";
provide("yskUtils", yskUtils);
const shopInfo=uni.getStorageSync("shopInfo");
provide("shopInfo", uni.getStorageSync("shopInfo"));

import { getShopTable, getShopTableDetail } from "@/http/api/table.js";
import { getProductList } from "@/http/api/product.js";
import { categoryPage } from "@/http/api/cateGory.js";
import { getShopInfo } from "@/http/api/shop.js";
import {
  getHistoryOrder,
  cancelOrder,
  rmPlaceOrder,
} from "@/http/api/order.js";

const modal = reactive({
  key: "",
  clear: false,
  data: "",
});
//临时菜
const lingshi = reactive({
  show: true,
});

const cars = reactive([]);
const data = reactive({
  scrollTop: 0, //tab标题的滚动条位置
  oldScrollTop: 0,
  current: 0, // 预设当前项的值
  menuHeight: 0, // 左边菜单的高度
  menuItemHeight: 0, // 左边菜单item的高度
  itemId: "", // 栏目右边scroll-view用于滚动的id
  tabbar: storageManage.cacheGoods() || [],
  menuItemPos: [],
  arr: [], //左右联动布局节点信息
  scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
  timer: null, // 定时器
  topZhanwei: 136 + 24,
  // 选择用户
  vipUser: {
    id: "",
  },

  table: {
    id: "",
  },
  socketData: {
    type: "onboc",
    account: uni.getStorageSync("iToken").loginId,
    shop_id: uni.getStorageSync("shopInfo").id,
    is_gift: 0,
  },
  orderId: null,
  isGoodsAdd: true,
  goodsData: null,
  orderInfo: null,
  historyOrder: [],
  historyOrderNum: 0,
  limitTimeDiscount: null, //限时折扣
});
const guigeModelData = reactive({
  title: "",
  chooseGoods: {
    skuMap: {},
    item: "",
    skus: [],
  },
});
const chooseGuigeModel = ref(null);
const cartItemId = ref(null);
let isCreateOrderToDetail = ref(false);
let option = {
  type: "",
};
const taocanModelRef = ref();
const websocketUtil = inject("websocketUtil"); // 注入 WebSocket 工具类实例

//限时折扣
const limitTimeDiscountRes = ref();
onLoad(async (opt) => {
  option = opt;
  Object.assign(data.table, opt);
  console.log(opt);
  uni.setNavigationBarTitle({
    title: opt && opt.type == "add" ? "顾客加菜" : "代客下单",
  });
  if (JSON.stringify(opt) == "{}") {
    isCreateOrderToDetail.value = true;
  }
  if (uni.getStorageSync("table_code") && !opt.tableCode) {
    data.table.tableCode = uni.getStorageSync("table_code");
  }

  const limitRes = await limitTimeDiscount({
    shopId: uni.getStorageSync("shopInfo").id || "",
  });
  limitTimeDiscountRes.value = limitRes;
  if (data.table.tableCode) {
    data.limitTimeDiscount = limitRes;
    websocketUtil.send(
      JSON.stringify({
        type: "shopping",
        operate_type: "time_discount_save",
        table_code: data.table.tableCode,
        shop_id: uni.getStorageSync("shopInfo").id,
        operate_type: "time_discount_save",
        data: limitTimeDiscountRes.value,
      })
    );
  }

  // init()
  xiadanClick();
});
watch(
  () => data.table.id,
  (newval, oldval) => {
    if (option.type != "add") {
      onSelTable();
    }
  }
);
onShow(() => {
  nextTick(() => {
    uni.showLoading({
      title: "购物车加载中",
      mask: true,
    });
    watchChooseTable();
    watchUpdate();
    watchSocketOpen();
    data.isGoodsAdd = true;

    init();
    onMessage();
  });
});
onReady(() => {
  getElRect("list-tight-top").then((res) => {
    data.topZhanwei = res.height;
  });
  getMenuItemTop();
});

onHide(() => {
  console.log("onHide");
  uni.$off("is-socket-open");
  websocketUtil.offMessage();
});
onUnmounted(() => {
  uni.$off("is-socket-open");
  websocketUtil.offMessage();
});

/**
 * 判断是否允许下单
 */
let canXiadan = ref(false);
async function xiadanClick() {
  canXiadan.value = await hasPermission("允许下单");
}

let $originGoods = [];
let $category = [];

async function init() {
  if (option.type == "add") {
    setTabBar($category, $originGoods, []);
  }
  let shopInfo = await getShopInfo({ id: uni.getStorageSync("shopInfo").id });
  uni.setStorageSync("shopInfo", shopInfo);
  // 获取分类数据
  let categoryRes = await categoryPage({ page: 1, size: 300 });
  $category = categoryRes.records;
  // 获取商品数据
  const goodsRes = await getGoods();
  const goods = goodsRes.filter((v) => {
    let isShow = true;
    if (v.type != "sku") {
      isShow = v.skuList.length >= 1;
    }
    return isShow;
  });
  $originGoods = goods;

  if (option.type == "add") {
    cars.length = 0;
    initCart();
    setTabBar($category, goods, []);
    return;
  }

  setTabBar($category, goods, cars);

  initCart();
}

/**
 * 获取订单详情
 */
async function getHistoryOrderDetail() {
  if(shopInfo.registerType==='before'){
    return 
  }
  data.historyOrder = [];
  let res = await getHistoryOrder({ tableCode: data.table.tableCode });
  data.orderInfo = res;
  if (res) {
    data.historyOrder = Object.entries(data.orderInfo.detailMap).map(
      ([key, value]) => ({
        info: value,
        placeNum: key,
      })
    );

    console.log("data.historyOrder===", data.historyOrder);

    let allHistoryOrder = data.historyOrder.map((item) => {
      return [...item.info];
    });

    // console.log('allHistoryOrder===', allHistoryOrder.flat());
    data.historyOrderNum = 0;
    allHistoryOrder.flat().map((item) => {
      data.historyOrderNum += item.num;
    });
    // console.log('data.historyOrderNum===', data.historyOrderNum);
  }
}

/**
 * 监听socket是否连接正常
 */
function watchSocketOpen() {
  uni.$off("is-socket-open");
  uni.$on("is-socket-open", (res) => {
    console.log("is-socket-open===", res);
    if (res) {
      data.isGoodsAdd = true;
      initCart();
    } else {
      uni.showLoading({
        title: "购物车加载中",
        mask: true,
      });
      data.isGoodsAdd = false;
    }
  });
}

/**
 * socket消息监听
 */
function onMessage() {
  websocketUtil.offMessage();
  websocketUtil.onMessage(async (res) => {
    let msg = JSON.parse(res);
    let cartItem;
    let cartArr = [];
    // console.log("onMessage===",msg)
    if (msg.msg_id) {
      websocketUtil.send(
        JSON.stringify({
          type: "receipt",
          msg_id: msg.msg_id,
        })
      );
    }
    if (msg.status == 0 && msg.type != "time_discount") {
      if (msg.type == "no_suit_num") {
        uni.showModal({
          title: "提示",
          showCancel: false,
          content: msg.msg,
          success: function (res) {
            if (res.confirm) {
              console.log(cartItemId.value);
              delCart(cartItemId.value);
              initCart();
              console.log("用户点击确定");
            } else if (res.cancel) {
              console.log("用户点击取消");
            }
          },
        });
        data.isGoodsAdd = true;
        return;
      }
      uni.$utils.showToast(msg.msg || "操作失败");
      data.isGoodsAdd = true;
      return;
    }
    if (msg.data) {
      cartArr = data.tabbar.reduce((prve, cur) => {
        prve = [...prve, ...cur.foods];
        return prve;
      }, []);
    }

    switch (msg.operate_type) {
      case "onboc_init":
        cars.length = 0;
        // console.log("购物车信息onboc_init===",msg)
        if (!data.table.tableCode) {
          data.table.tableCode = msg.table_code;
          uni.setStorageSync("table_code", msg.table_code);
          data.limitTimeDiscount = limitTimeDiscountRes.value;
          websocketUtil.send(
            JSON.stringify({
              type: "shopping",
              operate_type: "time_discount_save",
              table_code: data.table.tableCode,
              shop_id: uni.getStorageSync("shopInfo").id,
              operate_type: "time_discount_save",
              data: limitTimeDiscountRes.value,
            })
          );
        }
        // console.log("商品信息===",cartArr)
        msg.data.map((item) => {
          cartItem = getNowCart(item, cartArr);
          if (cartItem.isGrounding || cartItem.is_temporary == 1) {
            cartControls(cartItem, "add");
          } else {
            delCart(cartItem.id);
          }
        });
        getHistoryOrderDetail();
        uni.hideLoading();
        break;
      case "onboc_add":
      case "add":
        cartItem = getNowCart(msg.data, cartArr);
        cartControls(cartItem, "add");
        uni.$utils.showToast("操作成功");
        break;
      case "onboc_edit":
      case "edit":
        cartItem = getNowCart(msg.data, cartArr);
        cartControls(cartItem, "edit");
        uni.$utils.showToast("操作成功");
        break;
      case "onboc_del":
      case "del":
        cartItem = getNowCart(msg.data, cartArr);
        cartControls(cartItem, "del");
        break;
      case "onboc_cleanup":
      case "cleanup":
        cars.length = 0;
        for (let i in data.tabbar) {
          for (let k in data.tabbar[i].foods) {
            data.tabbar[i].foods[k].chooseNumber = 0;
          }
        }
        getHistoryOrderDetail();
        break;
      case "init":
      case "rottable":
        if (data.table.tableCode == msg.data.new_table_code) {
          initCart();
        } else {
          data.table.tableCode = msg.data.new_table_code;
          let resData = await getShopTableDetail({
            tableCode: msg.data.new_table_code,
          });
          data.table = resData;
          initCart();
        }
        break;
      case "product_update":
        init();
        break;
      case "clearOrder":
        getHistoryOrderDetail();
        break;
    }
  });
}

/**
 * 初始化购物车
 */
function initCart() {
  let params = {
    ...data.socketData,
    operate_type: "init",
    table_code: data.table.tableCode,
  };
  console.log("购物车初始化参数===", params);
  websocketUtil.send(JSON.stringify(params));
}

/**
 * 购物车添加菜品
 */
function editCart(par, operate_type) {
  cartItemId.value = par.id;
  if (!data.isGoodsAdd) {
    return;
  }
  let params = {
    ...data.socketData,
    operate_type: operate_type,
    table_code: data.table.tableCode,
    product_id: "",
    is_print: 1,
    sku_id: "", //
    number: 1, //数量
  };
  Object.assign(params, par);
  console.log("购物车添加菜品参数===", params);
  websocketUtil.send(JSON.stringify(params));
  data.isGoodsAdd = false;
}

/**
 * 删除购物车菜品
 */
function delCart(id) {
  let params = {
    ...data.socketData,
    id: id,
    operate_type: "del",
    table_code: data.table.tableCode,
  };
  console.log("购物车删除菜品参数===", params);
  websocketUtil.send(JSON.stringify(params));
}

/**
 * 清除购物车
 */
async function cleaCart(e) {
  if (e == "cart") {
    let params = {
      ...data.socketData,
      operate_type: "cleanup",
      table_code: data.table.tableCode,
    };
    console.log("购物车清空菜品参数===", params);
    websocketUtil.send(JSON.stringify(params));
  } else if (e == "allHistoryOrder") {
    await cancelOrder({
      orderId: data.orderInfo.id,
      shopId: uni.getStorageSync("shopInfo").id,
    });
    let params = {
      ...data.socketData,
      operate_type: "clearOrder",
      table_code: data.table.tableCode,
    };
    websocketUtil.send(JSON.stringify(params));
    initCart();
  } else {
    await rmPlaceOrder({
      orderId: data.orderInfo.id,
      placeNum: e,
      shopId: uni.getStorageSync("shopInfo").id,
    });
    let params = {
      ...data.socketData,
      operate_type: "clearOrder",
      table_code: data.table.tableCode,
    };
    websocketUtil.send(JSON.stringify(params));
    initCart();
  }
}

/**
 * 获取商品列表
 */
function getGoods() {
  const showLoading = data.tabbar.length <= 0 ? true : false;
  return getProductList({}, "product", showLoading);
}



/**
 * 前往选择桌台
 */
function chooseTable() {
  go.to("PAGES_CHOOSE_TABLE", {
    ...data.table,
  });
}

/**
 * 选择桌台完成
 */
function watchChooseTable() {
  uni.$off("choose-table");
  uni.$on("choose-table", (item) => {
    onChooseTable(item);
  });
}

/**
 * 选择桌台完成
 * @param {Object} item
 */
async function onChooseTable(item) {
  if (!item) {
    // #ifdef MP-WEIXIN
    uni.showModal({
      title: "提示",
      content: "桌台不存在或不是该店铺的桌台",
    });
    // #endif
    // #ifndef MP-WEIXIN
    uni.$utils.showToast("桌台不存在或不是该店铺的桌台");
    // #endif
    return;
  }
  console.log("---table:detail-----", item);
  console.log("---table_code-----", data.table.tableCode);
  console.log("---new_table_code-----", item.tableCode);
  let params = {
    ...data.socketData,
    operate_type: "rottable",
    table_code: data.table.tableCode,
    new_table_code: item.tableCode,
  };
  if (data.table.id || cars.length <= 0) {
    data.table = {
      ...item,
    };
    if (cars.length > 0) {
      websocketUtil.send(JSON.stringify(params));
    } else {
      initCart();
    }
    return;
  }
  if (item.status == "unbind") {
    return uni.$utils.showToast("该台桌未绑定，清先去桌台管理里绑定码牌");
  }
  if (item.status != "idle") {
    return uni.$utils.showToast("该台桌已在使用中");
  }
  data.table = item;
  if (cars.length > 0) {
    websocketUtil.send(JSON.stringify(params));
  }
  // initCart()
}

/**
 * 菜品操作
 * @param {Object} foodsindex
 * @param {Object} index
 * @param {Object} isAdd
 * @param {Object} searchGoodsIndex
 * @param {Object} showCurrentInput
 * @param {Object} is_time_discount //是否是限时折扣商品
 */
async function goodsUpdate(
  foodsindex,
  index,
  isAdd,
  searchGoodsIndex,
  showCurrentInput,
  is_time_discount
) {
  // showCurrentInput 称重才会传的参数
  // if (!data.table.id) {
  // 	return uni.$utils.showToast('请先选择桌台', 0.5).then(res => {
  // 		chooseTable()
  // 	})
  // }

  if (!data.isGoodsAdd) {
    return;
  }
  let $goods = data.tabbar[index].foods[foodsindex];

  if (is_time_discount === undefined) {
    is_time_discount = yskUtils.limitUtils.canUseLimitTimeDiscount(
      { ...$goods, salePrice: $goods.lowPrice },
      data.limitTimeDiscount,
      shopInfo,
      null,
      "id"
    )
      ? 1
      : 0;
  }
  if ($goods.type !== "sku") {
    //单规格
    let goodsInCarIndex = cars.findIndex((carsGoods) => {
      return (
        carsGoods.sku_id == $goods.skuList[0].id &&
        carsGoods.product_id == $goods.id
      );
    });
    let product_id = $goods.id;
    let product_type = $goods.type;
    let sku_id = $goods.skuList[0].id;
    let suitNum = $goods.skuList[0].suitNum || 1;
    if (goodsInCarIndex !== -1) {
      //更新
      let cartItem = cars[goodsInCarIndex];
      let number = isAdd ? cartItem.number + 1 : +cartItem.number - 1;
      if (!isAdd) {
        if (number === 0 || number < suitNum) {
          //移除
          setSearchGoods(searchGoodsIndex, 0);
          delCart(cartItem.id);
        }
      }

      // 不影响之前的代码  称重number单独处理
      if ($goods.type == "weight" && showCurrentInput) {
        number = Number(showCurrentInput);
      }

      editCart(
        {
          id: cartItem.id,
          suitNum: cartItem.suitNum || 1,
          number: number,
          product_id: product_id,
          product_type: product_type,
          sku_id: sku_id,
          is_temporary: cartItem.is_temporary,
          is_time_discount,
        },
        "edit"
      );
      data.isGoodsAdd = false;
      setSearchGoods(searchGoodsIndex, number);
    } else {
      // 不影响之前的代码  称重suit单独处理
      if ($goods.type == "weight" && showCurrentInput) {
        suitNum = showCurrentInput;
        if (
          $goods.skuList[0].suitNum &&
          showCurrentInput < $goods.skuList[0].suitNum
        ) {
          uni.$utils.showToast(`最小起售数量为${$goods.skuList[0].suitNum}份`);
          return;
        }
      }
      // 套餐和单规格
      if ($goods.groupType != 1) {
        //增加
        editCart(
          {
            number: suitNum,
            product_id: product_id,
            product_type: product_type,
            sku_id: sku_id,
            is_temporary: 0, //是否是临时菜
            is_time_discount,
          },
          "add"
        );
        data.isGoodsAdd = false;
      }
    }
    return;
  }
}

/**
 * socket通知购物车商品数量修改处理
 */
function cartControls(cartItem, type) {
  if (!data.table.tableCode) {
    data.table.tableCode = cartItem.table_code;
  }
  data.isGoodsAdd = true;
  let cartIndex = 0;
  let product_id = cartItem.product_id;
  let sku_id = cartItem.sku_id;
  let $goods;
  cars.map((item, index) => {
    if (item.id == cartItem.id) {
      cartIndex = index;
      product_id = item.product_id;
      sku_id = item.sku_id;
    }
  });
  data.tabbar.map((tabbarItem) => {
    if (tabbarItem.foods.find((v) => v.id == product_id)) {
      $goods =
        product_id < 0 ? {} : tabbarItem.foods.find((v) => v.id == product_id);
    }
  });

  if (type == "del") {
    cars.splice(cartIndex, 1);
    if ($goods) $goods.chooseNumber = 0;
    return;
  }
  if (type == "add") {
    cars.push(cartItem);
    if ($goods) $goods.chooseNumber = cartItem.number;
  }
  if (type == "edit") {
    cars[cartIndex].number = cartItem.number;
    if ($goods) {
      $goods.chooseNumber = cartItem.number;
    }
  }
}

/**
 * 购物车商品数量改变处理
 * @param {Object} e
 */
async function carsNumberChange(e) {
  if (!data.isGoodsAdd) {
    return;
  }
  let $sku;
  let $goods;
  let params = {
    number: e.num,
    id: e.goods.id,
    product_id: e.goods.product_id,
    sku_id: e.goods.sku_id,
    is_temporary: e.goods.is_temporary,
  };
  if (e.goods.is_temporary != 1) {
    data.tabbar.map((tabbarItem) => {
      if (tabbarItem.foods.find((v) => v.id == e.goods.product_id)) {
        $goods = !e.goods.product_id
          ? undefined
          : tabbarItem.foods.find((v) => v.id == e.goods.product_id);
      }
    });
    $sku = !e.goods.product_id
      ? { suitNum: 1 }
      : $goods.skuList.find((v) => v.id == e.goods.sku_id);
    params.suitNum = $sku.suitNum || 1;
    if (e.num === 0 || e.num < $sku.suitNum) {
      //移除
      delCart(e.goods.id);
      return;
    }
  } else {
    if (e.num === 0) {
      //移除
      delCart(e.goods.id);
      return;
    }
    params.product_name = e.goods.name;
    params.sku_name = e.goods.sku_name;
  }

  editCart(params, "edit");
  data.isGoodsAdd = false;
}

/**
 * 添加套餐
 * @param {Object} d
 * @param {Object} item
 */
async function taocanConfirm(d, item) {
  editCart(
    {
      number: item.skuList[0].suitNum,
      product_id: item.id,
      product_type: item.type,
      sku_id: item.skuList[0].id,
      pro_group_info: JSON.stringify(d),
      is_temporary: 0, //是否是临时菜
    },
    "add"
  );
  data.isGoodsAdd = false;
}

const instance = getCurrentInstance();
let selGoods = ref({});

/**
 * 打开规格弹窗
 * @param {Object} foodsindex
 * @param {Object} index
 */
function chooseGuige(foodsindex, index) {
  const $goods = data.tabbar[index].foods[foodsindex];
  selGoods.value = $goods;
  if ($goods.groupType == 1) {
    data.goodsData = $goods;
    taocanModelRef.value.open();
  } else {
    guigeModelData.title = $goods.name;
    const skuMap = returnSelGoodsSkuMap($goods.skuList);
    // 多规格,和套餐规格区分.groupType=1 套餐多规格
    const selectSpecInfo = returnSelGoodsSkuList($goods.selectSpecInfo);
    setSkugoodsDefaultInit($goods, selectSpecInfo, skuMap, $goods.skuList);
    chooseGuigeModel.value.open();
  }
}

//返回当前选中商品skuMap
function returnSelGoodsSkuMap(specList) {
  const skuMap = {};
  for (let i in specList) {
    skuMap[specList[i].specInfo] = specList[i];
  }
  return skuMap;
}
/**
 * 多规格选择
 * @param {Object} skuList
 */
function returnSelGoodsSkuList(selectSpecInfo) {
  let specInfo = [];
  for (var key in selectSpecInfo) {
    specInfo.push({
      name: key,
      value: selectSpecInfo[key],
    });
  }
  let result = specInfo.map((v, index) => {
    return {
      ...v,
      valueArr: v.value,
      sel: "",
      values: v.value.map((name) => {
        return {
          name: name,
          disabled: false,
        };
      }),
    };
  });
  return result;
}

/**
 * 多规格选择确认
 * @param {Object} sku
 * @param {Object} num
 */
async function guigeConfirm(sku, suitNum,is_time_discount) {
  if (!data.isGoodsAdd) {
    return;
  }
  let goods = guigeModelData.chooseGoods.item;
  let sku_id = sku.id;
  let product_id = goods.id;
  let product_type = goods.type;
  let res = findGoodsInCar(goods, sku_id);
  if (res) {
    //更新
    let { index } = res;
    let carGoods = cars[index];
    let cartId = carGoods.id;
    let newNumber = carGoods.number * 1 + suitNum;
    let suitNum = goods.skuList[0].suitNum || 1;

    editCart(
      {
        id: cartId,
        number: newNumber,
        suitNum: carGoods.suitNum || 1,
        product_id: product_id,
        sku_id: sku_id,
        is_temporary: carGoods.is_temporary, //是否是临时菜
        is_time_discount,

      },
      "edit"
    );
    data.isGoodsAdd = false;
  } else {
    //添加
    editCart(
      {
        number: suitNum,
        product_id: product_id,
        product_type: product_type,
        sku_id: sku_id,
        is_temporary: 0, //是否是临时菜
        is_time_discount,

      },
      "add"
    );
    data.isGoodsAdd = false;
  }
}

/**
 * 找到该规格商品在购物车中是否存在并返回index值以及对应的数据
 * @param {Object} $goods
 * @param {Object} skuId
 */
function findGoodsInCar($goods, sku_id) {
  const product_id = $goods.id;
  const goodsInCarIndex = cars.findIndex((carsGoods) => {
    return carsGoods.sku_id == sku_id && carsGoods.product_id == product_id;
  });
  const carGoods = cars[goodsInCarIndex];
  return carGoods
    ? {
        index: goodsInCarIndex,
        carGoods,
      }
    : false;
}

/**
 * 多规格商品弹窗时，找到默认可以下单的规格商品
 */
function findGoods(selectSpecInfo = [], goodsListMap = {}, skuList) {
  let skuMapNumber = selectSpecInfo.reduce((prve, cur) => {
    for (let i in cur.valueArr) {
      prve[cur.valueArr[i]] = i;
    }
    return prve;
  }, {});
  let canBudyGoods = skuList.filter((v) =>
    util.isCanBuy(v, guigeModelData.chooseGoods.item)
  );
  return canBudyGoods[0];
}

/**
 * 设置商品默认选中,规格禁止以及选中
 * @param {Object} goods
 * @param {Object} selectSpecInfo
 * @param {Object} skuMap
 * @param {Object} skuList
 */
function setSkugoodsDefaultInit(goods, selectSpecInfo, skuMap, skuList) {
  guigeModelData.chooseGoods.item = goods;
  guigeModelData.chooseGoods.skus = selectSpecInfo;
  guigeModelData.chooseGoods.skuMap = skuMap;
  const skuGoods = findGoods(selectSpecInfo, skuMap, skuList);
  if (skuGoods) {
    skuGoods.specInfo.split(",").map((v, index) => {
      guigeModelData.chooseGoods.skus[index].sel = v;
    });
  }
  setTagDisabled();
}

//更新选中规格
function updateSkuSel(skusIndex, skdName) {
  const skuList = guigeModelData.chooseGoods.skus;
  const skuMap = guigeModelData.chooseGoods.skuMap;
  guigeModelData.chooseGoods.skus[skusIndex].sel = skdName;
  const specInfo = guigeModelData.chooseGoods.skus
    .reduce((prve, cur) => {
      prve.push(cur.sel);
      return prve;
    }, [])
    .join();
  setTagDisabled();
}

/**
 * 设置规格按钮的禁止状态
 */
function setTagDisabled() {
  const skuList = guigeModelData.chooseGoods.skus;
  const skuMap = guigeModelData.chooseGoods.skuMap;
  const selArr = skuList.reduce((prve, cur) => {
    if (cur.sel) {
      prve.push(cur.sel);
    } else {
    }
    return prve;
  }, []);

  let selArrAllGroup = util.generateCombinations(selArr, selArr.length - 1);
  const matchArr = [];
  for (let key in skuMap) {
    let goods = skuMap[key];
    let keyArr = key.split(",");
    for (let spe of selArrAllGroup) {
      if (util.arrayContainsAll(keyArr, spe)) {
        matchArr.push(goods);
        break;
      }
    }
  }
  //全部规格都已下架
  if (!matchArr.length) {
    for (let k in skuList) {
      for (let i in skuList[k].values) {
        skuList[k].values[i].disabled = true;
      }
    }
    return;
  }
  const includeSkuMap = matchArr.reduce((prve, cur) => {
    const speArr = cur.specInfo.split(",");
    for (let i of speArr) {
      if (!prve.hasOwnProperty("i")) {
        prve[i] = matchArr
          .filter((v) => v.specInfo.match(i))
          .every((v) => {
            return !util.isCanBuy(v, guigeModelData.chooseGoods.item);
          });
      }
    }
    return prve;
  }, {});
  for (let i in includeSkuMap) {
    for (let k in skuList) {
      const index = skuList[k].valueArr.findIndex((val) => val === i);
      if (index !== -1) {
        skuList[k].values[index].disabled = includeSkuMap[i];
      }
    }
  }
}

/**
 * 扫桌台码
 */
function scanCode() {
  uni.scanCode({
    onlyFromCamera: true,
    success: async function (res) {
      console.log("条码类型：" + res.scanType);
      console.log("条码内容：" + res.result);
      if (res.result.includes("codeplate?code=")) {
        const par = returnUrlPar(res.result);
        const tableCode = par.code;
        let resData = await getShopTableDetail({ tableCode: tableCode });
        onChooseTable(resData);
      } else {
        uni.showToast({
          icon: "error",
          title: "请扫描正确的桌台码",
        });
      }
    },
  });
}

function returnUrlPar(str) {
  let arr = str.split("?")[1].split("&"); //先通过？分解得到？后面的所需字符串，再将其通过&分解开存放在数组里
  let obj = {};
  for (let i of arr) {
    obj[i.split("=")[0]] = i.split("=")[1]; //对数组每项用=分解开，=前为对象属性名，=后为属性值
  }
  return obj;
}

/**
 * 商品数据处理
 * @param {Object} category
 * @param {Object} goods
 * @param {Object} cars
 */
function setTabBar(category, goods, cars) {
  const goodsCategoryMap = goods.reduce((prve, cur) => {
    if (!prve.hasOwnProperty(cur.categoryId)) {
      prve[cur.categoryId] = [];
    }
    prve[cur.categoryId].push(cur);
    return prve;
  }, {});
  const chooseGoodsNumberMap = cars.reduce((prve, cur) => {
    if (!prve.hasOwnProperty(cur.productId)) {
      prve[cur.productId] = 0;
    }
    prve[cur.productId] += cur.number;
    return prve;
  }, {});
  let tabbar = category.map((v) => {
    const foods = goodsCategoryMap[v.id] || [];
    return {
      ...v,
      foods: foods.map((fgoods, index) => {
        return {
          ...fgoods,
          chooseNumber: chooseGoodsNumberMap[fgoods.id],
          price: fgoods.lowPrice,
          salePrice: fgoods.lowPrice || fgoods.salePrice,
          memberPrice: fgoods.memberPrice || fgoods.lowMemberPrice,
        };
      }),
    };
  });
  tabbar = tabbar.filter((v) => {
    return v.foods.length;
  });
  data.tabbar = tabbar;
  nextTick(() => {
    getMenuItemTop();
  });
  storageManage.cacheGoods(data.tabbar);
}

let searchValue = ref("");
let isSearch = ref(false);
let searchResult = ref([]);

/**
 * 搜索
 */
function search() {
  if (searchValue.value === "") {
    isSearch.value = false;
    return;
  }
  isSearch.value = true;
  searchResult.value = returnSearchGoods();
}

function returnSearchGoods() {
  const newval = searchValue.value;
  let arr = [];
  let goods = [];
  for (let i in data.tabbar) {
    const goodsArr = data.tabbar[i].foods || [];
    for (let k in goodsArr) {
      goods.push({
        ...goodsArr[k],
        index: i,
        goodsIndex: k,
      });
    }
  }
  if (newval == "") {
    arr = goods;
  } else {
    arr = goods.filter((v) => v.name.includes(newval.trim()));
  }
  return arr;
}

function clearSearch() {
  isSearch.value = false;
}

function chooseUser() {
  go.to("PAGES_CHOOSE_USER");
}

/**
 * 前往临时菜
 */
function toLinshi() {
  go.to("PAGES_CHOOSE_ADD_TEMP_CUISINE", {
    tableCode: data.table.tableCode,
  });
}

/**
 * 称重
 */
const refweighitem = ref(null);
const tapweigh = (foodsindex, index) => {
  const goods = data.tabbar[index].foods[foodsindex];
  refweighitem.value.open(foodsindex, index, goods);
};

/**
 * 搜索商品添加减少
 * @param {Object} goodsItem
 * @param {Object} goodsIndex
 * @param {Object} isAdd
 */
function searchGoodsUpdate(goodsItem, goodsIndex, isAdd) {
  goodsUpdate(goodsItem.goodsIndex, goodsItem.index, isAdd, goodsIndex);
}

function setSearchGoods(index, chooseNumber) {
  if (index !== undefined) {
    searchResult.value[index].chooseNumber = chooseNumber;
  }
}

let isTabClickOver = true;
/**
 * 点击左边的栏目切换
 * @param {Object} index
 */
async function swichMenu(index) {
  if (data.arr.length == 0) {
    await getMenuItemTop();
  }
  if (index == data.current) return;
  isTabClickOver = false;
  data.scrollRightTop = data.oldScrollTop;
  nextTick(function () {
    data.scrollRightTop = data.arr[index] + data.topZhanwei;
    data.current = index;
    leftMenuStatus(index);
  });
}

/**
 * 获取一个目标元素的高度
 * @param {Object} elClass
 * @param {Object} dataVal
 */
function getElRect(elClass, dataVal) {
  return new Promise((resolve, reject) => {
    const query = uni.createSelectorQuery().in(instance.proxy);
    query
      .select("." + elClass)
      .fields(
        {
          size: true,
        },
        (res) => {
          // 如果节点尚未生成，res值为null，循环调用执行
          if (!res) {
            setTimeout(() => {
              getElRect(elClass);
            }, 10);
            return;
          }
          if (dataVal) {
            data[dataVal] = res.height;
          }
          resolve(res);
        }
      )
      .exec();
  });
}

/**
 * 设置左边菜单的滚动状态
 * @param {Object} index
 */
async function leftMenuStatus(index) {
  if (!isTabClickOver) {
    return;
  }
  data.current = index;
  // 如果为0，意味着尚未初始化
  if (data.menuHeight == 0 || data.menuItemHeight == 0) {
    await getElRect("menu-scroll-view", "menuHeight");
    await getElRect("u-tab-item", "menuItemHeight");
  }
  // 将菜单活动item垂直居中
  data.scrollTop =
    index * data.menuItemHeight + data.menuItemHeight / 2 - data.menuHeight / 2;
}

/**
 * 获取右边菜单每个item到顶部的距离
 */
function getMenuItemTop() {
  new Promise((resolve) => {
    let selectorQuery = uni.createSelectorQuery();
    selectorQuery
      .selectAll(".class-item")
      .boundingClientRect((rects) => {
        // 如果节点尚未生成，rects值为[](因为用selectAll，所以返回的是数组)，循环调用执行
        if (!rects.length) {
          setTimeout(() => {
            getMenuItemTop();
          }, 10);
          return;
        }
        let arr = [];
        rects.forEach((rect) => {
          // 这里减去rects[0].top，是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
          arr.push(rect.top - rects[0].top);
        });
        data.arr = arr;
        resolve();
      })
      .exec();
  });
}

/**
 * 右边菜单滚动
 * @param {Object} e
 */
async function rightScroll(e) {
  data.oldScrollTop = e.detail.scrollTop;
  if (data.arr.length == 0) {
    await getMenuItemTop();
  }
  if (data.timer) return;
  if (!data.menuHeight) {
    await getElRect("menu-scroll-view", "menuHeight");
  }
  if (e.detail.scrollTop == 0) {
    isTabClickOver = true;
    // return swichMenu(0)
  }
  setTimeout(() => {
    // 节流
    data.timer = null;
    // scrollHeight为右边菜单垂直中点位置
    let scrollHeight =
      e.detail.scrollTop + data.menuHeight / 2 + data.topZhanwei / 2;
    for (let i = 0; i < data.arr.length; i++) {
      let height1 = data.arr[i];
      let height2 = data.arr[i + 1];
      // 如果不存在height2，意味着数据循环已经到了最后一个，设置左边菜单为最后一项即可
      if (!height2 || (scrollHeight >= height1 && scrollHeight < height2)) {
        if (isTabClickOver) {
          leftMenuStatus(i);
        } else {
          isTabClickOver = true;
        }
        return;
      }
    }
  }, 100);
}

/**
 * 台桌切换
 */
async function onSelTable() {
  setTabBar($category, $originGoods, cars);
}

function watchUpdate() {
  uni.$off("update:createOrderIndex");
  uni.$off("add:cashCai");
  uni.$on("update:createOrderIndex", () => {
    cars.length = 0;
    init();
  });

  // 添加临时菜到购物车
  uni.$on("add:cashCai", async (data) => {
    console.log("add:cashCai", data);
    $originGoods.push(data);
    data.isGoodsAdd = false;
  });
}
</script>

<style lang="scss" scoped>
.choose-user {
  background: #f9f9f9;
  padding: 22rpx 28rpx;
}

.search {
  padding-right: 28rpx;
}

.icon-saoma {
  margin-left: 20rpx;
  width: 34rpx;
  height: 32rpx;
}

$u-tips-color: $my-main-color;
$u-primary: $my-main-color;
$u-main-color: $my-main-color;

.u-wrap {
  height: calc(100vh);
  /* #ifdef H5 */
  height: calc(100vh - var(--window-top));
  /* #endif */
  display: flex;
  flex-direction: column;
}

.headeimg {
  width: 60rpx;
  height: 60rpx;
  display: flex;
  background-color: #eee;
  border-radius: 12rpx;
  overflow: hidden;

  .img {
    width: 60rpx;
    height: 60rpx;
  }
}

.u-menu-wrap {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.u-search-inner {
  // background-color: rgb(234, 234, 234);
  background-color: #fff;
  border-radius: 100rpx;
  display: flex;
  align-items: center;
  padding: 10rpx 16rpx;
}

.u-search-text {
  font-size: 26rpx;
  color: $u-tips-color;
  margin-left: 10rpx;
}

.u-tab-view {
  width: 178rpx;
  height: 100%;
}

.u-tab-item {
  height: 110rpx;
  background: #f6f6f6;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26rpx;
  color: #444;
  font-weight: 400;
  line-height: 1;
  box-sizing: border-box;
  padding-left: 12rpx;
}

.u-tab-item-active {
  position: relative;
  color: $my-main-color;
  font-size: 30rpx;
  font-weight: 600;
  background: #fff;
}

.u-tab-item-active::before {
  content: "";
  position: absolute;
  border-left: 4px solid $my-main-color;
  left: 0;
  top: 0;
  bottom: 0;
}

.u-tab-view {
  height: 100%;
  background-color: #f6f6f6;
}

.addCai {
  width: 250rpx;
  height: 272rpx;
  border-radius: 8rpx 8rpx 8rpx 8rpx;
  box-sizing: border-box;
  border: 4rpx solid #90bdf6;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.lingshi {
  width: 250rpx;
  height: 136px;
  background: #ffffff;
  border-radius: 8rpx 8rpx 8rpx 8rpx;
  border: 4rpx solid #90bdf6;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

::v-deep .uni-searchbar {
  padding-top: 12px !important;
  padding-bottom: 16px !important;
}

.right-box {
  width: 572rpx;
  // background-color: rgb(250, 250, 250);
  background-color: rgb(255, 255, 255);
}

.page-view {
  // padding: 24rpx 28rpx 24rpx 24rpx;
}

.class-item {
  margin-bottom: 30rpx;
  background-color: #fff;
  border-radius: 8rpx;
}

.class-item:last-child {
  min-height: 50vh;
}

.item-title {
  font-size: 26rpx;
  font-weight: bold;

  &.active {
    color: $my-main-color;
  }
}

.item-menu-name {
  font-weight: normal;
  font-size: 24rpx;
  color: $u-main-color;
}

.item-container {
  display: flex;
  flex-wrap: wrap;
  margin-top: 24rpx;
}

.thumb-box {
  margin-right: 24rpx;
  margin-bottom: 24rpx;
}

.item-menu-image {
  width: 120rpx;
  height: 120rpx;
}

.history-button {
  padding: 4upx 20upx;
  background-color: $uni-primary;
  position: fixed;
  bottom: 60%;
  right: 30upx;
  color: #fff;
  border-radius: 8upx;
  .num {
    padding: 0 6px;
    border-radius: 50px;
    background-color: #eb4f4f;
    color: #fff;
    position: absolute;
    top: -8px;
    right: -8px;
    font-size: 24rpx;
  }
}
</style>
