<template>
  <el-dialog :title="`上传${mapTitle[type]}`" :close-on-click-modal="false" :visible="innerVisible" width="1024px" @close="handleClose" center>


   <div style="display:flex;">
    <div style="display:flex;align-items:center;margin-right:10px" v-if="type === 'budget' || type === 'project'">
      <p style="margin-right:10px"> 
      <span style="color:red"> * </span>店铺:</p>
      <search-store size="mini" :value.sync="storeId" :openOptionDisbaled="true" />
    </div>

    <div style="display:flex;align-items:center" v-if="type === 'activity'">
      <p style="margin-right:10px"><span style="color:red"> * </span>{{mapTitle[type]}}文件:</p>
      <div v-if="file_url && isFile">
        <el-tooltip content="点击下载" placement="top">
          <a style="color:#409EFF" :href="file_url">{{file_name}}</a>
        </el-tooltip>
        <el-link
          :underline="false"
          @click="deleteUrl"
          type="warning"
          style="margin: 0 0 0 16px"
          >删除</el-link
        >
      </div>

      <div class="activity-upload" v-if="!file_url && isFile" style="margin:0">
      <div class="btnupload" style="position: relative">
        <i class="el-icon-plus avatar-uploader-icon"></i>
        <file-upload-pdf
          class="Upload"
          :accept="'.xlsx,.xls,.pdf,.zip,.rar,.7z'"
          :multiple="false"
          :uploadcondition="beforeOtherUpload"
          @UploadErrorEvent="UploadErrorOtherproof_url"
          @UploadSuccessEvent="UploadSuccessOtherproof_url"
        />
      </div>
      <div class="txt-tips fl">
        <p>建议大小：小于5MB</p>
        <p>文件格式：.xlsx,.xls,.pdf,.zip,.rar,.7z</p>
      </div>
    </div>
    </div>
   </div>
         

    <div style="padding:10px" v-loading="loading"  v-if="type !== 'activity'">
     <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">{{
        type === 'settlement' ? '保存' : '提交'  
      }}</el-button>
      </div>

      <div v-else>
        <upload-excel :on-success="onSuccess" :before-upload="beforeUpload" />
      </div>

      <ex-table
        noPagination
        :columns="columns"
        :table="table"
        :data="tableData"
        style="margin: 15px 0 0 0"
      />
    </div>

    <div class="flex-end" v-else>
      <el-button  type="primary" :size="'mini'" @click="onActivitySubmit">提交</el-button>
    </div>
  </el-dialog>
</template>

<script>
import asyncRequest from "@/apis/components/letter"
import companyHelper from '@/mixins/companyHelper'
import { utils, writeFile } from "xlsx"
import { template, intergeFields } from "./_template"
import { mapTitle } from './_columns'

import {
  columns,
  numberFields,
  getColumn,
  requsetFields,
  requiredFields,
  getTableProperty,
  mapFields
} from './_template'
import { add_sum, accMul } from '../../../../utils/validate'


