<template>
  <!-- 回款计划 -->
  <el-form ref="form" label-width="206px" class="payment-plan-container">
    <el-form-item class="payment-plan-line" label-width="156px" label="回款次数" :required="required.payback">
      <number-input
        :value="pageForm.paybackTimes"
        @input="onPaybackChange"
        placeholder="请输入"
        :min="0"
        maxlength="2">
        <template #append>次</template>
      </number-input>
      <div class="payback-table-container" v-if="payBackTimesMoreThan1">
        <el-table
          :data="paybackTableData"
          border
          stripe
          :summary-method="getSummaries"
          show-summary>
          <el-table-column
            type="index"
            header-align="center"
            align="center"
            width="100"
            label="序号">
          </el-table-column>
          <el-table-column
            prop="name"
            header-align="center"
            align="center"
            label="预计回款时间">
            <template slot-scope="scope">
              <el-date-picker
                :value="paybackTableData[scope.$index].time"
                @input="onChangeTableLineData('time', scope.$index, $event)"
                value-format="timestamp"
                type="date"
                placeholder="请选择日期">
              </el-date-picker>
            </template>
          </el-table-column>
          <el-table-column
            prop="money"
            header-align="center"
            align="center"
            label="预计回款金额（元）">
            <template slot-scope="scope">
              <number-input
                :value="paybackTableData[scope.$index].money"
                @input="onPaybackSplitMoneyChange(scope, $event)"
                type="number"
                placeholder="请输入"
                :min="0"
                :disabled="scope.$index === paybackTableData.length - 1"
              ></number-input>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-form-item>
    <el-form-item class="payment-plan-line" :label="paybackTimeLabel" :required="required.paymentDeadline" v-if="!payBackTimesMoreThan1">
      <number-input
        :value="pageForm.paymentDeadline"
        @input="onPaymentDeadlineChange"
        placeholder="请输入"
        maxlength="3">
        <template #append>个工作日回款，预计回款时间：<span style="color: #36a3f7">{{ expectedPaymentDeadlineTimeString }}</span></template>
      </number-input>
    </el-form-item>
  </el-form>
</template>

<script>
import { debounce } from 'lodash'
import {dateFormatter} from '@/assets/js/date'
import { toNumber } from '@/utils/utils'
import { selectorVModelMixin } from '@/utils/mixins/selector-v-model'
import { agreeStatusOptions } from '@/views/create-order/data/index.js'
import NumberInput from '@/views/create-order/ui/NumberInput.vue'
import { getWorkDay } from '@/api/modules'
import { pageFormState } from '@/views/create-order/mixins'
import { mapState, mapGetters } from 'vuex'
import { PayBackTableRow } from '@/views/create-order/data/interface'
import { add, sub } from '@/utils/number'

