<template>
  <div v-if="voluntaryData" class="form">
    <el-form
      ref="form"
      :model="form"
      :rules="rules"
      :disabled="disabled||scoreLocked"
      label-width="120px"
      label-position="right"
    >
      <el-form-item
        v-if="gkType == 2 || gkType == 3"
        :label="voluntaryData.isNewGaokao?`您的首选科目`:`您的科目`"
        prop="firstSubject"
      >
        <el-radio-group v-model="form.firstSubject">
          <el-radio v-for="item in voluntaryData.course0" :key="item" :label="item" />
        </el-radio-group>
      </el-form-item>
      <el-form-item v-if="voluntaryData.isNewGaokao" :label="gkType == 2 ? '您的次选科目' : '您的选科科目'" prop="lastSubject">
        <el-checkbox-group v-model="form.lastSubject" :max="gkType == 2 ? 2 : 3">
          <el-checkbox v-for="item in voluntaryData.course1" :key="item" :label="item" />
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label="您的总分" prop="score">
        <el-input v-model="form.score" type="number" placeholder="请输入分数" @mousewheel.native.prevent />
      </el-form-item>
      <el-form-item v-if="false" label="匹配位次">
        <el-input disabled placeholder="输入分数后查看位次" :value="form.rank.lowestRank" />
        <span v-if="!scoreLocked" class="f12 f-666 ml10">当前为估分模拟，不需填写排名</span>
      </el-form-item>
      <el-form v-if="!hiddenRanking" ref="inner" :model="form" :rules="rules" label-width="120px">
        <el-form-item label="填写位次" prop="seatInput">
          <el-input v-model="form.seatInput" placeholder="输入位次（可选）" />
          <el-link type="success" target="_blank" href="/zhiyuan/scoreSegment" class="ml10" :underline="false">查看位次</el-link>
          <div class="f12 f-666 mt5" style="line-height: 16px">
            <i class="el-icon-info" />
            已根据最新位次表获取分数的最低位次，您也可以修改为成绩单上的位次。<div v-if="form.rank&&scoreLocked">位次区间[{{ form.rank.highestRank }}~{{ form.rank.lowestRank }}]</div>
          </div>
        </el-form-item>
      </el-form>
      <slot />
      <el-form-item v-if="scoreLocked" label="" label-width="0" style="margin-bottom: 0">
        <div class="f-red" style="line-height: 18px">{{ scoreLockedTips }}</div>
      </el-form-item>
      <el-form-item v-if="!isLogin||!scoreLocked&&!scoreUnlock" label="" label-width="0" style="margin-bottom: 0">
        <div class="f-red" style="line-height: 18px">{{ scoreRuleTips }}</div>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>

import { getRankByScore } from '@/api/webApi/career-course'
import { getVoluntaryData } from '@/api/webApi/professlib'
import { mapGetters } from 'vuex'
import MxConfig from '@/common/MxConfig'
import { debounce } from '@/utils'

