<template>
  <!-- 页面的最外层容器，用于包裹整个购物车页面内容 -->
  <view class="container">
    <!-- 商品列表区域，用于展示购物车中的商品信息 -->
    <view class="prod-list">
      <!-- 使用v-for循环遍历shopCartItemDiscounts数组，scIndex为当前项的索引，每个元素对应一组商品相关的数据（可能是不同优惠规则下的商品集合等情况） -->
      <block v-for="(item, scIndex) in shopCartItemDiscounts" :key="scIndex">
        <view class="prod-block">
          <!-- 如果当前商品组有对应的优惠信息（chooseDiscountItemDto存在），则展示优惠提示信息 -->
          <view v-if="item.chooseDiscountItemDto" class="discount-tips">
            <!-- 展示优惠规则文本，通过wxs.parseDiscount函数对优惠规则进行解析处理后展示 -->
            <text class="text-block">
              {{ wxs.parseDiscount(item.chooseDiscountItemDto.discountRule) }}
            </text>
            <!-- 展示详细的优惠信息文本，通过wxs.parseDiscountMsg函数结合优惠规则、所需金额、优惠金额等数据进行解析展示 -->
            <text class="text-list">
              {{
                wxs.parseDiscountMsg(item.chooseDiscountItemDto.discountRule, item.chooseDiscountItemDto.needAmount, item.chooseDiscountItemDto.discount)
              }}
            </text>
          </view>
          <!-- 内层v-for循环，遍历当前商品组中的每个具体商品（prod代表每个商品对象），index为商品在当前组内的索引 -->
          <block v-for="(prod, index) in item.shopCartItems" :key="index">
            <view class="item">
              <!-- 商品选择按钮所在的容器 -->
              <view class="btn">
                <label>
                  <!-- 单个商品的选择框，绑定了一些自定义属性和事件 -->
                  <checkbox :data-scindex="scIndex"  <!-- 传递当前商品组的索引 -->
                    :data-index="index"  <!-- 传递当前商品在组内的索引 -->
                    :value="prod.prodId"  <!-- 绑定商品的唯一标识（产品ID） -->
                    :checked="prod.checked"  <!-- 绑定商品的选中状态 -->
                    color="#105c3e"  <!-- 设置选择框选中时的颜色 -->
                    @tap="onSelectedItem"  <!-- 绑定点击选择商品时触发的事件 -->
                  />
                </label>
              </view>
              <!-- 商品详细信息展示区域 -->
              <view class="prodinfo">
                <!-- 商品图片展示容器 -->
                <view class="pic">
                  <image :src="prod.pic" />  <!-- 通过绑定商品对象中的图片路径属性来展示商品图片 -->
                </view>
                <view class="opt">
                  <!-- 展示商品名称 -->
                  <view class="prod-name">
                    {{ prod.prodName }}
                  </view>
                  <!-- 展示商品规格信息，根据是否有skuName来动态添加类名，若没有skuName则添加empty-n类名 -->
                  <text :class="'prod-info-text ' + (prod.skuName?'':'empty-n')">
                    {{ prod.skuName }}
                  </text>
                  <!-- 商品价格和数量操作区域 -->
                  <view class="price-count">
                    <view class="price">
                      <!-- 价格符号“￥” -->
                      <text class="symbol">
                        ￥
                      </text>
                      <!-- 价格的整数部分，通过wxs.parsePrice函数对商品价格进行处理后获取整数部分展示 -->
                      <text class="big-num">
                        {{ wxs.parsePrice(prod.price)[0] }}
                      </text>
                      <!-- 价格的小数部分，通过wxs.parsePrice函数对商品价格进行处理后获取小数部分展示 -->
                      <text class="small-num">
                        .{{ wxs.parsePrice(prod.price)[1] }}
                      </text>
                    </view>
                    <view class="m-numSelector">
                      <!-- 数量减少按钮，绑定了点击事件onCountMinus，并传递相关索引信息 -->
                      <view class="minus"
                            :data-scindex="scIndex"
                            :data-index="index"
                            @tap="onCountMinus" />
                      <!-- 商品数量输入框，设置为不可输入（disabled），仅用于展示当前商品数量 -->
                      <input type="number"
                             :value="prod.prodCount"
                             disabled>
                      <!-- 数量增加按钮，绑定了点击事件onCountPlus，并传递相关索引信息 -->
                      <view class="plus"
                            :data-scindex="scIndex"
                            :data-index="index"
                            @tap="onCountPlus" />
                    </view>
                  </view>
                </view>
              </view>
            </view>
          </block>
        </view>
      </block>
    </view>

    <!-- 当购物车中没有商品（shopCartItemDiscounts数组长度为0）时，展示此区域，提示用户购物车为空 -->
    <view v-if="!shopCartItemDiscounts.length" class="empty">
      <view class="img">
        <image src="@/static/images/tabbar/basket.png" />  <!-- 展示一个代表购物车的图标 -->
      </view>
      <view class="txt">
        您还没有添加任何商品哦~  <!-- 显示提示文字 -->
      </view>
    </view>

    <!-- 底部按钮区域，当购物车中有商品（shopCartItemDiscounts长度大于0）时展示 -->
    <view v-if="shopCartItemDiscounts.length>0" class="cart-footer">
      <!-- 全选按钮所在容器 -->
      <view class="btn all">
        <checkbox :checked="allChecked"  <!-- 绑定全选状态变量 -->
          color="#f7d731;"  <!-- 设置全选按钮选中时的颜色 -->
          @tap="onSelAll"  <!-- 绑定全选按钮点击触发的事件 -->
        />
        全选  <!-- 按钮显示文字 -->
      </view>
      <!-- 删除按钮所在容器，点击触发onDelBasket事件 -->
      <view class="btn del" @tap="onDelBasket">
        <text>删除</text>  <!-- 按钮显示文字 -->
      </view>
      <!-- 合计金额展示按钮所在容器 -->
      <view class="btn total">
        <view class="finally">
          <text>合计:</text>  <!-- 显示“合计”文字 -->
          <view class="price">
            <text class="symbol">
              ￥
            </text>
            <!-- 最终金额的整数部分，通过wxs.parsePrice函数对finalMoney进行处理后展示 -->
            <text class="big-num">
              {{ wxs.parsePrice(finalMoney)[0] }}
            </text>
            <!-- 最终金额的小数部分，通过wxs.parsePrice函数对finalMoney进行处理后展示 -->
            <text class="small-num">
              .{{ wxs.parsePrice(finalMoney)[1] }}
            </text>
          </view>
        </view>
        <!-- 当有立减金额（subtractMoney大于0）时，展示总额和立减金额信息 -->
        <view v-if="subtractMoney>0" class="total-msg">
          总额:￥{{ wxs.toPrice(totalMoney) }} 立减:￥{{ wxs.toPrice(subtractMoney) }}
        </view>
      </view>
      <!-- 结算按钮所在容器，点击触发toFirmOrder事件 -->
      <view class="btn settle" @tap="toFirmOrder">
        <text>结算</text>  <!-- 按钮显示文字 -->
      </view>
    </view>
    <!-- 结束底部按钮区域 -->
  </view>
