<template>
  <div class="pay">
    <!-- 支付倒计时 -->
    <div v-if="success" class="price-box">
      <p class="price">{{ displayInfo.orderAmt }}</p>
      <p v-if="!overtime" class="time">
        支付剩余时间：
        <cr-count-down :time="displayInfo.periodSeconds" @finish="timeup" />
      </p>
      <p v-else>支付超时，订单关闭</p>
    </div>

    <!-- 推荐信用支付 -->
    <cr-pay-card
      v-if="getObjectKey(creditPayList.payList).length"
      v-model="creditPayList"
      :pay-type="payType"
      :disabled="overtime"
      :risk-limit="riskLimit"
      :show-coupon="showCoupon"
      :coupon-info="selectedCoupon"
      :has-pwd="creditPayInfo.hasPwd"
      :pay-coupon-could-be-used="
        displayInfo.payCouponInfo && displayInfo.payCouponInfo.payCouponCouldBeUsed
      "
      @changePayType="changePayType"
    />

    <!-- 其他支付方式 -->
    <cr-pay-card
      v-if="getObjectKey(thirdPayList.payList).length"
      v-model="thirdPayList"
      :pay-type="payType"
      :disabled="overtime"
      :show-coupon="showCoupon"
      :coupon-info="selectedCoupon"
      :has-pwd="creditPayInfo.hasPwd"
      :pay-coupon-could-be-used="
        displayInfo && displayInfo.payCouponInfo && displayInfo.payCouponInfo.payCouponCouldBeUsed
      "
      @changePayType="changePayType"
    />

    <!-- 支付按钮 -->
    <p v-if="isReady && !overtime" class="payBtn">
      <cr-contract
        v-if="isShowProtocol"
        ref="agreement"
        v-model="isCheckAgreement"
        :contract-list="payContractInfo.contractInfos"
      />
      <cr-button type="primary" class="btn-primary" :disabled="!payType" @click="nextAction">
        {{ accountS.text }}
      </cr-button>
    </p>
    <p v-if="overtime" class="btn">
      <cr-button type="default" class="btn-default" @click="goOrderList">我的订单</cr-button>
      <cr-button type="primary" class="btn-primary" @click="goHome">返回商城</cr-button>
    </p>
    <p class="placeholder" />
    <!-- 支付密码弹窗 -->
    <cr-pwd-field
      ref="pwd"
      v-model="pwdModal"
      :amount="amount"
      @getData="getPwd"
      @retrieveLink="retrieveLink"
    />

    <!-- 短信验证弹窗 -->
    <cr-sms-code-modal
      v-model="smsModal"
      :error-info="error"
      :order-no="orderNo"
      :flow-order-no="flowOrderNo"
      @close="smsModal = false"
      @submit="getSms"
    />

    <!-- 享花券弹窗 -->
    <cr-popup v-model="couponPopup" closeable round position="bottom">
      <cr-coupon-list
        no-render-disable-tab
        :show-coupon="couponPopup"
        :enable-list="payCouponList"
        :value="selectedCoupon.id"
        @change="handleSelectCoupon"
      />
    </cr-popup>
  </div>
</template>

