<template>
  <div>
    <div class="page">
      <div class="page-content">
        <div class="p-title">赛程与规则设置</div>
        <el-form :model="form" :rules="validRules" label-width="170px" label-suffix=":" size="small"
          :disabled="!!(!editing && id)">
          <el-form-item label="竞赛类型">
            {{ step1.completeCompetitionSetup.competitionType ? '团队赛（' + step1.completeCompetitionSetup.minTeamSize +
              '-' + step1.completeCompetitionSetup.maxTeamSize + '人/队）' : '个人赛' }} <span
              class="tips">（如需修改，请返回上一步。）</span>
          </el-form-item>
          <el-form-item prop="rule" label="赛制">
            <el-radio v-for="(rule, i) in rules" :key="i" v-model="form.rule" :label="rule.id">{{ rule.name
              }}</el-radio>
            <p class="tips">积分赛——包含多个竞赛阶段，每个阶段的成绩都包含在最终总成绩里，最后一轮结束后总成绩排名靠前的参赛者得到获奖资格。</p>
            <p class="tips">淘汰赛——包含多个竞赛阶段，每个阶段结束后之后只有部分参赛者能晋级下一阶段，晋级最后一轮且在最后一轮排名靠前的参赛者得到获奖资格。</p>
            <p class="tips">单项赛——仅包含一个竞赛阶段，单项的成绩排名即为最终排名，排名靠前的参赛者得到获奖资格。</p>
            <p class="tips">注：系统默认排名规则，优先按分数排名（分数高则排名靠前），分数相同则按用时排名（用时短则排名靠前）。</p>
          </el-form-item>
          <template v-if="form.rule !== 2">
            <el-form-item prop="stageNum" label="阶段数量">
              <div class="input-center">
                <el-select v-model="form.stageNum" @change="stageChange">
                  <el-option v-for="i in 10" :key="i" :label="i" :value="i"></el-option>
                </el-select>
              </div>
              <div v-if="step1.completeCompetitionSetup.competitionType" class="tips">
                (团队赛是否限制队内每个成员只能参加一个阶段赛项？
                <el-radio v-model="form.teamLimit" :label="1">是</el-radio>
                <el-radio v-model="form.teamLimit" :label="0">否</el-radio>
                )
              </div>
            </el-form-item>
            <el-form-item v-if="!form.rule" prop="resultCalculationMethod" label="总成绩计算方式">
              <el-radio v-model="form.resultCalculationMethod" :label="0">各阶段成绩加权求和</el-radio>
              <el-radio v-model="form.resultCalculationMethod" :label="1">各阶段成绩直接求和</el-radio>
              <el-radio v-model="form.resultCalculationMethod" :label="2">各阶段成绩取平均值</el-radio>
              <p class="tips">（若选择加权求和，则需要设置每个阶段成绩所占权重，且权重总和须为100%）</p>
            </el-form-item>
            <el-form-item prop="stageNum" label="阶段设置">
              <div v-for="(item, i) in form.competitionStageList" :key="i" class="step-set">
                <div class="line">
                  第{{ serials[i] }}阶段 <el-input v-model="item.stageName" clearable placeholder="请输入阶段名称，如“初赛”"
                    style="width: 200px"></el-input>
                </div>
                <div class="line">
                  <span class="req">*</span>
                  比赛方式：
                  <el-radio v-for="(method, i) in methods" :key="i" v-model="item.method" :label="method.id">{{
                    method.name }}</el-radio>
                </div>
                <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
                  <span class="req">*</span>
                  团队参赛人数限制：
                  <el-radio v-model="item.teamNumLimit" :label="0">不限制</el-radio>
                  <el-radio v-model="item.teamNumLimit" :label="1">自定义</el-radio>
                  <el-input v-model.number="item.customNumber" type="number" min="0" style="width: 150px;"
                    :disabled="item.teamNumLimit === 0"></el-input> 人
                  <span class="tips">（可限制本阶段单个团队的出战人数）</span>
                </div>
                <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
                  <span class="req">*</span>
                  团队成绩计算方式：
                  <el-radio v-for="(j, i) in teamCalculationMethods" :key="i" v-model="item.teamCalculationMethod"
                    :label="j.id">{{ j.name }}</el-radio>
                  <span class="tips">（可设置本阶段的团队取分规则）</span>
                </div>
                <div v-if="form.rule === 1 && i !== form.competitionStageList.length - 1" class="line"
                  style="display: flex;">
                  <p>
                    <span class="req">*</span>晋级规则：
                  </p>
                  <div>
                    <div class="line">
                      本阶段成绩排名前
                      <el-input v-model.number="item.peopleLimit" type="number" min="0" style="width: 100px"></el-input>
                      队，可晋级下一阶段比赛
                    </div>
                    <div class="line">
                      本阶段成绩排名前
                      <el-input v-model.number="item.percentageLimit" type="number" min="0"
                        style="width: 100px"></el-input>
                      %，可晋级下一阶段比赛
                    </div>
                    <div>
                      本阶段成绩
                      <el-select v-model="item.operator" style="width: 80px;margin-right: 10px">
                        <el-option v-for="i in operators" :key="i" :label="i" :value="i"></el-option>
                      </el-select>
                      <el-input v-model="item.score" type="number" min="0" style="width: 100px"></el-input>
                      分，可晋级下一阶段比赛
                    </div>
                  </div>
                </div>
                <div v-if="!form.rule" class="line">
                  <span class="req">*</span>
                  占总成绩权重：
                  <el-input v-model.number="item.pointWeight" type="number" min="0"
                    :disabled="form.resultCalculationMethod != 0" style="width: 150px;"></el-input> %
                </div>
                <div class="line">
                  成绩公布时间：
                  （阶段）比赛结束后
                  <el-input v-model.number="item.resultAnnouncementTime" type="number" min="0"
                    style="width: 120px"></el-input>
                  小时，公布（阶段）比赛成绩。（为空则不公布成绩，为0则阶段比赛结束后立马公布成绩）
                </div>
                <div
                  v-if="item.resultAnnouncementTime !== '' && item.resultAnnouncementTime !== null && item.resultAnnouncementTime !== undefined"
                  class="line">
                  是否公布成绩详情：
                  <el-radio v-model="item.resultsDetails" :label="0">是</el-radio>
                  <el-radio v-model="item.resultsDetails" :label="1">否</el-radio>
                  <p class="tips">若选择“是”，则公布成绩详情，竞赛结束后参赛者可查看自己的比赛成绩得分详情；</p>
                  <p class="tips">若选择“否”，则不公布成绩详情，参赛者只能知晓自己的分数及排名，不能查看得分详情。</p>
                </div>
              </div>
            </el-form-item>
          </template>
          <template v-else>
            <el-form-item prop="stageNum" label="规则设置">
              <div class="step-set">
                <div class="line">
                  <span class="req">*</span>
                  比赛方式：
                  <el-radio v-for="(method, i) in methods" :key="i" v-model="form.competitionStageList[0].method"
                    :label="method.id">{{ method.name }}</el-radio>
                </div>
                <div v-if="step1.completeCompetitionSetup.competitionType" class="line">
                  <span class="req">*</span>
                  团队成绩计算方式：
                  <el-radio v-for="(j, i) in teamCalculationMethods" :key="i"
                    v-model="form.competitionStageList[0].teamCalculationMethod" :label="j.id">{{ j.name }}</el-radio>
                  <span class="tips">（可设置本阶段的团队取分规则）</span>
                </div>
              </div>
            </el-form-item>
            <el-form-item label="成绩公布时间">
              （阶段）比赛结束后
              <el-input v-model.number="form.competitionStageList[0].resultAnnouncementTime" type="number" min="0"
                style="width: 120px"></el-input>
              小时，公布（阶段）比赛成绩。（为空则不公布成绩，为0则阶段比赛结束后立马公布成绩）
            </el-form-item>
            <el-form-item
              v-if="form.competitionStageList[0].resultAnnouncementTime !== '' && form.competitionStageList[0].resultAnnouncementTime !== null && form.competitionStageList[0].resultAnnouncementTime !== undefined"
              prop="resultsDetails" label="是否公布成绩详情">
              <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="0">是</el-radio>
              <el-radio v-model="form.competitionStageList[0].resultsDetails" :label="1">否</el-radio>
              <p class="tips">若选择“是”，则公布成绩详情，竞赛结束后参赛者可查看自己的比赛成绩得分详情；</p>
              <p class="tips">若选择“否”，则不公布成绩详情，参赛者只能知晓自己的分数及排名，不能查看得分详情。</p>
            </el-form-item>
          </template>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