</template>

<script setup>
  // 引入wxs模块（此处number()看起来不太完整，可能是代码有缺失或者自定义的一个函数调用方式，假设它用于一些数据处理相关操作）
  const wxs = number()
  // 生命周期函数 - 在页面显示时触发，一般用于加载初始化数据等操作
  onShow(() => {
    // 调用函数加载购物车数据
    loadBasketData()
    // 重新计算购物车中商品的总数量
    http.getCartCount()
  })

  // 定义一个响应式变量，用于控制全选按钮的选中状态，初始值为false
  const allChecked = ref(false)
  // 定义一个响应式数组，用于存储购物车中商品相关的详细数据（包含商品分组、各商品具体信息等），初始为空数组
  const shopCartItemDiscounts = ref([])

  // 加载购物车数据的函数
  const loadBasketData = () => {
    // 显示加载提示框，告知用户正在加载购物车数据
    uni.showLoading()
    // 发送POST请求到指定接口获取购物车数据
    http.request({
      url: '/p/shopCart/info',
      method: 'POST',
      data: {}
    })
      .then(({ data }) => {
        // 如果获取到的数据存在且长度大于0
        if (data && data.length > 0) {
          // 获取购物车商品数据中的商品分组相关数据
          const shopCartItemDiscountsParam = data[0].shopCartItemDiscounts
          // 遍历每个商品分组
          shopCartItemDiscountsParam.forEach(shopCartItemDiscount => {
            // 遍历商品分组内的每个具体商品，将其选中状态初始化为false
            shopCartItemDiscount.shopCartItems.forEach(shopCartItem => {
              shopCartItem.checked = false
            })
          })
          // 将处理后的商品分组数据赋值给响应式变量shopCartItemDiscounts
          shopCartItemDiscounts.value = shopCartItemDiscountsParam
          // 将全选按钮状态设置为false
          allChecked.value = false
        } else {
          // 如果获取到的数据为空，将shopCartItemDiscounts设置为空数组
          shopCartItemDiscounts.value = []
        }
        // 调用函数计算购物车商品的总价
        calTotalPrice()
        // 隐藏加载提示框
        uni.hideLoading()
      })
  }

  // 跳转到结算页面的函数
  const toFirmOrder = () => {
    // 获取当前购物车商品相关数据
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    const basketIds = []
    // 遍历每个商品分组
    shopCartItemDiscountsParam.forEach(shopCartItemDiscount => {
      // 遍历商品分组内的每个具体商品
      shopCartItemDiscount.shopCartItems.forEach(shopCartItem => {
        // 如果商品被选中，将其对应的basketId添加到basketIds数组中
        if (shopCartItem.checked) {
          basketIds.push(shopCartItem.basketId)
        }
      })
    })

    // 如果没有选中任何商品（basketIds数组长度为0）
    if (!basketIds.length) {
      // 显示一个提示Toast，告知用户需要选择商品，图标设置为无（none）
      uni.showToast({
        title: '请选择商品',
        icon: 'none'
      })
      return
    }

    // 将选中商品的basketIds数组转换为JSON字符串后存储到本地缓存中
    uni.setStorageSync('basketIds', JSON.stringify(basketIds))
    // 跳转到指定的结算页面，并传递orderEntry=0参数
    uni.navigateTo({
      url: '/pages/submit-order/submit-order?orderEntry=0'
    })
  }

  // 全选按钮点击事件处理函数
  const onSelAll = () => {
    // 取反当前全选按钮的选中状态，得到新的全选状态值
    const allCheckedParam = !allChecked.value
    // 获取当前购物车商品相关数据
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    // 遍历每个商品分组
    for (let i = 0; i < shopCartItemDiscountsParam.length; i++) {
      const cItems = shopCartItemDiscountsParam[i].shopCartItems
      // 遍历商品分组内的每个具体商品，将其选中状态设置为新的全选状态值
      for (let j = 0; j < cItems.length; j++) {
        cItems[j].checked = allCheckedParam
      }
    }
    // 更新全选按钮的选中状态
    allChecked.value = allCheckedParam
    // 更新购物车商品相关数据（因为数据是响应式的，更新后会触发相关UI更新）
    shopCartItemDiscounts.value = shopCartItemDiscountsParam
    // 调用函数重新计算购物车商品的总价
    calTotalPrice()
  }

  // 单个商品选择事件处理函数，在点击单个商品的选择框时触发
  const onSelectedItem = (e) => {
    // 获取当前商品在其所在分组内的索引
    const index = e.currentTarget.dataset.index
    // 获取当前商品所在分组的索引
    const scindex = e.currentTarget.dataset.scindex
    // 获取当前购物车商品相关数据
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    // 获取当前商品的选中状态
    const checked = shopCartItemDiscountsParam[scindex].shopCartItems[index].checked
    // 取反当前商品的选中状态
    shopCartItemDiscountsParam[scindex].shopCartItems[index].checked = !checked
    // 更新购物车商品相关数据
    shopCartItemDiscounts.value = shopCartItemDiscountsParam
    // 调用函数检查全选状态是否需要更新
    checkAllSelected()
    // 调用函数重新计算购物车商品的总价
    calTotalPrice()
  }

  // 检查全选状态的函数
  const checkAllSelected = () => {
    // 初始假设全选状态为true
    let allCheckedParam = true
    // 获取当前购物车商品相关数据
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    let flag = false
    // 遍历每个商品分组
    for (let i = 0; i < shopCartItemDiscountsParam.length; i++) {
      const cItems = shopCartItemDiscountsParam[i].shopCartItems
      // 遍历商品分组内的每个具体商品
      for (let j = 0; j < cItems.length; j++) {
        // 如果发现有商品未被选中
        if (!cItems[j].checked) {
          // 则全选状态变为false
          allCheckedParam = !allCheckedParam
          flag = true
          break
        }
      }
      // 如果已经发现有未选中商品，跳出外层循环
      if (flag) break
    }
    // 更新全选按钮的选中状态
    allChecked.value = allCheckedParam
  }

  // 定义响应式变量，用于存储购物车商品的总额，初始值为0
  const totalMoney = ref(0)
  // 定义响应式变量，用于存储购物车商品的立减金额，初始值为0
  const subtractMoney = ref(0)
  // 定义响应式变量，用于存储购物车商品的最终金额，初始值为0
  const finalMoney = ref(0)

  // 计算购物车商品总额的函数
  const calTotalPrice = () => {
    // 获取当前购物车商品相关数据
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    const shopCartIds = []
    // 遍历每个商品分组
    for (let i = 0; i < shopCartItemDiscountsParam.length; i++) {
      const cItems = shopCartItemDiscountsParam[i].shopCartItems
      // 遍历商品分组内的每个具体商品
      for (let j = 0; j < cItems.length; j++) {
        // 如果商品被选中，将其对应的basketId添加到shopCartIds数组中
        if (cItems[j].checked) {
          shopCartIds.push(cItems[j].basketId)
        }
      }
    }
    // 显示加载提示框
    uni.showLoading()
    // 发送POST请求到指定接口，传递选中商品的basketIds，用于获取总价相关信息
    http.request({
      url: '/p/shopCart/totalPay',
      method: 'POST',
      data: shopCartIds
    })
      .then(({ data }) => {
        // 如果没有返回有效数据，直接返回不做处理
        if (!data) return
        // 更新最终金额
        finalMoney.value = data.finalMoney
        // 更新总额
        totalMoney.value = data.totalMoney
        // 更新立减金额
        subtractMoney.value = data.subtractMoney
        // 隐藏加载提示框
        uni.hideLoading()
      })
  }

  // 减少商品数量的点击事件处理函数，点击商品数量减少按钮时触发
  const onCountMinus = (e) => {
    // 获取当前商品在其所在分组内的索引
    const index = e.currentTarget.dataset.index
    // 获取当前商品所在分组的索引
    const scindex = e.currentTarget.dataset.scindex
    // 获取当前购物车商品相关数据
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    // 获取当前商品的数量
    const prodCount = shopCartItemDiscountsParam[scindex].shopCartItems[index].prodCount
    // 如果商品数量大于1，调用函数减少商品数量
    if (prodCount > 1) {
      updateCount(shopCartItemDiscountsParam, scindex, index, -1)
    }
  }

  /**
   * 增加数量
   */
  const onCountPlus = (e) => {
    const index = e.currentTarget.dataset.index
    const scindex = e.currentTarget.dataset.scindex
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    updateCount(shopCartItemDiscountsParam, scindex, index, 1)
  }

  /**
   * 改变购物车数量接口
   */
  const updateCount = (shopCartItemDiscountsParam, scindex, index, prodCount) => {
    uni.showLoading({
      mask: true
    })
    http.request({
      url: '/p/shopCart/changeItem',
      method: 'POST',
      data: {
        count: prodCount,
        prodId: shopCartItemDiscountsParam[scindex].shopCartItems[index].prodId,
        skuId: shopCartItemDiscountsParam[scindex].shopCartItems[index].skuId,
        shopId: 1
      }
    })
      .then(() => {
        shopCartItemDiscountsParam[scindex].shopCartItems[index].prodCount += prodCount
        shopCartItemDiscounts.value = shopCartItemDiscountsParam
        calTotalPrice() // 计算总价
        uni.hideLoading()
        http.getCartCount() // 重新计算购物车总数量
      })
  }

  /**
   * 删除购物车商品
   */
  const onDelBasket = () => {
    const shopCartItemDiscountsParam = shopCartItemDiscounts.value
    const basketIds = []
    for (let i = 0; i < shopCartItemDiscountsParam.length; i++) {
      const cItems = shopCartItemDiscountsParam[i].shopCartItems
      for (let j = 0; j < cItems.length; j++) {
        if (cItems[j].checked) {
          basketIds.push(cItems[j].basketId)
        }
      }
    }
    if (!basketIds.length) {
      uni.showToast({
        title: '请选择商品',
        icon: 'none'
      })
    } else {
      uni.showModal({
        title: '',
        content: '确认要删除选中的商品吗？',
        confirmColor: '#eb2444',
        success(res) {
          if (res.confirm) {
            uni.showLoading({
              mask: true
            })
            http.request({
              url: '/p/shopCart/deleteItem',
              method: 'DELETE',
              data: basketIds
            })
              .then(() => {
                uni.hideLoading()
                loadBasketData()
              })
          }
        }

      })
    }
  }
</script>

<style scoped lang="scss">
@import "./basket.scss";
</style>
