<template>
  <view class="app-container">
    <view class="fixed-container">
      <view class="top-container">
        <scroll-view
          :scroll-x="true"
          :scroll-left="scrollLeft"
          scroll-with-animation
          :show-scrollbar="false"
          class="tabs-view"
          ref="tabs-view"
        >
          <view class="tab">
            <block v-for="(item, index) in tabList" :key="index">
              <view
                class="item"
                :ref="`tabs-item-${index}`"
                :class="[
                  `tabs-item-${index}`,
                  item.categoryId == tabCurrent ? 'current' : '',
                ]"
                @tap="changeTab(item.categoryId)"
                >{{ item.name }}</view
              >
            </block>
          </view>
        </scroll-view>
      </view>
      <view class="search-container">
        <view class="search">
          <image src="/static/icon/search.png" class=""></image>
          <input
            type="text"
            confirm-type="search"
            placeholder="搜索商品名称"
            v-model="keyword"
            @confirm="searchSubmit"
          />
        </view>
      </view>
    </view>

    <view class="banner-container" v-if="bannerUrl">
      <image :src="bannerUrl" mode="widthFix"></image>
    </view>

    <view class="list-container">
      <block v-for="(item, index) in dataList" :key="index">
        <div class="item" @tap="toGoodsDetail(item.goodsId)">
          <image :src="item.goodsImgSrc" mode="aspectFill"></image>
          <view class="right">
            <view class="title ellipsis-2">{{ item.goodsName }}</view>
            <view class="des ellipsis-2">{{
              item.describeText ? item.describeText : ''
            }}</view>
            <view class="stock-sales">
              <view class="stock">
                <text>剩余{{ item.stock }}件</text>
                <view class="progress-box">
                  <!-- 库存 / 总数 * 100 = 剩余百分比 -->
                  <progress
                    :percent="(item.stock / (item.stock + 100)) * 100"
                    activeColor="#FF3F42"
                    active
                    stroke-width="6"
                  />
                </view>
              </view>
              <view class="sales">销量：{{ item.saleNum || '0' }}</view>
            </view>
            <view class="bottom">
              <view class="price">
                <view class="price-1">¥{{ item.groupPrice | numToFixed }}</view>
                <view class="price-2"
                  >¥{{ item.orgGoodsPrice | numToFixed }}</view
                >
              </view>
              <view class="btn">去拼团</view>
            </view>
          </view>
        </div>
      </block>
    </view>
    <no-data v-if="!dataList.length" :showText="'暂无数据'"></no-data>
    <loading-text
      v-if="dataList.length"
      :loading="loading"
      :noMore="noMore"
    ></loading-text>

    <view
      class="share-container"
      :style="{ top: top + 'px' }"
      v-if="dataList.length"
    >
      <button @tap="clickShare">
        <image src="@/static/icon/share.png"></image>
        <text>分享</text>
      </button>
    </view>

    <view
      class="global-mask"
      v-show="isShareDialog"
      @tap="isShareDialog = false"
    ></view>
    <view class="sharelist-container" v-show="isShareDialog">
      <button class="item" open-type="share" @tap="isShareDialog = false">
        <image src="@/static/icon/wechat.png"></image>
        <text>分享给微信好友</text>
      </button>

      <view class="item" @tap="markImage">
        <image src="@/static/icon/image.png"></image>
        <text>生成图片分享</text>
      </view>
    </view>

    <view class="global-mask" v-show="isShowCanvas" @tap="closeCanvas"></view>
    <view class="canvas-container" v-show="isShowCanvas">
      <view class="content">
        <canvas
          style="width: 340px; height: 340px"
          canvas-id="myCanvas"
          id="myCanvas"
        ></canvas>
      </view>
      <view class="button"><text @tap="saveImage">保存图片</text></view>
    </view>

    <!-- <drag-button :isDock="true" :customBar="true" ref="dragButton"></drag-button> -->
  </view>
</template>

<script>
import { mapState } from 'vuex';
// import dragButton from '@/components/drag-button.vue';

