<template>
  <view>
    <uni-popup
      ref="popup_buy"
      type="bottom"
      mask-background-color="rgba(0,0,0,0.8)"
      :is-mask-click="true"
    >
      <view>
        <view v-if="cdTime" class="yfs-cd-bar">
          <view class="yfs-cd-main">
            {{ cdText }}<text class="yfs-cd-time">{{ cdTime }}</text>
          </view>
        </view>
        <view class="popup-buy">
          <text class="title">确认支付</text>
          <image
            class="close"
            src="@/assets/icon/icon-close-dark.png"
            @click="handlePopupClose('popup_buy')"
          >
          </image>
          <view class="detail">
            <image class="cover" :src="img" mode="aspectFill"></image>
            <view class="body">
              <text class="detail-name">{{ title }}</text>
              <view class="bottom">
                <text class="color"
                  >&yen;<text class="big">{{ originPrice }}</text></text
                >
                <view class="tips">
                  <text>该商品不支持7天无理由退换</text>
                  <text class="big">x{{ buyNum }}</text>
                </view>
              </view>
            </view>
          </view>
          <view class="line-wrap">
            <view
              class="line"
              @click="currentCoupon ? handlePopupShow('popup_coupon') : ''"
            >
              <image
                class="label-icon"
                src="@/assets/detail/icon-coupon.png"
              ></image>
              <view class="label">
                <text>优惠券</text>
              </view>
              <view class="line-body"></view>
              <view v-if="currentCoupon" class="right color">
                <text>已使用优惠 &yen; {{ currentCoupon.reduce_price }}</text>
                <image class="more" src="@/assets/icon/icon-more.png"></image>
              </view>
              <view v-else class="right">
                <text>暂无可用优惠券</text>
              </view>
            </view>
          </view>
          <view class="line-wrap">
            <view
              :class="['line', { disabled: disabledBalance }]"
              @click="handleChangePaytype('1')"
            >
              <image
                class="label-icon"
                src="@/assets/detail/icon-balance.png"
              ></image>
              <view class="label">余额支付</view>
              <view class="line-body">
                （可用余额：&yen;{{ userInfo.show_price }}）
              </view>
              <view
                :class="[
                  'checkbox',
                  { disabled: disabledBalance, checked: payType === '1' },
                ]"
              ></view>
            </view>
            <view class="line" @click="handleChangePaytype('2')">
              <image
                class="label-icon"
                src="@/assets/detail/icon-wechat.png"
              ></image>
              <view class="label">微信支付</view>
              <view class="line-body"
                >（注：连续支付可能被拦截，建议充值购买）</view
              >
              <view :class="['checkbox', { checked: payType === '2' }]"></view>
            </view>
          </view>
          <view v-if="isScore" class="line-wrap integral">
            <view class="line">
              <view class="line-body">
                <view class="integral-desc"
                  >可用积分：<text class="big">{{ canUseScore }}</text
                  ><image
                    src="@/assets/detail/icon-help.png"
                    class="icon-help"
                    @click="handlePopupShow('popup_integral')"
                  ></image>
                  <!-- <image
                  src="@/assets/detail/icon-edit.png"
                  class="icon-edit"
                ></image> -->
                </view>
              </view>
              <switch
                class="score-switch"
                :checked="useScore"
                color="#08C2C3"
                @change="handleChangeUseScore"
              />
            </view>
          </view>
          <view class="line-wrap agreement">
            <view class="line">
              <view class="label" @click="selectAgreement = !selectAgreement">
                <view
                  :class="['checkbox', { checked: selectAgreement }]"
                ></view>
                <text class="small"
                  >同意《云果国潮玩法说明》，未成年不可购买</text
                >
              </view>
            </view>
          </view>
          <view class="pay-footer">
            <view class="text">
              <text>应付：</text>
              <text class="color">&yen;</text>
              <text class="color big">{{ realPrice }}</text>
            </view>
            <button
              :class="[
                'btn',
                {
                  'btn-gray': !selectAgreement,
                },
              ]"
              @click="pay"
            >
              立即支付
            </button>
          </view>
        </view>
      </view>
    </uni-popup>
    <uni-popup
      ref="popup_coupon"
      type="bottom"
      mask-background-color="rgba(0,0,0,0.8)"
      :is-mask-click="true"
    >
      <view class="popup-buy">
        <text class="title">选择优惠券</text>
        <image
          class="close"
          src="@/assets/icon/icon-close-dark.png"
          @click="handlePopupClose('popup_coupon')"
        >
        </image>
        <view class="coupon-list">
          <coupon
            v-for="item in coupons"
            :key="item.id"
            :coupon="item"
            :checked="currentCoupon.id === item.id"
            @click="handleSelectCoupon(item.id)"
          >
          </coupon>
        </view>
      </view>
    </uni-popup>
    <uni-popup
      ref="popup_integral"
      type="center"
      mask-background-color="rgba(0,0,0,0.8)"
      :is-mask-click="true"
    >
      <view class="popup-wrap">
        <view class="popup-content">
          <view class="h1"><text>积分说明</text></view>
          <view class="p" v-html="scoreText || ''"></view>
        </view>
        <image
          class="popup_close"
          :src="require('@/assets/icon/icon-close.png')"
          @click="handlePopupClose('popup_integral')"
        ></image>
      </view>
    </uni-popup>
  </view>