<script>
import crPayCard from './components/PayCard';
import { payByWay } from '@/service/pay.service';
import crContract from './components/Contract.vue';
import crSmsCodeModal from './components/SmsModal';
import { isWechat } from '@/service/validation.service';
import { encryptByDESModeEBC } from '@/service/encrypt';
import localStorage from '@/service/localStorage.service';
import { throttle } from '@/service/utils.service';
import { goUrlExtends } from './extends';
import cookies from '@/service/cookieStorage.service';
import {
  codeArr,
  CASH_PAY,
  CREDIT_PAY,
  PAY_SUCCESS,
  creditStatus,
  IS_THIRD_PAY,
  IS_GROUP_PAY,
  IS_CREDIT_PAY,
  isDetentionFn,
  havePayingOrder,
  filterAllPayList,
  PAYMENT_CODE_PAY,
  CASH_PAY_SUCCESS,
  ACCOUNT_APPLY_FAIL,
  creditPayStatusType,
  ACCOUNT_APPLY_SUCCESS,
  SMS_VERIFICATION_CODE_PAY, //短信验证码
  FACE_VERIFICATION_CODE_PAY
} from './STATIC_DATA';
import {
  pay,
  prepay,
  getCoupon,
  ocrFaceId,
  queryPayInfo,
  kaGetNextUrl,
  reissueContract
} from '@/api/pay.api.js';
const VCC_CHANNEL = localStorage.get('vccChannel');
let Current_Url = null;
export default {
  components: {
    crPayCard,
    crContract,
    crSmsCodeModal
  },
  provide() {
    return {
      pay: this
    };
  },
  extends: goUrlExtends,
  data() {
    return {
      error: '',
      random: '',
      orderNo: '',
      payInfo: {},
      success: false,
      payType: null,
      isReady: false,
      overtime: false,
      pwdModal: false,
      smsModal: false,
      showCoupon: false,
      flowOrderNo: null,
      couponPopup: false,
      showGoFaceTip: false, // h5支付活体提示怎么处理
      payTypeList: {},
      creditPayList: {
        title: '推荐信用支付',
        payList: {}
      },
      thirdPayList: {
        title: '其他支付方式',
        payList: {}
      },
      displayInfo: {
        payCouponInfo: {}
      },
      creditPayInfo: {},
      accountS: {
        text: '确认支付',
        fn: this.pay
      },

      payCouponList: [],
      isDetention: false,
      selectedCoupon: {},
      payContractInfo: {},
      isCheckAgreement: false,
      mergePayPretreatmentInfo: {},
      tradeType: isWechat ? 'JSAPI' : 'MWEB',
      amountInfo: {}
    };
  },
  computed: {
    riskLimit() {
      return this.isRiskLimit();
    },
    amount() {
      return IS_THIRD_PAY(this.payType) || !this.selectedCoupon.faceValue
        ? this.displayInfo.orderAmt
        : (this.displayInfo.orderAmt - this.selectedCoupon.faceValue).toFixed(2);
    },
    isShowProtocol() {
      return (
        !IS_THIRD_PAY(this.payType) &&
        this.payContractInfo.payContractIsSign &&
        this.creditPayInfo.accountStatus === ACCOUNT_APPLY_SUCCESS
      );
    },
    canUseAmount() {
      return (
        ((this.selectedCoupon?.faceValue && +this.selectedCoupon.faceValue) || 0) +
        ((this.displayInfo?.creditPayInfo?.canAmt && +this.displayInfo.creditPayInfo.canAmt) || 0) -
        ((this.displayInfo?.orderAmt && +this.displayInfo.orderAmt) || 0)
      );
    }
  },
  watch: {
    payType() {
      this.getBtnStatus(this.isRiskLimit());
    }
  },
  mounted() {
    this.orderNo = this.$route.query.orderNo || cookies.get('orderNo')?.orderNo;
    cookies.set('orderNo', { orderNo: this.orderNo });
    if (this.$route?.query?.ocrflag) {
      this.payInfo = cookies.get('info') || {};
      cookies.remove('ocrflag');
      cookies.remove('info');
      // 先支付再查询信息
      this.pay(this.payInfo?.paramsData, 'ocr', cookies.get('ocrflag'));
    }
    const vccToken = localStorage.get('vccToken');
    Current_Url = `${window.location.origin}/payWaiting?vccToken=${vccToken}&orderNo=${this.orderNo}`;
    this.queryPayInfo();
    this.getCouponList(this.orderNo);
  },
  methods: {
    /* 查询支付信息 */
    async queryPayInfo() {
      console.log({
        orderNo: this.orderNo,
        isUsedMergePayMethod: false
      });
      const [data, error] = await queryPayInfo({
        orderNo: this.orderNo,
        isUsedMergePayMethod: false
      });
      if (error && codeArr.indexOf(error?.response?.businessCode) < 0) {
        this.payResult('Fail');
        return;
      }
      this.isReady = true;
      const { displayInfo = {}, payMethods, creditQuotaInfo } = data || {};
      this.overtime = displayInfo.periodSeconds <= 0;
      this.success = true;
      if (this.overtime) {
        this.displayInfo.orderAmt = displayInfo.orderAmt;
        return;
      }
      if (displayInfo.payCouponInfo && displayInfo.payCouponInfo.optimalPayCoupon) {
        this.selectedCoupon = displayInfo.payCouponInfo.optimalPayCoupon;
        this.selectedCoupon.id = this.selectedCoupon.pickupId;
        this.showCoupon = displayInfo.payCouponInfo.optimalType === 3;
      }
      this.payContractInfo = displayInfo.payContractInfo || {};
      for (const p of payMethods) {
        // 默认支付方式
        if (p.isDefault) {
          this.payType = p.method;
        }
        for (const key in displayInfo) {
          const payType = displayInfo[key].payType;
          if (!payType) {
            continue;
          }
          /* 三方支付 */
          if (IS_THIRD_PAY(p.method) && p.method === payType) {
            this.$set(this.thirdPayList.payList, key, {
              ...displayInfo[key],
              ...p,
              show: true,
              isCheck: p.isDefault || false
            });
            break;
          }
          /* 信用支付 */
          if (
            IS_CREDIT_PAY(p.method) &&
            (p.method === payType || (p.method > 3 && p.method - 2 === payType))
          ) {
            this.creditPayList.isGroupPay = IS_GROUP_PAY(p.method);
            if (p.isDefault) {
              this.mergePayPretreatmentInfo = p.mergePayPretreatmentInfo;
            }
            this.$set(this.creditPayList.payList, key, {
              ...displayInfo[key],
              ...p,
              show: true,
              payType: p.method,
              isCheck: p.isDefault || false,
              isGroupPay: IS_GROUP_PAY(p.method)
            });
            if (!('creditPayInfo' in this.creditPayList.payList)) {
              this.$set(this.creditPayList.payList, 'creditPayInfo', {
                ...displayInfo['creditPayInfo'],
                show: true,
                isCheck: false
              });
            }
            break;
          }
        }
      }

      if (this.payType === CREDIT_PAY && displayInfo.creditPayInfo.disabled) {
        this.payType = null;
      }
      this.displayInfo = displayInfo || {};

      this.creditPayInfo = displayInfo.creditPayInfo || {};
      displayInfo.periodSeconds = displayInfo.periodSeconds * 1000;
      this.getBtnStatus(this.isRiskLimit());
      if (this.payInfo?.payType) {
        this.selectedCoupon = this.payInfo.selectedCoupon;
        this.changePayType(this.payInfo.payType, this.payInfo.mergePayPretreatmentInfo);
        this.isShowProtocol && (this.isCheckAgreement = true);
        this.setAmount();
      }
      if (creditQuotaInfo?.isFreezeCreditInOtherOrder && !this.payInfo?.payType) {
        havePayingOrder.call(this);
      }
    },
    isRiskLimit() {
      const { accountStatus, riskManagementAmt } = this.creditPayInfo;
      const { orderAmt } = this.displayInfo;
      if (accountStatus === ACCOUNT_APPLY_SUCCESS) {
        const coupon = +this.selectedCoupon.faceValue || 0;
        return +riskManagementAmt + coupon < +orderAmt;
      } else {
        return false;
      }
    },
    getBtnStatus(isRiskLimit) {
      const { accountStatus } = this.creditPayInfo;
      if (!accountStatus) return;
      if (IS_CREDIT_PAY(this.payType)) {
        // payType=1--享花卡支付，payType=2微信支付
        if (accountStatus === ACCOUNT_APPLY_FAIL) {
          this.accountS = {
            text: '立即激活',
            fn: this.goApply
          };
        } else if (creditStatus.indexOf(accountStatus) > -1) {
          this.accountS = {
            text: '立即开通',
            fn: this.goApply
          };
        } else if (isRiskLimit) {
          // 展示限额提示
          this.accountS = {
            text: '认证提额',
            fn: this.goOcr
          };
        } else if (accountStatus === ACCOUNT_APPLY_SUCCESS) {
          const finalCount = this.showCoupon
            ? (this.displayInfo.orderAmt - (this.selectedCoupon.faceValue || 0)).toFixed(2)
            : this.displayInfo.orderAmt;
          const txt = `实际支付${finalCount || '0.00'}`;
          this.accountS = {
            text: txt,
            fn: this.pay
          };
        }
      } else {
        const txt = `确认支付`;
        this.accountS = {
          text: txt,
          fn: this.pay
        };
      }
    },
    /* 获取优惠券信息 */
    async getCouponList(orderNo) {
      const [data] = await getCoupon({ orderNo: orderNo });
      this.payCouponList = [];
      if (data && data.coupons) {
        data.coupons.forEach(item => {
          // 享花券
          if (item.couponCategory === 21) {
            this.payCouponList.push({
              ...item,
              id: item.pickupId,
              pickupAble: 1
            });
          }
        });
      }
    },
    nextAction: throttle(function() {
      const trackParams = {
        order_id: this.orderNo,
        pay_method: this.payType,
        vcc_state: !IS_THIRD_PAY(this.payType) ? this.creditPayInfo?.accountStatus : '',
        buttons_name: this.accountS.text
      };
      cookies.set('payTrackInfo', trackParams);
      if (this.isShowProtocol) {
        if (!this.isCheckAgreement) {
          this.$toast('请仔细阅读并同意相关协议');
          return;
        }
        this.reissueContract();
      }
      this.accountS.fn();
    }, 1000),
    /* 预支付 */
    async pay(params, isOcr) {
      // 组合支付的提示和享花卡支付逻辑
      if (this.overtime) {
        this.$toast('订单已超时！');
        return;
      }
      this.error = '';
      this.setAmount();
      if (
        !params &&
        !this.isDetention &&
        IS_THIRD_PAY(this.payType) &&
        this.payType !== CASH_PAY &&
        !isOcr
      ) {
        this.isDetention = true;
        isDetentionFn.call(this);
        return;
      }
      this.isDetention = false;
      /* 设置密码 */
      if (IS_CREDIT_PAY(this.payType) && !this.creditPayInfo.hasPwd) {
        this.retrieveLink();
        return;
      }
      if (this.payType === CREDIT_PAY && this.canUseAmount < 0) {
        this.$dialog({
          message: '您的消费额度不足，请更换支付方式！',
          confirmButtonText: '知道了',
          showCancelButton: false,
          confirmButtonColor: '#EC1500'
        });
        return;
      }
      const paramsData = {
        ...params,
        quitUrl: Current_Url,
        returnUrl: Current_Url,
        ocrAuth: {
          isH5: true
        },
        orderNo: this.orderNo,
        payMethod: this.payType,
        payCouponId: this.selectedCoupon.id || '',
        mergePayPretreatmentId: this.mergePayPretreatmentInfo?.mergePayPretreatmentId
      };
      const [data, error] = params
        ? isOcr
          ? await pay(params)
          : await pay(paramsData)
        : await prepay(paramsData);
      /* 支付失败 */
      if (error) {
        if (error?.response?.businessCode === '3001') {
          /* 有享花卡未支付的订单 */
          havePayingOrder.call(this);
          return;
        }
        if (codeArr.indexOf(error?.response?.businessCode) < 0) {
          this.payResult('Fail', error.message);
          return;
        }
        error?.message && this.$toast(error?.message);
        this.error = error?.message;
        this.pwdModal && this.retrieve();
        return;
      }
      // TODO 此处在获取与支付信息后，，跳转前通过判断渠道号，来判断是否在app中的打开，来规避支付等待页中的schema跳转问题
      if (localStorage.get('vccChannel')) localStorage.set('isAppInner', true);
      const {
        creditPayInfo = {},
        wxPayInfo = {},
        flowOrderNo,
        aliPayInfo = {},
        vmPayInfo = {}
      } = data;
      const creditPayStatus = creditPayInfo.creditPayStatus;
      this.flowOrderNo = flowOrderNo;
      if (wxPayInfo.mwebUrl) {
        /* 微信支付 */
        payByWay(this.tradeType, { ...wxPayInfo, url: wxPayInfo.mwebUrl });
        return;
      } else if (aliPayInfo.order_string) {
        /* 支付宝支付 */
        payByWay('ALIWEB', { ...aliPayInfo, url: aliPayInfo.order_string });
        return;
      } else if (creditPayStatus === PAY_SUCCESS) {
        /*  信用支付成功 */
        this.close();
        this.payResult('Success');
        return;
      } else if (
        creditPayStatus === PAYMENT_CODE_PAY ||
        creditPayStatus === SMS_VERIFICATION_CODE_PAY
      ) {
        /* 密码或者短信鉴权 */
        this.close();
        this[`${creditPayStatusType[creditPayStatus]}Modal`] = true;
        return;
      } else if (creditPayStatus === FACE_VERIFICATION_CODE_PAY) {
        /* 人脸鉴权 */
        cookies.set('info', {
          paramsData: {
            flowOrderNo: this.flowOrderNo,
            ...paramsData
          },
          payType: this.payType,
          selectedCoupon: this.selectedCoupon,
          isCheckAgreement: this.isCheckAgreement,
          mergePayPretreatmentInfo: this.mergePayPretreatmentInfo
        });
        this.close();
        this.goOcr();
      } else if (vmPayInfo?.vmPayStatus === CASH_PAY_SUCCESS) {
        !params && this.pay({ flowOrderNo: this.flowOrderNo });
        params && this.payResult('Success');
      }
    },
    payResult(type, error) {
      /* 跳转支付结果页面 */
      this.$router.replace({
        name: `pay${type}`,
        query: {
          reason: error,
          orderNo: this.orderNo,
          payType: this.payType,
          finalAmt: this.amountInfo.finalAmt || '',
          freeAmount: this.amountInfo.freeAmount || ''
        }
      });
    },
    /* 选择支付方式 */
    changePayType(type, mergePayPretreatmentInfo) {
      if (this.payType === CASH_PAY) {
        this.$toast('请选择现金券支付！');
        type = CASH_PAY;
      }
      this.payType = type;
      this.isDetention = false;
      this.thirdPayList = filterAllPayList(type, this.thirdPayList);
      this.creditPayList = filterAllPayList(type, this.creditPayList);
      this.mergePayPretreatmentInfo = mergePayPretreatmentInfo || null;
    },
    openCouponModal() {
      this.random = Math.random();
      this.couponPopup = true;
    },
    /* 选取优惠券 */
    handleSelectCoupon(id, selectedCoupon) {
      this.selectedCoupon = selectedCoupon || {};
      this.getBtnStatus(this.isRiskLimit());
      this.couponPopup = false;
    },
    close() {
      this.pwdModal = false;
      this.smsModal = false;
    },
    /* 支付时间超时 */
    timeup() {
      this.overtime = true;
      this.close();
    },
    /* 获取支付密码 */
    async getPwd({ pwd }) {
      this.retrieve();
      this.pay({ flowOrderNo: this.flowOrderNo, password: await encryptByDESModeEBC(pwd) });
    },
    /*  短信验证码回调 */
    getSms(e) {
      this.pay({ flowOrderNo: this.flowOrderNo, smsAuthorizationCode: e });
    },
    /* 进入h5授信流程 */
    async goApply() {
      const [{ nextUrl }] = await kaGetNextUrl();
      if (!nextUrl) return;
      window.location.href = `${nextUrl}&returnUrl=${window.location.origin}/pay&from=pay`;
    },
    /* 走h5活体流程 */
    async goOcr() {
      const [res] = await ocrFaceId({
        isH5: true,
        type: 'xyqb',
        orderNo: this.orderNo,
        flowOrderNo: this.flowOrderNo,
        callBackUrl: encodeURIComponent(`${window.location.href}&ocrflag=1`)
      });
      if (!res.callBackUrl) return;
      window.location.href = res.callBackUrl;
    },
    /* 密码支付失败 */
    retrieve() {
      this.$refs.pwd.tips(false, this.error);
    },
    /* 忘记密码 */
    retrieveLink() {
      let url = `${this.creditPayInfo.forgetPwdJumpUrl}&vccChannel=${VCC_CHANNEL}&redirectUrl=${window.location.href}`;
      url = url.replace('{token}', localStorage.get('vccToken'));
      window.location.href = url;
    },
    getObjectKey(obj) {
      return Object.keys(obj);
    },
    setAmount() {
      const faceValue = +this.selectedCoupon?.faceValue || 0;
      const orderAmt = +this.displayInfo?.orderAmt || 0;
      const finalAmt =
        IS_THIRD_PAY(this.payType) || !this.showCoupon
          ? orderAmt || '0.00'
          : (orderAmt - faceValue || 0).toFixed(2);
      const freeAmount =
        !IS_THIRD_PAY(this.payType) && this.showCoupon ? faceValue || '0.00' : '0.00';
      this.amountInfo = { finalAmt, freeAmount };
      cookies.set('amount', { finalAmt, freeAmount });
    },
    async reissueContract() {
      await reissueContract({
        templateIdList: this.payContractInfo.contractInfos.map(item => item.contractId)
      });
    }
  }
};
</script>

<style lang="less">
@import './index';
</style>