export default {
  // components:{
  // 	dragButton
  // },
  data() {
    return {
      configInfo: uni.getStorageSync('configInfo'),
      dataList: [], // 优惠券列表
      pageNum: 1,
      pageSize: 8,
      noMore: false,
      loading: false,
      isShareDialog: false, // 是否显示分享弹窗
      isShowCanvas: false, // 是否显示海报弹窗
      isFinishCanvas: false, // 是否已完成海报
      codeUrl: '',
      bgUrl: '',
      headUrl: '',
      top: 300,
      tabList: [], // 分类列表
      tabCurrent: '', // 分类当前值
      keyword: '',

      scrollLeft: 50,
      scrollViewWidth: 0,
      tabsRect: {
        left: 0,
      },

      bannerUrl: '',
    };
  },

  watch: {
    tabList() {
      this.$nextTick(() => {
        this.resize();
      });
    },
  },

  computed: {
    ...mapState(['userInfo', 'isLogin', 'userId']),
  },

  onShow() {
    // this.$refs.dragButton.init();

    this.top =
      uni.getStorageSync('top') < 200
        ? uni.getStorageSync('top')
        : uni.getStorageSync('top') - 124;
  },

  onLoad() {
    this.getTabList();
    this.getBanner();
  },

  onShow() {
    uni.$on('hanbleShare', () => {
      this.clickShare();
    });
  },

  onHide() {
    uni.$off('hanbleShare');
  },

  // 下拉刷新
  onPullDownRefresh() {
    this.pageNum = 1;
    this.getList();
  },

  // 上拉加载
  onReachBottom() {
    this.getList(1);
  },

  onShareAppMessage(options) {
    if (options && options.from == 'button') {
      // 来自页面内的转发按钮
    } else {
      // 点击微信右上角的分享按钮
    }
    return {
      title: `${this.userInfo.nickName}向你推荐了${this.configInfo.minAppName}的团购活动`,
      // imageUrl: this.detail.imgUrl,
      path:
        '/pages/index/index?serviceId=' +
        this.userId +
        '&otherType=groupbuyList',
      query: {
        // id: this.goodsId,
      },
      success: function (res) {
        if (res.errMsg == 'shareAppMessage:ok') {
          this.$successToast('分享完成');
        }
      },
    };
  },

  methods: {
    getList(loadMore) {
      if (this.noMore && loadMore) return;
      this.noMore = false;
      if (!loadMore) {
        this.pageNum = 1;
      } else {
        this.loading = true;
      }
      this.$axios({
        url: '/goods/promotion/group/list',
        method: 'get',
        params: {
          pageNo: this.pageNum,
          pageSize: this.pageSize,
          userId: this.userId,
          goodsCategoryId: this.tabCurrent,
          keyword: this.keyword,
        },
        isLoading: !loadMore,
      }).then((res) => {
        let _list = res.data.records;
        let pageTotal = res.data.pages;
        if (this.pageNum >= pageTotal) {
          this.noMore = true;
        }
        if (_list.length) {
          this.pageNum += 1;
        }
        if (loadMore) {
          this.dataList = this.dataList.concat(_list);
          this.loading = false;
        } else {
          this.dataList = _list;
        }

        uni.stopPullDownRefresh();
      });
    },

    // 获取一级菜单
    getTabList() {
      this.$axios({
        url: '/goods/category/list',
        method: 'get',
        params: {},
      }).then((res) => {
        res.data.unshift({ name: '全部', categoryId: '' });
        this.tabList = res.data;
        this.tabCurrent = res.data.length > 0 ? res.data[0].categoryId : 0;
        this.getList();
      });
    },

    // 切换一级菜单
    changeTab(current) {
      this.pageNum = 1;
      this.tabCurrent = current;
      this.resize();
      this.getList();
    },

    searchSubmit() {
      this.pageNum = 1;
      this.getList();
    },

    setScrollLeft() {
      // 当前活动tab的布局信息，有tab菜单的width和left(为元素左边界到父元素左边界的距离)等信息
      const index = this.findElem(this.tabList, 'categoryId', this.tabCurrent);
      const tabRect = this.tabList[index];
      // 累加得到当前item到左边的距离
      const offsetLeft = this.tabList.slice(0, index).reduce((total, curr) => {
        return total + curr.rect.width;
      }, 0);
      // 此处为屏幕宽度
      const res = uni.getSystemInfoSync();
      const windowWidth = res.windowWidth;
      // 将活动的tabs-item移动到屏幕正中间，实际上是对scroll-view的移动
      let scrollLeft =
        offsetLeft -
        (this.tabsRect.width - tabRect.rect.width) / 2 -
        (windowWidth - this.tabsRect.right) / 2 +
        this.tabsRect.left / 2;

      // 这里做一个限制，限制scrollLeft的最大值为整个scroll-view宽度减去tabs组件的宽度
      scrollLeft = Math.min(
        scrollLeft,
        this.scrollViewWidth - this.tabsRect.width
      );
      this.scrollLeft = Math.max(0, scrollLeft);
    },
    // 获取所有标签的尺寸
    resize() {
      // 如果不存在list，则不处理
      if (this.tabList.length === 0) {
        return;
      }
      Promise.all([this.getTabsRect(), this.getAllItemRect()]).then(
        ([tabsRect, itemRect = []]) => {
          this.tabsRect = tabsRect;
          this.scrollViewWidth = 0;
          itemRect.map((item, index) => {
            // 计算scroll-view的宽度，这里
            this.scrollViewWidth += item.width;
            // 另外计算每一个item的中心点X轴坐标
            this.tabList[index].rect = item;
          });
          // 获取了tabs的尺寸之后，设置滑块的位置
          this.setScrollLeft();
        }
      );
    },
    // 获取导航菜单的尺寸
    getTabsRect() {
      return new Promise((resolve) => {
        this.queryRect('tabs-view').then((size) => resolve(size));
      });
    },
    // 获取所有标签的尺寸
    getAllItemRect() {
      return new Promise((resolve) => {
        const promiseAllArr = this.tabList.map((item, index) =>
          this.queryRect(`tabs-item-${index}`, true)
        );
        Promise.all(promiseAllArr).then((sizes) => resolve(sizes));
      });
    },
    // 获取各个标签的尺寸
    queryRect(el, item) {
      const query = uni.createSelectorQuery().in(this);
      return new Promise((resolve) => {
        query
          .select(`.${el}`)
          .boundingClientRect((data) => {
            resolve(data);
          })
          .exec();
      });
    },

    findElem(array, attr, val) {
      for (var i = 0; i < array.length; i++) {
        if (array[i][attr] == val) {
          return i; //返回当前索引值
        }
      }
      return -1;
    },

    // 进入商品详情
    toGoodsDetail(id) {
      if (!id) {
        return false;
      }
      uni.navigateTo({
        url: '/packageGoods/pages/detail?id=' + id,
      });
    },

    // 获取海报图
    getBanner() {
      this.$axios({
        url: '/goods/promotion/share/qrcode',
        method: 'get',
        params: {
          userId: this.userId,
        },
      }).then((res) => {
        this.bannerUrl = res.data.posterImgUrl;
      });
    },

    // 点击分享
    clickShare() {
      if (!this.isLogin) {
        return uni.navigateTo({
          url: '/pages/login/index',
        });
      }
      this.getCode();
      this.isShareDialog = true;
    },

    // 获取二维码
    getCode() {
      let that = this;
      this.$axios({
        url: '/goods/promotion/share/qrcode',
        method: 'get',
        params: {
          userId: this.userId,
        },
      }).then((res) => {
        if (res.data) {
          // this.codeUrl = res.data.qrcode;
          // this.bgUrl = res.data.promotionImgUrl;
          if (!this.isFinishCanvas) {
            uni.downloadFile({
              url: res.data.promotionImgUrl,
              success: function (fileRes) {
                that.bgUrl = fileRes.tempFilePath;
              },
            });
            uni.downloadFile({
              url: res.data.qrcode,
              success: function (fileRes) {
                that.codeUrl = fileRes.tempFilePath;
              },
            });
            uni.downloadFile({
              url:
                that.userInfo.avatar.indexOf('http') >= 0
                  ? that.userInfo.avatar
                  : that.$imageUrl + that.userInfo.avatar,
              success: function (fileRes) {
                that.headUrl = fileRes.tempFilePath;
              },
            });
          }
        }
      });
    },

    // 生成图片
    markImage() {
      if (!this.bgUrl || !this.codeUrl || !this.headUrl) {
        this.getCode();
        return this.$toast('生成失败，请重新操作');
      }

      let that = this;
      this.isShareDialog = false;
      this.isShowCanvas = true;

      if (this.isFinishCanvas) {
        return false;
      }

      uni.showLoading({
        title: '海报生成中',
      });

      let codeUrl = this.codeUrl;
      let bgUrl = this.bgUrl;
      let headUrl = this.headUrl;

      // this.userInfo.nickName = '阿里巴巴的的';
      let name =
        this.userInfo.nickName.length > 4
          ? this.userInfo.nickName.slice(0, 4) + '...'
          : this.userInfo.nickName;

      var ctx = uni.createCanvasContext('myCanvas');

      // 背景图片
      ctx.drawImage(bgUrl, 0, 0, 340, 340);

      // 二维码
      this.circleImgOne(ctx, codeUrl, 260, 260, uni.upx2px(70));
      // ctx.drawImage(codeUrl, 260, 260, 70, 70)

      // 矩形
      // ctx.setFillStyle('rgba(0,0,0,0.4)')
      // ctx.fillRect(185, 10, 145, 30)

      // 圆角矩形
      this.fillRoundRect(ctx, 175, 10, 155, 30, 15, 'rgba(0,0,0,0.4)');

      // 头像
      // this.circleImgOne(ctx, headUrl, 200, 10, 15);
      ctx.drawImage(headUrl, 187, 12, 26, 26);

      // 文字
      ctx.setFontSize(12);
      ctx.setFillStyle('#FFFFFF');
      ctx.fillText(name + '向你推荐', 217, 30);

      ctx.draw();
      uni.hideLoading();
      this.isFinishCanvas = true;
    },

    // ctx=Canvas实例, img=图片地址, x=x轴坐标, y=y轴坐标, r=圆形半径
    circleImgOne(ctx, img, x, y, r) {
      // 如果在绘制图片之后还有需要绘制别的元素，需启动 save() 、restore() 方法，否则 clip() 方法会导致之后元素都不可见
      // save()：保存当前 Canvas 画布状态
      // restore()：恢复到保存时的状态
      ctx.save();
      let d = r * 2;
      let cx = x + r;
      let cy = y + r;
      ctx.arc(cx, cy, r, 0, 2 * Math.PI);
      ctx.strokeStyle = '#FFFFFF'; // 设置绘制圆形边框的颜色
      ctx.stroke(); // 绘制出圆形，默认为黑色，可通过 ctx.strokeStyle = '#FFFFFF'， 设置想要的颜色
      ctx.clip();
      ctx.drawImage(img, x, y, d, d);
      ctx.restore();
    },

    /**该方法用来绘制一个有填充色的圆角矩形
     *@param cxt:canvas的上下文环境
     *@param x:左上角x轴坐标
     *@param y:左上角y轴坐标
     *@param width:矩形的宽度
     *@param height:矩形的高度
     *@param radius:圆的半径
     *@param fillColor:填充颜色
     **/
    fillRoundRect(cxt, x, y, width, height, radius, fillColor) {
      //圆的直径必然要小于矩形的宽高
      if (2 * radius > width || 2 * radius > height) {
        return false;
      }

      cxt.save();
      cxt.translate(x, y);
      //绘制圆角矩形的各个边
      this.drawRoundRectPath(cxt, width, height, radius);
      cxt.fillStyle = fillColor;
      cxt.fill();
      cxt.restore();
    },

    drawRoundRectPath(cxt, width, height, radius) {
      cxt.beginPath(0);
      //从右下角顺时针绘制，弧度从0到1/2PI
      cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
      //矩形下边线
      cxt.lineTo(radius, height);
      //左下角圆弧，弧度从1/2PI到PI
      cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
      //矩形左边线
      cxt.lineTo(0, radius);
      //左上角圆弧，弧度从PI到3/2PI
      cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2);
      //上边线
      cxt.lineTo(width - radius, 0);
      //右上角圆弧
      cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2);
      //右边线
      cxt.lineTo(width, height - radius);
      cxt.closePath();
    },

    // 保存图片
    saveImage() {
      let that = this;
      uni.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: 340,
        height: 340,
        canvasId: 'myCanvas',
        success: function (res) {
          uni.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success: function () {
              that.$successToast('保存成功');
            },
          });
        },
      });
    },

    // 关闭canvas
    closeCanvas() {
      this.isShowCanvas = false;
      uni.hideLoading();
    },
  },
};
</script>