export default {
  name: 'PaymentPlanModule',
  mixins: [selectorVModelMixin, pageFormState],
  components: {
    NumberInput
  },
  props: {
    contractStatus: {
      type: [String, Number],
      default: 0,
      validator(v) {
        return agreeStatusOptions.map(a => a.value).concat(-1).includes(v)
      }
    },
    contractTime: {
      type: [String, Number],
      default: ''
    }
  },
  data() {
    return {
      conf: {
        paybackMin: 1,
        paybackMax: 5,
      },
      required: {
        payback: true,
        paymentDeadline: true,
      },
      form: {
        // payback: '1',
        // paymentDeadline: '',
      },
      // paybackTableData: [],
      expectedPaymentDeadlineTime: '',
    }
  },
  computed: {
    ...mapState({
      pageForm: state => state.order.pageForm,
    }),
    ...mapGetters('order', ['pageTotalMoney', 'exceptPaybackMoney']),
    buySubject() {
      return this.pageForm.buySubject
    },
    payBackTimesMoreThan1() {
      return this.pageForm.paybackTimes > 1
    },
    paybackTableData() {
      return this.pageForm.paybackTableData
    },
    exceptedPayBackMoney() {
      return this.exceptPaybackMoney
    },
    requiredList() {
      return [
        {
          field: 'payback',
          message: '回款次数为必填项', // 错误提示文案
          rank: 2, // 提示优先级，值越小优先级越高
          required: this.required.payback,
        },
        {
          field: 'paymentDeadline',
          message: '回款时间为必填项', // 错误提示文案
          rank: 2,
          required: this.required.paymentDeadline && !this.payBackTimesMoreThan1,
        },
      ].filter(f => f.required)
    },
    expectedPaymentDeadlineTimeString() {
      return this.pageForm.expectedPaymentDeadlineTime || '-'
    },
    paybackTimeLabel() {
      return this.contractStatus === 1 ? '自协议签订之日起': '自订单创建之日起'
    }
  },
  watch: {
    contractTime() {
      if (this.pageForm.paymentDeadline) {
        this.onPaymentDeadlineChangeCallback()
      }
    },
    buySubject() {
      this.reset()
    }
  },
  methods: {
    reset() {
      this.clearPaybackTableData()
      this.onPaybackChange(1)
    },
    validate() {
      return new Promise((resolve, reject) => {
        const { payback, paymentDeadline } = this.form
        const pass = payback && paymentDeadline
        if (pass) {
          resolve()
        } else {
          reject()
        }
      })
    },
    getState() {
      return Object.assign({}, this.form)
    },
    setState(t) {
      if (!t) return
      Object.assign(this.form, t)
    },
    onPaybackChange(i) {
      const max = this.conf.paybackMax
      const min = this.conf.paybackMin
      if (i > max) {
        this.setPageFormData('paybackTimes', max)
        this.$message({
          message: `最大值为${max}`,
          type: 'warning'
        })
      } else if (i < min && i !== '') {
        this.$message({
          message: `最小值为${min}`,
          type: 'warning'
        })
        this.setPageFormData('paybackTimes', 1)
      } else {
        this.setPageFormData('paybackTimes', i)
      }
      if (i > 1) {
        this.initPaybackTableData()
      } else {
        this.clearPaybackTableData()
      }
    },
    calcLastColumnMoney() {
      // 1. 计算最后一个格子的金额
      // 1.1 先计算除了最后一个的总和
      let eNum = 0
      this.paybackTableData.forEach((p, index) => {
        if (index <= this.paybackTableData.length - 2) {
          // eNum += Number(p.money)
          // 高精度计算
          eNum = add(eNum, Number(p.money))
        }
      })
      
      // const lastMoney = this.exceptedPayBackMoney - eNum
      // 高精度计算
      const lastMoney = sub(this.exceptedPayBackMoney ,eNum)

      return lastMoney
    },
    onPaybackSplitMoneyChange(scope, e) {
      const index = scope.$index
      this.onChangeTableLineData('money', index, e)
      if (!this.pageTotalMoney.hasContract) {
        this.onChangeTableLineData('money', index, '')
        return this.$message({
          message: '请先输入合同金额',
          type: 'warning'
        })
      }
      if (scope.row.money === 0 || scope.row.money === '0') {
        this.onChangeTableLineData('money', index, '')
        return this.$message({
          message: '不可为0',
          type: 'warning'
        })
      }
      let lastMoney = this.calcLastColumnMoney()
      // 1.2 限制当前格子的金额
      if (lastMoney < 0) {
        this.$message({
          message: '需小于应收金额',
          type: 'warning'
        })
        this.onChangeTableLineData('money', index, '')
        lastMoney = this.calcLastColumnMoney()
      }
      this.onChangeTableLineData('money', this.paybackTableData.length - 1, lastMoney)
    },
    onPaymentDeadlineChange(e) {
      this.setPageFormData('paymentDeadline', e)
      this.onPaymentDeadlineChangeCallback()
    },
    // 回款计划，工作日变更
    onPaymentDeadlineChangeCallback: debounce(function() {
      this.expectedPaymentDeadlineTime = ''

      // 签协议：预计回款时间=协议签订时间+填写的工作日
      // 不签协议：预计回款时间=订单创建时间+填写的工作日

      // 回款工作日为0
      const paymentDeadline = toNumber(this.pageForm.paymentDeadline)
      if (paymentDeadline === 0) {
        if (this.contractStatus === 1) {
          this.expectedPaymentDeadlineTime  = dateFormatter(this.contractTime || new Date(), 'yyyy-MM-dd')
        }else{
          this.expectedPaymentDeadlineTime = dateFormatter(new Date(), 'yyyy-MM-dd')
        }
        this.setPageFormData('expectedPaymentDeadlineTime', this.expectedPaymentDeadlineTime)
      } else {
        let start = ''
        if (this.contractStatus === 1) { // 签协议
          start = dateFormatter(this.contractTime || new Date(), 'yyyy-MM-dd')
        } else { // 不签协议
          start = dateFormatter(new Date(), 'yyyy-MM-dd')
        }
        if (!paymentDeadline  || !start) {
          return
        }
        const params = {
          inputTime: start,
          workDayNum: toNumber(paymentDeadline)
        }
        getWorkDay(params).then((res) => {
          if (res.data) {
            // this.expectedPaymentDeadlineTime = res.data
            this.setPageFormData('expectedPaymentDeadlineTime', res.data)
          }
        })
      }
    }, 700),
    clearPaybackTableData() {
      this.setPageFormData('paybackTableData', [])
    },
    initPaybackTableData() {
      const arr = new Array(this.pageForm.paybackTimes - 0).fill(undefined).map(() => new PayBackTableRow())
      // this.paybackTableData = arr
      this.setPageFormData('paybackTableData', arr)
    },
    getSummaries(param) {
      const { columns } = param
      const sums = [];
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '合计';
          return;
        }
        if (index === 1) {
          sums[index] = '-';
          return
        }
        if (index === 2) {
          sums[index] = this.exceptedPayBackMoney || '-';
          return
        }
      });
      return sums;
    },
    onChangeTableLineData(key, index, e) {
      // this.paybackTableData[index].time = e
      this.updatePageFormArrayObjectValue({
        arrayName: 'paybackTableData',
        index,
        key,
        newValue: e
      })
    },
  }
}
</script>

<style lang="scss" scoped>
.payment-plan-line {
  $radius: 4px;
  ::v-deep {
    .el-input-group__append {
      background: transparent;
      border: none;
      color: $gray_10;
    }
    .el-input-group--append {
      width: auto;
      .el-input__inner {
        width: 128px;
        border-top-right-radius: $radius;
        border-bottom-right-radius: $radius;
      }
    }
  }
}
.payback-table-container {
  margin-top: 8px;
  ::v-deep {
    .el-table {
      border-radius: 6px;
    }
    .el-table__header {
      tr,
      th.el-table__cell {
        background: #f5f7fa;
      }
    }
  }
}
</style>