</template>

<script>
import Decimal from "decimal.js";
import api from "@/lib/api/api";
import login from "@/lib/utils/login";
import coupon from "@/components/coupon/coupon.vue";

export default {
  name: "PayPop",
  components: {
    coupon,
  },
  props: {
    title: {
      type: String,
      default: "",
    },
    img: {
      type: String,
      default: "",
    },
    detailId: {
      type: String,
      default: "0",
    },
    type: {
      type: Number,
      default: 1, // 1：福袋； 2：一番赏；
    },
    scoreText: {
      type: String,
      default: "",
    },
    cdText: {
      type: String,
      default: "",
    },
    cdTime: {
      type: String,
      default: "",
    },
    isScore: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      userInfo: null,
      useScore: true,
      scoreInfo: null,
      balanceCoupons: [],
      wxCoupons: [],
      couponIdx: 0,
      payType: "1", // 1-余额；2-微信
      buyNum: 0,
      originPrice: 0,
      selectAgreement: false,
      //   bagData: null,
    };
  },
  computed: {
    coupons() {
      if (this.payType === "1") return this.balanceCoupons;
      else return this.wxCoupons;
    },
    currentCoupon() {
      const current = this.coupons[this.couponIdx];
      return current
        ? {
            ...this.coupons[this.couponIdx],
          }
        : null;
    },
    isLogin() {
      return !!this.userInfo && !!this.userInfo.session;
    },
    disabledBalance() {
      // 优惠券不能单买
      if (!this.userInfo?.show_price) return true;

      let coupons = 0;
      if (this.balanceCoupons && this.balanceCoupons[0]) {
        coupons = this.balanceCoupons[0]?.reduce_price || 0;
      }

      let score = 0;
      if (this.useScore && this.canUseScore) {
        score = new Decimal(this.canUseScore).div(this.scoreProportion);
      }

      return (
        new Decimal(this.userInfo.show_price)
          .plus(coupons)
          .plus(score)
          .toNumber() < this.originPrice
      );
    },
    salePrice() {
      if (this.currentCoupon) {
        return new Decimal(this.currentCoupon.real_price)
          .minus(this.currentCoupon.reduce_price_sort)
          .div(100)
          .toNumber();
      }
      return this.originPrice;
    },
    scoreProportion() {
      if (!this.scoreInfo || !this.scoreInfo.score_price) return 0;
      return new Decimal(this.scoreInfo.score)
        .div(this.scoreInfo.score_price)
        .toNumber();
    },
    canUseScore() {
      if (this.salePrice === 0 || !this.scoreInfo || !this.isScore) {
        return 0;
      }
      const decimal = new Decimal(this.salePrice).mul(100);
      const maxScore = decimal
        .minus(decimal.mul(this.scoreInfo.percent).div(10))
        .div(new Decimal(this.scoreProportion).div(100))
        .floor()
        .toNumber();
      return Math.min(this.scoreInfo.score, maxScore);
    },
    realPrice() {
      let decimal = new Decimal(this.salePrice).mul(100);

      if (this.useScore && this.canUseScore) {
        decimal = decimal.minus(
          new Decimal(this.canUseScore).mul(
            new Decimal(this.scoreProportion).div(100)
          )
        );
      }

      return decimal.div(100).toNumber();
    },
  },
  methods: {
    handlePopupShow(popup_ref) {
      if (this.$refs[popup_ref]) this.$refs[popup_ref].open();
    },
    handlePopupClose(popup_ref) {
      if (this.$refs[popup_ref]) this.$refs[popup_ref].close();
    },
    closeAll() {
      this.handlePopupClose("popup_buy");
      this.handlePopupClose("popup_coupon");
      this.handlePopupClose("popup_integral");
    },
    handleChangeUseScore(e) {
      this.useScore = e.detail.value;
    },
    async getUserInfo() {
      try {
        const data = await api.userInfo(this.userInfo.session);
        data.data.show_price = Number(data.data.show_price);
        this.userInfo = { ...this.userInfo, ...data.data };
      } catch (e) {
        uni.showToast({
          icon: "none",
          title: "用户信息失效,请重新登录",
          duration: 2e3,
        });
        login.logout();
        this.userInfo = null;
        throw e;
      }
    },

    // 获取可用优惠券
    async getUserCoupons() {
      const data = await api.getUserCoupons({
        kuji_id: this.detailId,
        session: this.userInfo.session,
        num: "" + this.buyNum,
        pay_type: this.payType,
      });

      if (data.data) {
        this.scoreInfo = data.data.score_info;
        this.balanceCoupons = data.data.balance_pay;
        this.wxCoupons = data.data.wx_pay;
        this.couponIdx = 0;
      } else {
        this.scoreInfo = null;
        this.balanceCoupons = [];
        this.wxCoupons = [];
      }
    },

    async buy(num = 1, originPrice, loading = true) {
      this.buyNum = num;
      this.originPrice = originPrice;

      const uinfoStr = uni.getStorageSync("userinfo");
      if (uinfoStr) {
        this.userInfo = JSON.parse(uinfoStr);
      }

      if (loading) {
        uni.showLoading({
          title: "加载中",
          mask: true,
        });
      }
      try {
        await this.getUserInfo();
        await this.getUserCoupons();

        this.payType = !this.disabledBalance ? "1" : "2";

        this.handlePopupShow("popup_buy");
      } catch (e) {
        uni.showToast({
          icon: "none",
          title: e.message || "请求失败，请重试",
          duration: 2e3,
        });
      }
      if (loading) {
        uni.hideLoading();
      }
    },
    handleChangePaytype(payType) {
      if (this.disabledBalance && payType === "1") {
        uni.showToast({
          icon: "none",
          title: "余额不足",
          duration: 2e3,
        });
        return;
      }
      this.couponIdx = 0;
      this.payType = payType;
    },
    async pay() {
      if (this.disabledBalance && this.payType === "1") {
        uni.showToast({
          icon: "none",
          title: "余额不足",
          duration: 2e3,
        });
        return;
      }
      if (!this.selectAgreement) {
        uni.showToast({
          icon: "none",
          title: "请先勾选和同意用户协议",
          duration: 2e3,
        });
        return;
      }
      try {
        this.showCard = false;
        const data = await (this.payType === "1" ||
        (this.payType === "2" && this.realPrice === 0)
          ? this.balancePay()
          : this.wechatPay());
        this.handlePopupClose("popup_buy");
        this.$emit("paySuccess", data);
      } catch (e) {
        uni.hideLoading();
        uni.showToast({
          title: e.message || "支付失败",
          icon: "none",
          mask: true,
          duration: 2e3,
        });
      }
    },
    async wechatPay() {
      uni.showLoading({
        title: "加载中",
        mask: true,
      });

      const { errno, errmsg, data } = await (this.type === 2
        ? api.yfsPrePay
        : api.prePay)({
        session: this.userInfo.session,
        id: "" + this.detailId,
        account_coupon_id: this.currentCoupon?.id || 0,
        num: "" + this.buyNum,
        score: Number(this.useScore ? this.canUseScore : 0),
      });

      uni.hideLoading();

      if (errno !== 10000) {
        throw new Error(errmsg);
      }
      const {
        timeStamp,
        nonceStr,
        package: pkg,
        signType,
        paySign,
        order_id,
      } = data;

      return new Promise((resolve, reject) => {
        uni.requestPayment({
          provider: "wxpay",
          timeStamp,
          nonceStr,
          package: pkg,
          signType,
          paySign,
          success: async (res) => {
            if (res.errMsg === "requestPayment:ok") {
              resolve();
            } else {
              const type =
                res.errMsg === "requestPayment:fail cancel" ? "3" : "2";
              await (this.type === 2 ? api.yfsCompletePay : api.completePay)({
                session: this.userInfo.session,
                order_id,
                type,
              }).catch((e) => {
                console.log(e);
              });
              reject(new Error(type === "3" ? "取消支付" : "支付失败"));
            }
          },
          fail: async (err) => {
            const type =
              err.errMsg === "requestPayment:fail cancel" ? "3" : "2";
            await api
              .completePay({
                session: this.userInfo.session,
                order_id,
                type,
              })
              .catch((e) => {
                console.log(e);
              });
            reject(new Error(type === "3" ? "取消支付" : "支付失败"));
          },
        });
      }).then(() => this.loopPayRes("" + order_id));
    },
    async loopPayRes(order_id) {
      uni.showLoading({
        title: "加载中",
        mask: true,
      });
      const data = await (this.type === 2 ? api.yfsQueryPay : api.queryPay)({
        session: this.userInfo.session,
        order_id,
      });
      if (data.errno == 90000) {
        return new Promise((r) => {
          setTimeout(() => r(), 1000);
        }).then(() => this.loopPayRes(order_id));
      }

      uni.hideLoading();

      if (data.errno == 10000) {
        return data.data;
      }

      throw new Error("订单查询失败");
    },
    async balancePay() {
      uni.showLoading({
        title: "加载中",
        mask: true,
      });
      const data = await (this.type === 2 ? api.yfsBalancePay : api.balancePay)(
        {
          session: this.userInfo.session,
          id: "" + this.detailId,
          account_coupon_id: this.currentCoupon?.id || 0,
          num: "" + this.buyNum,
          score: Number(this.useScore ? this.canUseScore : 0),
        }
      );
      uni.hideLoading();

      if (data.errno !== 10000) {
        throw new Error(data.errmsg);
      }

      return data.data;
    },
    handleSelectCoupon(id) {
      const i = this.coupons.findIndex((item) => item.id === id);
      this.couponIdx = i;
      this.handlePopupClose("popup_coupon");
    },
  },
};
</script>

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