<template>
  <SysDialog
    class="import-partition"
    :visible="dialog.visible"
    v-bind="getBindValue"
    @onClose="onClose"
  >
    <template #content>
      <div class="import-partition-warp">
        <el-alert type="info" show-icon>
          表头顺序必须以ZIP Code、Zone为准
          <br />
          快速导入会直接覆盖当前分区更新
          <br />
          可直接复制excel文件导入分区
          <el-button
            class="import-model"
            type="primary"
            link
            @click="exportTemplate"
            :disabled="importPartition.exportLoad"
            :loading="importPartition.exportLoad"
            >下载模版</el-button
          >
        </el-alert>
        <div class="title">邮编分区设置</div>
        <el-form ref="importPartitionRef" :model="importPartition" :rules="importPartition.rules">
          <el-row>
            <el-col :span="12">
              <el-form-item label="邮编模式" label-width="110px">
                <BaseSelect
                  v-model:modelValue="importPartition.postalCodeMode"
                  :filterable="false"
                  :options="importPartition.postalCodeModeList"
                  @change="changePostalCodeMode"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item prop="countryId" label="国家/地区" label-width="110px">
                <BaseSelect
                  v-model:modelValue="importPartition.countryId"
                  class="countryId-select"
                  :filterable="true"
                  :options="countryList"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-show="getIsFill">
            <el-col :span="12">
              <el-form-item prop="startZipCodeFill" label="起始邮编填充" label-width="110px">
                <el-input v-model="importPartition.startZipCodeFill"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item prop="endZipCodeFill" label="结束邮编填充" label-width="110px">
                <el-input v-model="importPartition.endZipCodeFill"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item>
            <el-input
              v-model="importPartition.content"
              :autosize="{ minRows: 22, maxRows: 28 }"
              type="textarea"
              :placeholder="importPartition.placeholderText"
            />
          </el-form-item>
        </el-form>
      </div>
      <div class="flex justify-end footer">
        <el-button type="danger" @click="onClose"> 取消 </el-button>
        <el-button type="primary" @click="hanleSetZones"> 确定 </el-button>
      </div>
    </template>
  </SysDialog>
</template>
<script lang="ts" setup>
import { ref, reactive, unref, computed } from "vue";
import SysDialog from "@/components/SysDialog.vue";
import useDialog from "@/hooks/useDialog";
import { useMessage } from "@/hooks/useMessage";
import { BasePartitionTypeEnum } from "@/type/BasePartitionTypeEnum";
import { v4 as uuidv4 } from "uuid";
import { zoningStore } from "@/store/zoning";
import { useErrorConfirm } from "@/utils/useErrorConfirm";
import { api_downloadZipCodeArea } from "@/api/partition/partition";
import { downloadByData } from "@/utils/download";
import BaseSelect from '@/components/QuerySelect/BaseSelect.vue';
import { useDropDownData } from "@/hooks/useDropDownData";
import { useEleFormValidate } from "@/hooks/useEleFormValidate";
import { ListIitem } from "@/api/base/BaseDataModel";
import { generateZipCodeRegexForRange } from "@/utils/dealData";

const emit = defineEmits(["savePartition"]);
const { ElMessageBox, createMessage } = useMessage();
const { countryList } = useDropDownData()
const { report } = useErrorConfirm();
//弹框属性
const { dialog, onClose, onShow } = useDialog();
// 弹框一些配置
const getBindValue = reactive({
  title: "导入分区",
  top: "6vh",
  width: 660,
  height: 0,
  isFooter: true,
  closeOnClickModal: false,
});
// 分区 store
const zoningstore = zoningStore();
// 基础数据
const importPartition = reactive({
  rules: {
    countryId: [{ required: true, message: '请选择国家/地区', trigger: 'change' }],
    // startZipCodeFill: [{ required: true, message: '请输入起始邮编填充', trigger: 'blur' }],
    // endZipCodeFill: [{ required: true, message: '请输入结束邮编填充', trigger: 'blur' }],
  },
  content: "", //国家/地区分区设置
  partitionList: [] as Recordable[],
  exportLoad: false,
  startZipCodeFill: "",
  endZipCodeFill: "",
  countryId: undefined,
  postalCodeMode: 1,
  postalCodeModeList: [
    { value: 1, label: '填充模式' },
    // { value: 2, label: '区间正则模式' },
  ] as ListIitem[],
  placeholderText: `ZIP Code	Zone
005---089 8区
  `
});
const getIsFill = computed(() => importPartition.postalCodeMode === 1)
const getIsRegex = computed(() => importPartition.postalCodeMode === 2)
const changePostalCodeMode = (val) => {
  if (val === 2) {
    importPartition.startZipCodeFill = ""
    importPartition.endZipCodeFill = ""
  }
}