import util from "@/libs/util";
import Const from '@/const/match'
import _ from 'lodash'
export default {
  props: ['setupId', 'editing'],
  data () {
    return {
      id: this.$route.query.id,
      updateTime: 0,
      step1: this.$parent.$refs.step1.form,
      serials: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'],
      form: {
        resultCalculationMethod: 0,
        rule: 0,
        stageNum: 3,
        teamLimit: 1,
        competitionStageList: [
          {
            method: 0,
            number: 1,
            pointWeight: '',
            stageName: '',
            teamCalculationMethod: 0,
            peopleLimit: '',
            percentageLimit: '',
            scoreLimit: '',
            operator: '>',
            score: '',
            customNumber: '',
            teamNumLimit: 0,
            resultAnnouncementTime: '',
            resultsDetails: '',
          },
          {
            method: 0,
            number: 2,
            pointWeight: '',
            stageName: '',
            teamCalculationMethod: 0,
            peopleLimit: '',
            percentageLimit: '',
            scoreLimit: '',
            operator: '>',
            score: '',
            customNumber: '',
            teamNumLimit: 0,
            resultAnnouncementTime: '',
            resultsDetails: '',
          },
          {
            method: 0,
            number: 3,
            pointWeight: '',
            stageName: '',
            teamCalculationMethod: 0,
            peopleLimit: '',
            percentageLimit: '',
            scoreLimit: '',
            operator: '>',
            score: '',
            customNumber: '',
            teamNumLimit: 0,
            resultAnnouncementTime: '',
            resultsDetails: '',
          }
        ]
      },
      validRules: {
        rule: [
          { required: true, trigger: 'change' }
        ],
        stageNum: [
          { required: true, trigger: 'change' }
        ],
        resultCalculationMethod: [
          { required: true, trigger: 'change' }
        ],
        resultAnnouncementTime: [
          { required: true, message: '请输入成绩公布时间', trigger: 'change' }
        ],
        resultsDetails: [
          { required: true, trigger: 'change' }
        ],
      },
      originForm: null,
      ruleForm: {},
      rules: Const.rules,
      methods: Const.methods,
      teamCalculationMethods: Const.teamCalculationMethods,
      operators: ['>', '>=', '=', '<', '<=']
    };
  },
  watch: {
    // 监听信息是否有更改,有的话页面离开的时候要询问是否要保存
    form: {
      handler () {
        this.updateTime++
      },
      deep: true
    },
  },
  mounted () {
    this.ruleForm = JSON.parse(JSON.stringify(this.form.competitionStageList[0]))
    this.id && this.getData()
    this.step1 || this.getStep1() // 如果没有第一步的数据，则直接接口获取
  },
  methods: {
    getData () {
      this.$get(this.api.getCompetitionRule, {
        competitionId: this.id
      }).then(res => {
        const rule = res.competitionRule
        if (rule) {
          rule.competitionStageList.map(e => {
            const limit = e.scoreLimit
            if (limit) {
              e.operator = limit.replace(/\d+/, '')
              const num = limit.replace(/\D+/, '')
              if (num) e.score = num
            }
            e.teamCalculationMethod = +e.teamCalculationMethod
          })
          this.originForm = _.cloneDeep(rule)
          this.form = rule
        }
        this.$nextTick(() => {
          this.updateTime = 0
        })
      }).catch(res => { })
    },
    // 获取第二部的数据
    getStep1 () {
      this.$post(`${this.api.getCompetition}?competitionId=${this.id}`).then(({ competition }) => {
        this.step1 = competition
        const { minTeamSize, maxTeamSize, competitionType } = this.step1.completeCompetitionSetup
        competitionType && minTeamSize !== '' && maxTeamSize !== '' && minTeamSize == maxTeamSize && this.teamCalculationMethods.pop() // 团队上下限人数相等，则不显示求和
      }).catch(err => { })
    },
    // 阶段数量选择回调
    stageChange (val) {
      const stages = this.form.competitionStageList
      const { ruleId } = this.form
      if (stages.length < val) {
        const len = stages.length
        for (let i = 1; i <= val - len; i++) {
          const form = JSON.parse(JSON.stringify(this.ruleForm))
          form.number = len + i
          if (ruleId) form.ruleId = ruleId
          this.form.competitionStageList.push(form)
        }
      } else {
        this.form.competitionStageList = stages.slice(0, val)
      }
    },
    // 保存自动分配人员条件
    async automaticAllocation (next) {
      // 团队赛
      if (this.step1.completeCompetitionSetup.competitionType) {
        const { form, originForm } = this

        // 赛制、阶段数量、是否限制成员只参加一个阶段、参赛人数限制。这些字段有改一个，则调接口查询其他3个条件；一共4个条件都满足后，才需要弹框；否则直接进入下一步
        let changeLimit = 0
        for (const i in form.competitionStageList) {
          const e = form.competitionStageList[i]
          if (e.teamNumLimit !== originForm.competitionStageList[i].teamNumLimit || e.customNumber !== originForm.competitionStageList[i].customNumber) {
            changeLimit = 1
            break
          }
        }
        if (form.rule !== originForm.rule || form.stageNum !== originForm.stageNum || form.teamLimit !== originForm.teamLimit || changeLimit) {
          await this.$post(this.api.updateEventAllocationRecord, {
            competitionId: +this.id,
            whetherToModifyTheRule: 1,
          })
          this.$emit('next', next)
        } else {
          this.$emit('next', next)
        }
      } else {
        this.$emit('next', next)
      }
    },
    // 提交
    save (status, next = 0, releaseType, cb) {
      const form = _.cloneDeep(this.form)
      const { rule } = form
      let invalid = 0
      let pointWeight = 0
      const { step1 } = this
      // 下一步需要校验
      if (next === 2) {
        const stages = form.competitionStageList
        if (form.rule === 2) { // 单项赛只需要输入成绩公布时间
          const e = stages[0]
          e.stageName = step1.name
          if (e.resultsDetails === 0 && e.resultAnnouncementTime !== '') {
            if (e.resultAnnouncementTime < 0) {
              return util.errorMsg('成绩公布时间不得小于0')
            }
            if (e.resultAnnouncementTime % 1) {
              return util.errorMsg('成绩公布时间须为整数')
            }
            e.resultAnnouncementTime = +e.resultAnnouncementTime
          }
          form.competitionStageList = stages.slice(0, 1) // 单项赛只需要存第一个阶段的数据
        } else { // 非积分赛则全部字段校验
          let customNumber = 0
          const { competitionType, minTeamSize, maxTeamSize } = step1.completeCompetitionSetup // 0为个人赛，1为团队赛
          for (const i in stages) {
            const e = stages[i]
            if (rule !== 2 && !e.stageName) {
              invalid = 1
              util.errorMsg('请输入阶段名称')
              break
            }
            // rule: 0为积分赛，1为淘汰赛，2为单项赛
            // 积分赛
            if (!rule) {
              // 个人
              if (form.resultCalculationMethod == 0 && (e.pointWeight === '' || e.pointWeight === undefined)) {
                invalid = 1
                util.errorMsg('请输入权重')
                break
              }
              pointWeight += e.pointWeight // 权重求和
            } else if (rule === 1) { // 淘汰赛
              // 晋级规则必须至少填一个(最后一个阶段不用填写)
              if (i != stages.length - 1 && e.peopleLimit === '' && e.percentageLimit === '' && e.score === '') {
                invalid = 1
                util.errorMsg('请至少填写一条晋级规则')
                break
              }
              if (e.score !== '') e.scoreLimit = e.operator + e.score
            }
            if (rule !== 2 && competitionType && e.teamNumLimit) {
              if (e.customNumber === '' || e.customNumber === undefined) {
                invalid = 1
                util.errorMsg('请输入团队参数人数限制')
                break
              } else if (e.customNumber < 0) {
                invalid = 1
                util.errorMsg('团队参数人数不得小于0')
                break
              } else if (maxTeamSize !== '' && e.customNumber > maxTeamSize) {
                invalid = 1
                util.errorMsg('团队参数人数不得大于团队人数上限')
                break
              }
            }
            if (e.resultsDetails === 0 && (e.resultAnnouncementTime !== '' && e.resultAnnouncementTime !== undefined)) {
              if (e.resultAnnouncementTime < 0) {
                invalid = 1
                util.errorMsg('成绩公布时间不得小于0')
                break
              }
              if (e.resultAnnouncementTime % 1) {
                invalid = 1
                util.errorMsg('成绩公布时间须为整数')
                break
              }
              e.resultAnnouncementTime = +e.resultAnnouncementTime
            }
            if (e.teamNumLimit && e.customNumber) customNumber += e.customNumber // 各阶段自定义的人数之和
            if (!e.teamNumLimit) e.customNumber = ''
          }
          if (invalid) return
          if (form.teamLimit && competitionType) {
            if (stages.length > minTeamSize) return util.errorMsg('阶段数不得大于团队人数下限')
            if (customNumber > minTeamSize) return util.errorMsg('各阶段自定义的参赛人数之和不得大于团队人数下限')
          }
          if (form.resultCalculationMethod == 0 && !rule && pointWeight > 0 && pointWeight !== 100) return util.errorMsg('权重须等于100，请重新输入')
        }
      } else { // 保存草稿的情况下，只保存输入了阶段名称的阶段
        form.competitionStageList = form.competitionStageList.filter(e => e.stageName)
      }
      this.$parent.showLoad()
      this.pass = 1
      if (form.ruleId) {
        this.$post(this.api.editCompetitionRule, form).then(res => {
          this.$parent.hideLoad()
          this.updateTime && util.successMsg("修改成功");
          this.updateTime = 0
          this.automaticAllocation(next)
        }).catch(err => {
          this.$parent.hideLoad()
        })
      } else {
        form.setupId = this.setupId
        this.$post(this.api.addCompetitionRule, form).then(res => {
          this.$parent.hideLoad()
          util.successMsg("创建成功");
          this.$emit('next', next, cb)
        }).catch(err => {
          this.$parent.hideLoad()
        })
      }
    },
  }
};
</script>

<style scoped lang="scss">
/deep/ .d-inline-block {
  width: 216px;

  .el-select,
  .el-input {
    width: 100%;
  }
}

.inline-input {
  .input-wrap {
    display: flex;
    align-items: center;
    margin-bottom: 10px;

    .el-input {
      display: inline-block;
      width: 216px;
      margin-right: 8px;
    }

    .remove {
      width: 16px;
      height: 16px;
      background: url('../../../assets/img/close.png') 0 0 / cover no-repeat;
      cursor: pointer;
    }
  }

  .add-btn {
    margin-left: 32px;
  }
}

.input-center {
  display: flex;
  align-items: center;
  width: 216px;
  white-space: nowrap;

  .el-input {
    margin-right: 5px;
  }
}

.step-set {
  padding: 15px;
  background-color: #fbfbfb;
}

.tips {
  font-size: 13px;
  color: #959595;
}

.req {
  color: #f00;
}

.line {
  margin-bottom: 10px;
}
</style>