<style lang="scss">
.app-container {
  background: #f4f2f2;
  box-sizing: border-box;
  padding-top: 184rpx;
}

.fixed-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
}

.share-container {
  position: fixed;
  right: 20rpx;
  // bottom: 30vh;
  button {
    width: 108rpx;
    height: 108rpx;
    padding: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    border-radius: 50%;
    // box-shadow: 0 1px 4px rgba(0, 21, 41, .8);
    background: #ffffff;
    border: 4rpx solid #eaeaea;
    image {
      width: 28rpx;
      height: 28rpx;
      display: block;
      flex-shrink: 0;
      margin-bottom: 6rpx;
    }
    text {
      font-size: 22rpx;
      line-height: 24rpx;
      color: #666666;
      margin-top: 8rpx;
    }
  }
}

.top-container {
  background: #ffffff;
  .tab {
    display: flex;
    margin-left: -10rpx;
    .item {
      display: flex;
      flex-direction: column;
      align-items: center;
      flex-shrink: 0;
      font-size: 28rpx;
      color: #666666;
      height: 80rpx;
      line-height: 80rpx;
      position: relative;
      padding: 0 30rpx;
      &.current {
        color: #ff3f42;
        font-weight: 600;
        &::after {
          content: '';
          display: block;
          width: 50rpx;
          height: 6rpx;
          background: #ff3f42;
          position: absolute;
          bottom: 0;
          left: 50%;
          margin-left: -25rpx;
        }
      }
    }
  }
}

