<template>
  <el-dialog
    center
    width="1024px"
    title="导入采销订单补录"
    :visible="innerVisible"
    :close-on-click-modal="false"
    @close="() => innerVisible = false"
  >
    <div v-if="tableData && tableData.length > 0" class="tr" style="padding: 10px 0 0 0">
      <el-button :size="'mini'" @click="() => tableData = []">取消</el-button>
      <el-button type="primary" :size="'mini'" @click="onSubmit">提交</el-button>
    </div>
    <div v-else>
      <upload-excel :on-success="onSuccess" :before-upload="beforeUpload" />
    </div>

    <ex-table
      :columns="columns"
      :table="table"
      :data="tableData"
      style="margin: 15px 0 0 0"
    />
  </el-dialog>
</template>

<script>
import asyncRequest from '@/apis/service/netOrderEntry/netOrderEnter'
import { isMobile, isPhone, isnumber } from '@/utils/validate'
import companyHelper from '@/mixins/companyHelper'
import { MessageBox } from 'element-ui'
import dayjs from 'dayjs'

import {
  helper,
  columns,
  PROPERTYS,
  getTableProperty,
  createErrorMessage,
  createFieldVerification,
  requsetFields,
  requiredFields,
  numberFields
} from './template'

export default {
  mixins: [companyHelper],
  props: ['visible'],
  data() {
    return {
      columns,
      loading: false,
      tableData: [],
      table: {
        stripe: true,
        border: true,
        'max-height': '800px'
      }
    }
  },
  computed: {
    innerVisible: {
      get() {
        return this.visible
      },
      set(newVal) {
        this.$emit('update:visible', newVal)
      }
    }
  },
  methods: {
    validateTableHeader(header, importHeader) {
      let isHeaderOk = true
      if (header.length !== importHeader.length) return false
      for (const index in header) {
        const field = header[index]
        const importField = importHeader[index]
        if (field !== importField) {
          console.log(field, importField)
          isHeaderOk = false
          break
        }
      }

      return isHeaderOk
    },
    /* 校验导入的销售方列表编码(与选择的公司必须一致) **/
    validateCompanyNo(companys = []) {
      const verification = createFieldVerification('销售方公司不能为空且必须与选择的公司一致')
      const current = this.currentCompany
      companys.forEach((companyNo, index) => {
        if (companyNo !== current || !companyNo) {
          verification.isValid = false
          verification.notValidRows.push(index + 1)
        }
      })
      return verification
    },
    /* 校验导入的购买方列表编码(开头必须为KH) **/
    validateKhNo(customers = []) {
      const verification = createFieldVerification("购买方公司编码不能为空且必须以'KH'开头")
      customers.forEach((customerNo, index) => {
        const perfix = String(customerNo || '').slice(0, 2)
        if (perfix !== 'KH' || !customerNo) {
          verification.isValid = false
          verification.notValidRows.push(index + 1)
        }
      })
      return verification
    },
    /* 校验导入的联系电话是否合法 **/
    validateMobile(mobiles = []) {
      const verification = createFieldVerification('联系电话不能为空且必须为手机号或电话号码')
      mobiles.forEach((mobile, index) => {
        if (!mobile || isMobile(mobile) && isPhone(mobile)) {
          verification.isValid = false
          verification.notValidRows.push(index + 1)
        }
      })
      return verification
    },
    /* 校验导入的购买方列表编码(开头必须为QS) **/
    validateSupplierNo(suppliers = []) {
      const verification = createFieldVerification("供应商公司编码不能为空且必须以'QS'开头")
      suppliers.forEach((supplierNo, index) => {
        const perfix = String(supplierNo || '').slice(0, 2)
        if (perfix !== 'QS' || !supplierNo) {
          verification.isValid = false
          verification.notValidRows.push(index + 1)
        }
      })
      return verification
    },
    /* 校验导入的税率、数量、采购单价、销售单价是否为数字 **/
    validateNumberField(numberFields) {
      const verification = createFieldVerification('税率、数量、销售单价、采购单价不能为空且必须是数字')
      const fields = helper.fields(numberFields)
      numberFields[fields[0]].forEach((_, index) => {
        const values = helper.values(numberFields, fields, index)
        const valuesIsNumber = values.every(value => {
          return isnumber(value)
        })
        console.log(valuesIsNumber)
        if (!valuesIsNumber) {
          verification.isValid = false
          verification.notValidRows.push(index + 1)
        }
      })
      return verification
    },
    /* 所属平台、商品分类、商品名称、单位、收货人、收货地址、PO编号不能为空 **/
    validateRequiredField(requiredFields) {
      const verification = createFieldVerification('所属平台、商品分类、商品名称、单位、收货人、收货地址、PO编号不能为空')
      const fields = helper.fields(requiredFields)
      requiredFields[fields[0]].forEach((_, index) => {
        if (!helper.values(requiredFields, fields, index).every(value => value && String(value).trim() !== '')) {
          verification.isValid = false
          verification.notValidRows.push(index + 1)
        }
      })
      return verification
    },
    /* 处理不合法的值,提示错误信息,并返回最终的验证状态 **/
    handleNotValidFields(...validStates) {
      const messages = {}
      let isFinalValid = true

      for (const validState of validStates) {
        const { message, isValid, notValidRows } = validState
        if (isValid) continue
        isFinalValid = false

        notValidRows.forEach(row => {
          if (!messages[row]) messages[row] = []
          messages[row].push(message)
        })
      }

      return {
        isFinalValid,
        message: () => !isFinalValid && MessageBox({
          type: 'warning',
          title: '数据填写错误',
          dangerouslyUseHTMLString: true,
          message: createErrorMessage(messages),
          customClass: 'error-message__wrapper'
        })
      }
    },
    /* 校验导入的数据 **/
    validateFields(tableData = []) {
      const mapTableFieldToTableData = {}
      for (const tableItem of tableData) {
        const propertys = Object.keys(tableItem)
        for (const property of propertys) {
          const value = tableItem[property]
          if (!mapTableFieldToTableData[property]) mapTableFieldToTableData[property] = []
          mapTableFieldToTableData[property].push(value)
        }
      }

      return this.handleNotValidFields(
        this.validateMobile(mapTableFieldToTableData[PROPERTYS.MOBILE]),
        this.validateKhNo(mapTableFieldToTableData[PROPERTYS.CUSTOMER_NO]),
        this.validateCompanyNo(mapTableFieldToTableData[PROPERTYS.COMPANY_NO]),
        this.validateSupplierNo(mapTableFieldToTableData[PROPERTYS.SUPPLIER_NO]),
        this.validateNumberField(helper.write(mapTableFieldToTableData, numberFields)),
        this.validateRequiredField(helper.write(mapTableFieldToTableData, requiredFields))
      )
    },
    mapTemplateItemToTableItem(templateItem) {
      const tableItem = {}
      const templatePropertys = Object.keys(templateItem)
      templatePropertys.forEach(templateProperty => {
        const tableproperty = getTableProperty(templateProperty)
        tableItem[tableproperty] = templateItem[templateProperty]
      })
      return tableItem
    },
    onSuccess({ results: templateItems, header: templateHeader }) {
      const isHeaderValid = this.validateTableHeader(
        this.columns.map(({ label }) => label).slice(1),
        templateHeader
      )
      if (!isHeaderValid) {
        this.$message.warning('表格与导入的表头不一致!')
        return
      }
      if (templateItems.length === 0) {
        this.$message.warning('导入的表格没有数据!')
        return
      }
      templateItems.forEach(templateItem => {
        const tableItem = this.mapTemplateItemToTableItem(templateItem)
        this.tableData.push(tableItem)
      })
      this.validateFields(this.tableData).message()
    },
    async onSubmit() {
      const { message, isFinalValid } = this.validateFields(this.tableData)
      if (!isFinalValid) return message()

      const list = this.tableData.map(tableItem => requsetFields.reduce((prev, currentKey) => ({
        ...prev,
        [currentKey]: currentKey === PROPERTYS.SEND_TIME ? dayjs(tableItem[currentKey] * 1000).format('YYYY-MM-DD HH:mm:ss') : tableItem[currentKey]
      }), {}))

      this.loading = true
      const result = await asyncRequest.importOrder({
        list
      })
      this.loading = false

      switch (String(result.code)) {
        case '0':
          this.$message.success('导入成功')
          this.innerVisible = false
          this.$emit('refresh')
          break
        default:
          this.$message.warning(result.message)
          break
      }
    }
  }
}
</script>

<style lang="scss">
.error-message__wrapper{
  width: 1024px;
}
</style>
