<template>
  <div class="comp-car-card iccid-change">
    <el-form ref="formRef" :model="form" :rules="formRules" size="small" label-position="top" @submit.native.prevent>
      <el-row>
        <el-col :span="24">
          <el-form-item label="车辆VIN码" prop="vin">
            <div class="el-input-wrapper">
              <el-input
                :value="form.vin"
                clearable
                maxlength="17"
                placeholder="请输入您的VIN码"
                class="ccc-vin-input"
                @input="onVinInput"
                @focus="onVinFocus"
                @blur="onVinBlur"
              />
              <!-- <el-button v-if="isInApp" class="ccc-add-vin-btn" type="primary" icon="el-icon-camera" plain size="small" @click.stop="handleTakeScan">扫码添加</el-button> -->
            </div>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <div class="add-iccid-btn-wrapper">
            <el-form-item label="ICCID列表" prop="iccidList">
              <el-button :disabled="!enableAddBtn" type="primary" icon="el-icon-plus" plain size="small" @click.stop="clickAddIccid">添加ICCID卡</el-button>
            </el-form-item>
          </div>
          <div class="iccid-table-wrapper">
            <el-table
              v-loading="loading"
              ref="multipleTable"
              :data="iccidList"
              @selection-change="handleSelectionChange">
              <el-table-column type="selection" width="40"/>
              <el-table-column type="index" label="全选" width="100"/>
              <el-table-column
                prop="iccid"
                label="原件ICCID"
                min-width="320"
              >
                <template slot-scope="scope">
                  <template v-if="scope.row.state === 'readonly'">{{ scope.row.iccid }}</template>
                  <template v-else-if="scope.row.state === 'edit'">
                    <el-form :ref="scope.row._formId" :model="scope.row" :rules="iccidRules" size="small" label-width="0" @submit.native.prevent>
                      <el-form-item prop="iccid" class="ccc-el-form-item">
                        <el-input :ref="scope.row._inputId" :value="scope.row.iccid" clearable maxlength="50" class="ccc-iccid-el-input" @input="onIccidInput($event, scope.row)"/>
                      </el-form-item>
                    </el-form>
                  </template>
                </template>
              </el-table-column>
              <el-table-column
                label="新件ICCID"
                prop="newIccid"
                width="320">
                <template slot-scope="scope">
                  <el-input v-if="scope.row.checked" v-model.trim="scope.row.newiccid" clearable maxlength="20" />
                  <div v-else>{{ scope.row.newiccid }}</div>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="120">
                <template slot-scope="scope">
                  <el-link v-if="canDelIccidRecord(scope)" class="ccc-el-link-del" @click.stop="clickIccidItemDel(scope)">删除</el-link>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-col>
      </el-row>
    </el-form>
    <comp-confirm
      :show.sync="showDelConfirm"
      :desc="delConfirmDesc"
      :show-cancel-btn="true"
      @on-sure="onDelSure"
    />
    <comp-confirm
      :show.sync="showTipConfirm"
      :desc="tipConfirmDesc"
    />
  </div>
</template>

<script>
import bridge, { isInApp } from '@/utils/bridge'
import { CancelToken } from 'axios'
import { queryBindCardByVin } from '@/api/iccid'
import CompConfirm from '@/components/CompConfirm'

let gid = 0