export default {
  name: 'SimulateScore',
  props: ['form', 'disabled', 'hiddenRanking', 'provinceName', 'disableRequired', 'keepValue', 'disableWatch'],
  inject: { 'fetchVoluntaryData': { default: () => () => null }},
  data() {
    return {
      scoreLockedTips: MxConfig.scoreLockedTips,
      scoreRuleTips: MxConfig.scoreRuleTips,
      // TODO: 应该将voluntaryData提取出此控件，因为时间不够没有动这里的逻辑，怕影响其它地方
      voluntaryData: {
        isNewGaokao: false,
        minScore: 0,
        maxScore: 750,
        course0: [],
        course1: []
      },
      gkType: 0, // 1 6选三  2 4选2  3 旧高考文理
      rules: {},
      lazyRules: {
        firstSubject: [
          { required: !this.disableRequired, message: '请选择科目', trigger: 'change' },
          {
            validator: (r, v, cb) => {
              const myForm = this.form || {}
              const emptyLast = Array.isArray(myForm.lastSubject) ? myForm.lastSubject.length : myForm.lastSubject
              if (emptyLast && !v) cb('请选择科目')
              else cb()
            }, trigger: 'change'
          }
        ],
        lastSubject: [
          { required: !this.disableRequired, message: '请选择次选科目', trigger: 'change' },
          {
            validator: (r, v, cb) => {
              const maxCount = this.gkType == 2 ? 2 : 3
              const canEmpty = !this.form.firstSubject && this.disableRequired
              if (v.length < maxCount && !canEmpty) {
                cb(`请选择${maxCount}项科目`)
              } else {
                cb()
              }
            }, trigger: 'change'
          }
        ],
        score: [
          { required: !this.disableRequired, message: '请输入你的总分', trigger: 'blur' },
          { pattern: /^[1-9]\d*$/, message: '分数必须为整数', trigger: 'blur' },
          {
            validator: (r, v, cb) => {
              if (v > this.voluntaryData.maxScore) {
                cb(`成绩超出当前省份满分${this.voluntaryData.maxScore}`)
              } else if (v < 0) {
                cb(`成绩不能为负数`)
              } else {
                cb()
              }
            }, trigger: ['blur', 'change']
          }
        ],
        seatInput: [
          { required: true, message: '请输入你的位次', trigger: 'blur' },
          { pattern: /^[1-9]\d*$/, message: '请输入合法的位次', trigger: 'blur' },
          {
            validator: (r, v, cb) => {
              if (!this.form.rank && !v) {
                cb() // ignore
              } else if (v >= this.form.rank?.highestRank && v <= this.form.rank?.lowestRank) {
                cb() // valid
              } else if (this.scoreUnlock) {
                cb() // 锁分期间启动位次校验，否则用户随意输入
              } else {
                if (!this.form.rank?.highestRank || !this.form.rank?.lowestRank) cb('无效位次') //
                else cb(`输入位次必须在${this.form.rank?.highestRank}~${this.form.rank?.lowestRank}之间`)
              }
            }, trigger: ['blur', 'change']
          }
        ]
      }
    }
  },
  computed: {
    ...mapGetters(['currentUser', 'isLogin', 'scoreLocked', 'scoreUnlock']),
    injectedVoluntaryData() {
      // noinspection JSUnresolvedFunction
      return this.fetchVoluntaryData()
    }
  },
  watch: {
    'form.score': { handler: 'handleScoreUpdate' },
    'form.firstSubject': { handler: 'handleScoreUpdate' },
    'provinceName': function() {
      this.loadVoluntaryEnv()
    }
  },
  mounted() {
    if (this.injectedVoluntaryData?.maxScore) {
      // injected voluntary data is valid
      this.voluntaryData = this.injectedVoluntaryData
      this.processVoluntaryData(this.voluntaryData)
    } else {
      this.loadVoluntaryEnv()
    }
  },
  methods: {
    handleScoreUpdate: debounce(function() {
      if (this.disableWatch) return // 如果是从编辑界面同步的情况，就不去重新加载位次
      if (!this.form.init) return // 只监控用户修改的属性变化
      if (this.form.score < 0) return
      if (this.form.score > this.voluntaryData.maxScore) return
      // validate score, reduce invalid requests for ranking
      this.loadRankByScoreAndSubject()
    }, 800),
    loadVoluntaryEnv() {
      const hasBind = this.isLogin && this.currentUser.isBind
      if (!hasBind && !this.provinceName) return
      const commit = {}
      if (this.provinceName) commit['provinceName'] = this.provinceName
      getVoluntaryData(commit).then(res => {
        this.voluntaryData = res.data
        this.$emit('voluntary-ready', res.data) // 传递给父组件
        this.processVoluntaryData(this.voluntaryData)
      })
    },
    processVoluntaryData(data) {
      if (!data.course0.length && data.course1?.length) {
        this.gkType = 1
      } else if (data.course0.length && data.course1) {
        this.gkType = 2
      } else if (!data.isNewGaokao) {
        this.gkType = 3
      }
      if (this.gkType && !this.keepValue) {
        // reset form data
        this.form.score = ''
        this.form.firstSubject = ''
        this.form.lastSubject = ''
        if (data.isNewGaokao) this.form.lastSubject = []
      }
      this.rules = this.lazyRules
      this.$nextTick(() => {
        this.$refs.form?.clearValidate([])
        this.$refs.inner?.clearValidate([])
      })
    },
    loadRankByScoreAndSubject() {
      if (this.hiddenRanking) return // 此时不需要查位次
      if (!this.form.score) {
        this.$set(this.form, 'seatInput', '')
        this.$set(this.form, 'rank', {})
        return
      }
      getRankByScore({ mode: this.form.firstSubject, scoreRank: this.form.score }).then(res => {
        const { lowestRank, highestRank } = res.data
        const current = this.form.seatInput // valid current seat of user input
        const rangeInvalid = current < highestRank || current > lowestRank
        // const forceChange = !current || (rangeInvalid && !this.scoreUnlock) // 锁分期间启动位次校验，否则用户随意输入
        if (rangeInvalid) this.$set(this.form, 'seatInput', res.data.lowestRank)
        this.$set(this.form, 'rank', res.data)
        this.$nextTick(() => this.$refs.form?.clearValidate([]))
      })
    },
    async validate() {
      try {
        if (this.$refs.inner) await this.$refs.inner.validate()
        await this.$refs.form.validate()
      } catch (e) {
        const demo = Object.values(e).first()?.first()
        if (demo) this.$message.error(demo.message)
        return Promise.reject(e)
      }
    }
  }
}
</script>
<style scoped lang="scss">
.form {
  ::v-deep {
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      -webkit-appearance: none;
    }
  }
}

.form {
  width: 640px;
  padding: 30px 0;
  margin: 0 auto;
}

.form {
  ::v-deep {
    .el-form-item__label {
      padding-right: 25px;
    }

    .el-input {
      width: 300px;
    }
  }
}

.btn {
  width: 120px;
  margin-left: 83px;
  margin-top: 30px;
}

</style>