const show = (data) => {
  if (data.countryId) importPartition.countryId = data.countryId
  onShow();
};

// 导出模版
const exportTemplate = async () => {
  importPartition.exportLoad = true;
  try {
    const res = await api_downloadZipCodeArea({});
    // debugger
    if (res) {
      // 获取接口表格响应的头
      const header = res.headers["content-disposition"].split("''");
      // 转中文
      const fileName = decodeURIComponent(header[1]);
      // 通过blod导出模板
      downloadByData(res.data, fileName);
      importPartition.exportLoad = false;
    }
  } catch (error) {
    importPartition.exportLoad = false;
  }
};

// 判断表头顺序必须以ZIP Code、Zone为准
function checkArrayHead(arr) {
  const xlsxHead = ["ZIP Code", "Zone"];
  if (
    Array.isArray(arr) &&
    arr.length === xlsxHead.length &&
    arr.every((item, index) => item === xlsxHead[index])
  ) {
    return true;
  } else {
    return false;
  }
}

// 表单 ref
const importPartitionRef = ref()
const { formValidate, resetForm } = useEleFormValidate()
// 快速导入
const hanleSetZones = async () => {
  const isValidate = await formValidate(unref(importPartitionRef))
  if (!isValidate) return;
  const content = importPartition.content;
  try {
    if (content) {
      // 拆行数据并且过滤空格
      const itemList = content.split(/[\r\n]+/).filter((item) => item);
      // 表头
      const headers = itemList[0].split(/\s{2,}|\t/g);
      // 规定这个表头
      const isHead = checkArrayHead(headers);
      if (!isHead) {
        ElMessageBox.alert(
          "Excel表头顺序必须是（ZIP Code、Zone）"
        );
        return false;
      }
      // 判断表格是否对齐
      const notAligned = itemList.filter((x) => {
        return (
          x.split(/\s{2,}|\t/g).filter((str) => str).length != headers.length
        );
      });
      if (notAligned.length > 0) {
        // 表格未对齐
        ElMessageBox.alert(
          "当前分区内容表格未对齐<br/>" + notAligned.join("<br/>"),
          { dangerouslyUseHTMLString: true }
        );
        return false;
      }

      unref(getIsFill) && dealFillZipCode(itemList)
      unref(getIsRegex) && dealIntervalZipCode(itemList)
      ElMessageBox.confirm("是否确定快速导入").then(() => {
        // console.log(importPartition.partitionList, "<==邮编分区数据");
        emit("savePartition", importPartition.partitionList);
        clear();
      });
    } else {
      ElMessageBox.alert("请输入邮编信息");
    }
  } catch (error) {
    report(error);
  }
};
// 处理填充邮编
const dealFillZipCode = (itemList: string[]) => {
// 判断分区名称是否存在
  let foundPartition = false;
  let zipCodeBelongArea = {}
  for (let i = 1; i < itemList.length; i++) {
    foundPartition = false
    zipCodeBelongArea = {}
    // 邮编信息
    const country = {
      countryId: importPartition.countryId,
      haveZipCodeArea: true,
      zipCodeBelongAreaList: [] as Recordable[]
    };
    // xlsx行数据
    const fields = itemList[i].split(/\s{2,}|\t/g);

    // 分区名称
    const fieldsCodes = fields[0] && fields[0].replace(/\s/g, "")
    const fieldsText = fields[1] && fields[1].replace(/\s/g, "")
    const zipCode = fieldsCodes.split('---')
    if (zipCode.length === 2) {
      zipCodeBelongArea = { startZipCode: zipCode[0] + importPartition.startZipCodeFill, endZipCode: zipCode[1] + importPartition.endZipCodeFill }
      country.zipCodeBelongAreaList = [zipCodeBelongArea]
    } else {
      zipCodeBelongArea = { startZipCode: zipCode[0] + importPartition.startZipCodeFill, endZipCode: zipCode[0] + importPartition.endZipCodeFill }
      zipCode[0] && (country.zipCodeBelongAreaList = [zipCodeBelongArea])
    }
    // 判断分区名称是否相同
    for (let j = 0; j < importPartition.partitionList.length; j++) {
      const partitionName = importPartition.partitionList[j].partitionName
      const partitionNameText = partitionName && partitionName.replace(/\s/g, "")
      if (
        partitionNameText === fieldsText
        && zipCode.length > 0
      ) {
        // 相同分区添加邮编进去
        importPartition.partitionList[j].countryInfoList[0].zipCodeBelongAreaList.push(zipCodeBelongArea)
        foundPartition = true;
        break;
      }
    }
    if (!foundPartition) {
      importPartition.partitionList.push({
        id: uuidv4(), // 以uuid生成的分区编号
        feeId: zoningstore.feeId, // 费用编号
        partitionName: fieldsText, //分区名称
        orderNumber: importPartition.partitionList.length + 1, //序号
        partitionType: BasePartitionTypeEnum.POSTALCODE, //分区类型
        countryInfoList: [country], //国家/地区分区
      });
    }
  }
}
// 处理区间邮编
const dealIntervalZipCode = (itemList: string[]) => {
// 判断分区名称是否存在
  let foundPartition = false;
  let zipCodeBelongArea = {}
  for (let i = 1; i < itemList.length; i++) {
    foundPartition = false
    zipCodeBelongArea = {}
    // 邮编信息
    const country = {
      countryId: importPartition.countryId,
      haveZipCodeArea: true,
      zipCodeBelongAreaList: [] as Recordable[]
    };
    // xlsx行数据
    const fields = itemList[i].split(/\s{2,}|\t/g);

    // 分区名称
    const fieldsCodes = fields[0] && fields[0].replace(/\s/g, "")
    const fieldsText = fields[1] && fields[1].replace(/\s/g, "")
    const zipCode = fieldsCodes.split('---')
    if (zipCode.length === 2) {
      // 区间的邮编范围
      const zipCodeRegex = generateZipCodeRegexForRange(zipCode[0], zipCode[1])
      if (zipCodeRegex.test(zipCode[0]) && zipCodeRegex.test(zipCode[1])) {
        zipCodeBelongArea = { startZipCode: zipCode[0], endZipCode: zipCode[1], zipCodeRegex: `${zipCodeRegex}` }
        country.zipCodeBelongAreaList = [zipCodeBelongArea]
      }
    } else {
      // 
    }
    // 判断分区名称是否相同
    for (let j = 0; j < importPartition.partitionList.length; j++) {
      const partitionName = importPartition.partitionList[j].partitionName
      const partitionNameText = partitionName && partitionName.replace(/\s/g, "")
      if (
        partitionNameText === fieldsText
        && zipCode.length > 0
      ) {
        // 相同分区添加邮编进去
        importPartition.partitionList[j].countryInfoList[0].zipCodeBelongAreaList.push(zipCodeBelongArea)
        foundPartition = true;
        break;
      }
    }
    if (!foundPartition) {
      importPartition.partitionList.push({
        id: uuidv4(), // 以uuid生成的分区编号
        feeId: zoningstore.feeId, // 费用编号
        partitionName: fieldsText, //分区名称
        orderNumber: importPartition.partitionList.length + 1, //序号
        partitionType: BasePartitionTypeEnum.POSTALCODE, //分区类型
        countryInfoList: [country], //国家/地区分区
      });
    }
  }
}
// 清空数据
const clear = () => {
  resetForm(unref(importPartitionRef))
  importPartition.startZipCodeFill = "",
  importPartition.endZipCodeFill = "",
  importPartition.postalCodeMode = 1
  importPartition.content = "";
  importPartition.partitionList = [];
  onClose();
};

//父组件调用子组件显示弹框
//暴露出去给外部使用
defineExpose({
  show,
});
</script>
<style lang="scss" scoped>
.import-partition {
  .import-partition-warp {
    .title {
      padding: 10px 0;
    }
  }

  .footer {
    padding-top: 16px;
  }
  .import-model {
    font-size: 12px;
    text-decoration: underline;
    margin-bottom: 3px;
  }
  
  .countryId-select {
    width: 100%;
  }
}
</style>