export default {
  name: 'IccidChange',
  components: {
    CompConfirm
  },
  props: {
    data: {
      type: Object,
      default: () => ({})
    },
    maxIccidLength: {
      type: Number,
      default: 5
    }
  },
  data() {
    const checkVin = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请输入您的vin码'))
      } else if (!this.checkVin(value)) {
        callback(new Error('vin码格式不正确'))
      } else {
        callback()
      }
    }
    const checkIccid = (rule, value, callback) => {
      if (value !== '') {
        if (this.checkIccid(value)) {
          callback()
        } else {
          callback(new Error('iccid格式不正确'))
        }
      } else {
        if (this.validIccidList.length) {
          callback()
        } else {
          callback(new Error('请输入iccid'))
        }
      }
    }
    return {
      form: {
        vin: '',
        iccidList: []
      },
      formRules: {
        vin: [
          { required: true, validator: checkVin, trigger: 'blur' }
        ],
        iccidList: [
          { type: 'array', required: true, message: '请添加ICCID数据', trigger: '' }
        ]
      },
      iccidRules: {
        iccid: [
          { required: true, validator: checkIccid, trigger: 'blur' }
        ]
      },
      isInApp,
      iccidList: [],
      selectedList: [],
      loading: false,
      showDelConfirm: false,
      delConfirmDesc: '确认删除当前行吗？',
      showTipConfirm: false,
      tipConfirmDesc: '',
      inputIsFocus: false
    }
  },
  computed: {
    newAddedIccidList() {
      return this.iccidList.filter(item => item.state === 'edit')
    },
    validIccidList() {
      return this.iccidList.filter(item => (item.state === 'edit' ? this.checkIccid(item.iccid) : (item.iccid !== '')))
    },
    enableAddBtn() {
      const ret = (!this.inputIsFocus && !this.loading) || (this.inputIsFocus && !this.form.vin)
      this.$emit('on-canenable', ret)
      return ret
    }
  },
  watch: {
    data() {
      this.updateInternalData()
    },
    iccidList(val) {
      if (this._iccidListInitMount) {
        this._iccidListInitMount = false
        return
      }
      if (val.length) {
        this.$refs.formRef.clearValidate('iccidList')
      } else {
        this.$refs.formRef.validateField('iccidList')
      }
    }
  },
  created() {
    this._iccidListInitMount = true
    this.init()
  },
  methods: {
    errorTips(errMsg) {
      this.showTipConfirm = true
      this.tipConfirmDesc = errMsg
    },

    init() {
      this.updateInternalData()
    },
    updateInternalData() {
      if (typeof this.data === 'object' && this.data !== null) {
        this.form.vin = this.data.vin || ''
        this.form.iccidList = []
        this.iccidList = Array.isArray(this.data.iccidList) ? [...this.data.iccidList] : this.getDefaultIccidList()
        // 筛选出选中的行
        this.selectedList = []
        this.iccidList.forEach(item => {
          if (item.checked) {
            this.selectedList.push(item)
            this.$nextTick(() => {
              this.$refs.multipleTable.toggleRowSelection(item, true)
            })
          }
        })
      }
    },
    getDefaultIccidList() {
      return []
    },

    // 点击添加 ICCID 按钮
    clickAddIccid() {
      if (this.iccidList.length >= this.maxIccidLength) {
        this.errorTips(`最多只能添加${this.maxIccidLength}条ICCID数据`)
        return
      }
      const newIccid = this.makeIccidTemplate()
      newIccid.state = 'edit'
      newIccid.checked = false
      newIccid.newiccid = ''
      this.iccidList.push(newIccid)
      this.$nextTick(() => {
        this.$refs[`${newIccid._inputId}`].focus()
      })
    },
    // 点击删除 ICCID 记录按钮
    clickIccidItemDel(scope) {
      this.showDelConfirm = true
      this._curDelIndex = scope.$index
    },
    // 确认删除 ICCID
    onDelSure() {
      this.iccidList.splice(this._curDelIndex, 1)
    },
    onIccidInput($event, cur) {
      if ($event === '' || $event.length <= 20) {
        cur.iccid = $event
      }
    },
    canDelIccidRecord(scope) {
      if (scope.row.state === 'readonly') {
        return false
      } else {
        return true
      }
    },

    onVinFocus() {
      this.inputIsFocus = true
    },
    // 光标移开 vin 码输入框时的动作
    onVinBlur() {
      this.inputIsFocus = false
      this.$refs.formRef.validateField('vin', errorMsg => {
        if (!errorMsg) {
          this.onVinBlurHandler()
        } else {
          if (this._req) {
            this._req.cancel()
          }
        }
      })
    },
    // 光标移开 vin 码输入框处理
    async onVinBlurHandler() {
      if (this.form.vin.length < 17) {
        return false
      }
      this.loading = true
      const retData = await this.getIccidListByVin()
      this.loading = false
      if (retData === 'cancel') {
        return
      }
      console.log('=== onVinBlurHandler =>', retData)
      const tempIccidList = this.iccidList.map(item => item.iccid)
      const pendingAdd = (retData.iccidList || []).filter(item => tempIccidList.indexOf(item) === -1)
      const addCount = this.maxIccidLength - this.iccidList.length
      if (this._preVin === this.form.vin) {
        this.iccidList = [
          ...this.iccidList,
          ...this.normalizeIccidList(pendingAdd.slice(0, addCount))
        ]
      } else {
        this.iccidList = [
          ...this.iccidList.filter(item => item.state !== 'readonly'),
          ...this.normalizeIccidList(pendingAdd.slice(0, addCount))
        ]
      }
      this._preVin = this.form.vin
    },
    // vin 码输入长度限制
    onVinInput($event) {
      if ($event === '' || $event.length <= 17) {
        this.form.vin = $event
      }
    },

    checkVin(vin) {
      return vin.length === 17
    },
    checkIccid(iccid) {
      return typeof iccid === 'string' && iccid !== '' && iccid.length === 20
    },

    async getIccidListByVin() {
      if (this._req) {
        this._req.cancel()
      }
      this._req = CancelToken.source()

      let retData = null
      const searchParams = {
        vin: this.form.vin
      }
      try {
        const respData = await queryBindCardByVin({
          data: {
            ...searchParams
          },
          cancelToken: this._req.token,
          hideToast: true
        })
        retData = respData || {}
      } catch (e) {
        if (e.code === '_CANCEL_REQUEST_') {
          retData = 'cancel'
        }
      }
      return retData || {}
    },

    // ICCID 记录数据模板
    makeIccidTemplate() {
      return {
        iccid: '',
        state: 'readonly',
        _formId: gid++,
        _inputId: gid++,
        checked: false,
        newiccid: ''
      }
    },
    // 标准化远程获取的 ICCID 记录数据
    normalizeIccidList(list = []) {
      return list.map(item => {
        const newIccid = this.makeIccidTemplate()
        newIccid.iccid = item
        newIccid.state = 'readonly'
        newIccid.checked = false
        newIccid.newiccid = ''
        return newIccid
      })
    },

    async validateForm1(isErrorAnchor = false) {
      this.form.iccidList = JSON.parse(JSON.stringify(this.iccidList))
      try {
        await this.$refs.formRef.validate()
        return true
      } catch (e) {
        if (isErrorAnchor) {
          this.$refs.formRef.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
        }
        let temp = {
          anchor: () => {
            this.$refs.formRef.fields.filter(item => item.validateState === 'error')[0].$el.scrollIntoView(true)
            temp = null
          }
        }
        throw temp
      }
    },
    async validateIccidListForm2(isErrorAnchor = false) {
      const validateIccidList = this.newAddedIccidList
      for (let i = 0, len = validateIccidList.length; i < len; i++) {
        const item = validateIccidList[i]
        try {
          await this.$refs[item._formId].validate()
        } catch (e) {
          if (isErrorAnchor) {
            this.$refs[item._inputId].$el.scrollIntoView(true)
          }
          let temp = {
            anchor: () => {
              this.$refs[item._inputId].$el.scrollIntoView(true)
              temp = null
            }
          }
          throw temp
        }
      }
      return true
    },

    // 校验
    async validate(isErrorAnchor = false) {
      try {
        await Promise.all([
          this.validateForm1(),
          this.validateIccidListForm2()
        ])
        return true
      } catch (e) {
        throw e
      }
    },
    // 获取数据
    getFormData() {
      return {
        vin: this.form.vin,
        iccidList: this.iccidList.map(item => item.iccid)
      }
    },
    // 获取待缓存数据
    getPendingCacheData() {
      return {
        vin: this.form.vin,
        iccidList: JSON.parse(JSON.stringify(this.iccidList))
      }
    },

    /**
    * 表格多选方法
    * @param  {Array} val 选中的行组成的数组
    * @time 2021-10-19 09:49:46
    */
    handleSelectionChange(val) {
      this.iccidList.forEach(ele => {
        ele.checked = false
      })
      val.forEach(ele => {
        ele.checked = true
      })
      this.selectedList = val
    },

    /**
     * 扫码功能
     */
    handleTakeScan() {
      bridge.scanCode(true, code => {
        this.form.vin = code
        this.onVinBlur()
      })
    }
  }
}
</script>

<style lang="scss">
.comp-car-card {
  .ccc-vin-input {
    width: 44%;
  }
  .ccc-iccid-el-input {
    width: 60%;
  }
  .ccc-el-form-item {
    .el-form-item__error {
      left: 62%;
      top: 50%;
      transform: translateY(-50%);
    }
  }
  .add-iccid-btn-wrapper {
    margin-bottom: 8px;
  }
  .iccid-table-wrapper {
    .el-form-item {
      margin-bottom: 0 !important;
    }
    .ccc-el-link-del {
      font-size: 14px;
      color: #2A68FF;
      &:hover {
        &:after {
          display: none;
        }
      }
    }
  }
  .el-input-wrapper {
    display: flex;
    .ccc-add-vin-btn {
      margin-left: 12px;
    }
  }
}
.iccid-change{
  .has-gutter{
    .cell{
      margin-left: 10px;
    }
  }
}
</style>