.search-container {
  background: #ffffff;
  padding: 20rpx;
  .search {
    height: 64rpx;
    display: flex;
    align-items: center;
    border-radius: 64rpx;
    padding: 0 20rpx;
    border: 1px solid #eaeaea;
    image {
      width: 28rpx;
      height: 28rpx;
    }
    input {
      width: 100%;
      padding-left: 15rpx;
    }
  }
}

.banner-container {
  padding: 20rpx 20rpx 0;
  image {
    display: block;
    width: 100%;
    border-radius: 10rpx;
  }
}

.list-container {
  padding: 20rpx;
  .item {
    background: #ffffff;
    border-radius: 10rpx;
    display: flex;
    padding: 20rpx;
    margin-bottom: 20rpx;
    image {
      display: block;
      width: 180rpx;
      height: 180rpx;
      flex-shrink: 0;
    }
    .right {
      width: 490rpx;
      box-sizing: border-box;
      padding-left: 20rpx;
      .title {
        font-size: 30rpx;
        color: #333333;
        line-height: 36rpx;
        font-weight: 600;
      }
      .des {
        font-size: 24rpx;
        line-height: 30rpx;
        color: #999999;
        margin-top: 6rpx;
      }
      .stock-sales {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-top: 10rpx;
        font-size: 24rpx;
        color: #666666;
        .stock {
          display: flex;
          align-items: center;
          text {
            font-size: 24rpx;
            color: #666666;
          }
          .progress-box {
            width: 140rpx;
            border-radius: 6px;
            overflow: hidden;
            margin-left: 10rpx;
          }
        }
      }
      .bottom {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-top: 10rpx;
        .price {
          display: flex;
          flex-direction: column;
        }
        .price-1 {
          font-size: 32rpx;
          color: #ff3f42;
          line-height: 36rpx;
        }
        .price-2 {
          font-size: 26rpx;
          color: #666666;
          line-height: 30rpx;
          text-decoration: line-through;
        }
        .btn {
          width: 110rpx;
          height: 44rpx;
          background: #ff3f42;
          border-radius: 5rpx;
          font-size: 28rpx;
          color: #ffffff;
          text-align: center;
          line-height: 44rpx;
        }
        .btn2 {
          width: 110rpx;
          height: 44rpx;
          background: #aaaaaa;
          border-radius: 5rpx;
          font-size: 28rpx;
          color: #ffffff;
          text-align: center;
          line-height: 44rpx;
        }
      }
    }
  }
}

.sharelist-container {
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 999;
  width: 100%;
  box-sizing: border-box;
  background: #ffffff;
  padding: 30rpx 0;
  display: flex;
  button {
    background: none;
    border-radius: 0;
    &::after {
      border: none;
    }
  }
  .item {
    display: flex;
    width: 50%;
    flex-direction: column;
    align-items: center;
    image {
      width: 100rpx;
      height: 100rpx;
      display: block;
      margin-bottom: 20rpx;
    }
    text {
      font-size: 28rpx;
      line-height: 32rpx;
      color: #333333;
    }
  }
}
.canvas-container {
  position: fixed;
  left: 50%;
  top: 50%;
  z-index: 999;
  margin-left: -170px;
  margin-top: -170px;
  .button {
    display: flex;
    justify-content: center;
    text {
      display: block;
      width: 280rpx;
      height: 70rpx;
      border-radius: 70rpx;
      background: linear-gradient(-90deg, #ff3f42 0%, #fe781f 100%);
      font-size: 28rpx;
      color: #ffffff;
      text-align: center;
      line-height: 70rpx;
      margin-top: 20rpx;
    }
  }
}
</style>