export default {
  mixins: [companyHelper],
  props: ['visible', 'title', 'requsetMethod','isFile', 'type', 'id'],
  data() {
    return {
      columns,
      loading: false,
      tableData: [],
      storeId:"",
      file_name:"",
      file_url:"",
      isInit:true,
      mapTitle,
      table: {
        stripe: true,
        border: true,
        'max-height': '800px'
      }
    }
  },
  computed: {
    innerVisible: {
      get() {
        return this.visible
      },
      set(newVal) {
        this.$emit('update:visible', newVal)
      }
    }
  },
  methods: {
    handleClose(){
      this.tableData = []
      this.loading = false
      this.file_url = ""
      this.innerVisible = false
    },
    isNumberValid(input) {
    // 正则表达式模式
     var pattern = /^\d+(\.\d+)?$/;
      // 使用正则表达式进行匹配
     return pattern.test(input);
    },
    downloadTemplate(){
      const workBook = utils.book_new()
      const workSheet = utils.json_to_sheet(template)
      utils.book_append_sheet(workBook,workSheet,"sheet")
      writeFile(workBook,"预算函模板.xlsx",{
        bookType:'xlsx'
      })
    },
    validateTableHeader(header, importHeader) {
      console.log(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
    },
    beforeOtherUpload(file) {
      let isJPG = false;
      if (
        file.type === "application/vnd.ms-excel" ||
        file.type ===
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ||
        file.type === "application/pdf" ||
        file.type === "application/x-zip-compressed"
      ) {
        isJPG = true;
      }
      let name = file.name;
      let list = name.split(".");
      if (list[list.length - 1] === "rar" || list[list.length - 1] === "7z" || list[list.length - 1] === "zip") {
        isJPG = true;
      }

      const isLt2M = file.size / 1024 / 1024 < 5;
      if (!isJPG) {
        this.$message.error("文件格式不正确！");
      }
      if (!isLt2M) {
        this.$message.error("文件大小不能超过 5MB!");
      }
      return isJPG && isLt2M;
    },
        //其他文件上传失败
    UploadErrorOtherproof_url(res) {
      if (res !== "break") {
        this.$message.error("文件上传失败!");
      }
    },
    deleteUrl(){
      this.file_name = ""
      this.file_url = ""
    },
    async UploadSuccessOtherproof_url(data) {
      console.log(data)
      const { url, name } = data;
      this.file_name = name;
      this.file_url = url;
      // this.$message.success("文件成功!");
    },
    isValueNotNull(value){
      if(!value) return
      const _value = String(value)
      return _value.trim() !== ""
    },
    /* 校验导入的数据 **/
    validateFields(tableData = []) {
      for (const index in tableData) {
        const line = Number(index) + 1
        const tableItem = tableData[index]
        const properties = Object.keys(tableItem)
        for (const property of properties) {
          if(requiredFields.includes(property) && !this.isValueNotNull(tableItem[property])){
            this.$message.warning(`第 ${line} 行 : ${getColumn(property).label} 不能为空`)
            return false
          }

          if(numberFields.includes(property) && !this.isNumberValid(tableItem[property])){
            this.$message.warning(`第 ${line} 行 : ${getColumn(property).label} 必须为正数`)
            return false
          }

          if(intergeFields.includes(property) && this.isNumberValid(tableItem[property]) 
            && String(tableItem[property]).includes(".")){
            this.$message.warning(`第 ${line} 行 : ${getColumn(property).label} 必须为正整数`)
            return false
          }

          if(property === mapFields.price){
            // 校验:单价 * 数量 = 含税报价
            const includeTaxTotal = accMul(tableItem[mapFields.price], tableItem[mapFields.num])
            if(Number(includeTaxTotal) !== Number(tableItem[mapFields.taxIncludedQuote])){
              this.$message.warning(`第 ${line} 行 : 单价 * 数量必须等于含税报价`)
              return
            }
          }

          if(property === mapFields.nonTaxQuotes){
            //校验:非税报价 + 税额 = 含税报价
            const total = add_sum(tableItem[mapFields.nonTaxQuotes], tableItem[mapFields.tax])
            if(Number(total) !== Number(tableItem[mapFields.taxIncludedQuote])){
              this.$message.warning(`第 ${line} 行 : 非税报价 + 税额必须等于含税报价`)
              return
            }
          }
        }
      }

      return true
    },
    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)
    },
    onActivitySubmit(){
      if(this.isFile && !this.file_url){
        this.$message.warning('请上传文件！')
        return
      }

      this.$emit("activitySubmit", this.file_url)
      this.visible = false
    },
    async onSubmit() {
      if(!this.validateFields(this.tableData)){
        return
      }

      if((this.isFile && !this.file_url) && (
        this.type === 'activity'
      )){
        this.$message.warning('请上传文件！')
        return
      }

      if(this.type === "budget" && !this.storeId){
        this.$message.warning('请选择店铺!')
        return
      }

      if(this.type === "settlement"){
        const { code, data } = await asyncRequest.list({ 
          plan_type : 3, 
          req_id: this.id,
          status: 2,
          is_check: 1
        })

        if(code !== 1) return
        const [letter] = data.list || []
        const { store_id , plan_file} = letter
        this.storeId = store_id
        this.file_url = plan_file
      }

      const planinfo = this.tableData.map(tableItem => requsetFields.reduce((prev, currentKey) => ({
        ...prev,
        [currentKey]: tableItem[currentKey]
      }), {}))

      this.loading = true
      const { code } = await this.requsetMethod(planinfo, this.file_url, this.storeId)
      this.loading = false

      if(code === 0){
        this.innerVisible = false
      }

      if(code !== 1){
        return
      }

      this.$emit('refresh')
      this.innerVisible = false
    }
  }
}
</script>

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

.activity-upload{
  margin-bottom: 50px;
  margin-left: 10px;
}
</style>
