<script setup lang="ts">
import { reactive, ref, nextTick } from "vue";
import { ElMessage } from "element-plus";
import { importStation } from "@/api/station";
import * as XLSX from "xlsx";

defineOptions({ name: "StationUploadDialog" });

const emit = defineEmits(["on-import-finish"]);
const fileInputRef = ref<HTMLInputElement>();

const fieldList = [
  { label: "序号ID", value: "id" },
  { label: "站点ID", value: "stationId" },
  { label: "站点名称", value: "stationName" },
  { label: "设备短编号", value: "shortId" },
  { label: "设备SN", value: "equipmentId" },
  { label: "设备编号", value: "connectorId" },
  { label: "车位编号", value: "parkingNo" }
];

const initState = () => ({
  dialog: { isShowDialog: false },
  excelForm: {
    columns: [] as any[],
    data: [] as any[],
    importFields: [] as string[],
    selectFields: [] as Array<{ value: string; label: string }>
  },
  uploadFileName: "" as string | null,
  importLoading: false,
  tableHeight: 400
});

const state = reactive(initState());

const open = () => {
  state.dialog.isShowDialog = true;
  nextTick(() => {
    const clientHeight = document.body.clientHeight;
    state.tableHeight = clientHeight - 60 - 120 - 300;
  });
  state.excelForm.selectFields = fieldList.map(k => ({
    value: k.value,
    label: k.label
  }));
};

const onClose = () => {
  state.dialog.isShowDialog = false;
  Object.assign(state, initState());
};

const handleOpenFile = () => {
  fileInputRef.value?.click();
};

const handleFileChange = (e: Event) => {
  const input = e.target as HTMLInputElement;
  const file = input.files?.[0];
  if (!file) return;
  state.uploadFileName = file.name;
  parseExcel(file);
  input.value = "";
};

const parseExcel = (file: File) => {
  const reader = new FileReader();
  reader.onload = (e) => {
    const fileData = e.target?.result;
    const wb = XLSX.read(fileData, { type: "binary", cellDates: true });
    const sheet = wb.SheetNames[0];
    const rowList: any = XLSX.utils.sheet_to_json(wb.Sheets[sheet], { header: 1 });

    let maxColumnLength = 1;
    rowList.forEach((row: any, idx: number) => {
      if (idx < 10) maxColumnLength = Math.max(maxColumnLength, row.length);
    });

    const tmpHeaders: any[] = [];
    const headers = rowList[0] || [];
    for (let i = 0; i < maxColumnLength; i++) {
      const header = i >= headers.length ? "" : headers[i];
      const find = fieldList.find((k: any) => k.label === header || k.value === header);
      state.excelForm.importFields[i + 1] = find ? find.value : "";
      tmpHeaders.push({ field: `f${i}`, name: header || `列${i + 1}` });
    }
    state.excelForm.columns = [{ field: "idx", name: "#", fixed: "left" }, ...tmpHeaders];

    const tmpContents: any[] = [];
    for (let i = 1; i < rowList.length; i++) {
      const dl = rowList[i];
      const rowItem: any = {};
      let fullEmpty = true;
      dl.forEach((rowValue: any, columnIdx: number) => {
        if (rowValue) fullEmpty = false;
        rowItem[`f${columnIdx}`] = rowValue;
      });
      if (!fullEmpty) tmpContents.push(rowItem);
    }
    state.excelForm.data = tmpContents;
  };
  reader.readAsBinaryString(file);
};

const handleConfirm = () => {
  const checks: string[] = [];
  let checkPass = true;
  state.excelForm.importFields.forEach(key => {
    if (key) {
      if (checks.includes(key)) {
        checkPass = false;
        ElMessage.error("表头不可重复");
      } else {
        checks.push(key);
      }
    }
  });
  if (!checkPass) return;

  state.importLoading = true;
  const fieldIndexes: number[] = [];
  state.excelForm.importFields.forEach((key, idx) => {
    if (key) fieldIndexes.push(idx - 1);
  });
  const fields = state.excelForm.importFields.filter(k => !!k);
  const dataList: any[] = [];
  state.excelForm.data.forEach(data => {
    const item: any = {};
    fieldIndexes.forEach((idx, i) => {
      item[fields[i]] = data[`f${idx}`] || "";
    });
    dataList.push(item);
  });

  importStation({ fields, fieldIndexes, dataList })
    .then(() => {
      ElMessage.success("导入成功");
      state.importLoading = false;
      emit("on-import-finish");
      state.dialog.isShowDialog = false;
    })
    .catch(() => {
      state.importLoading = false;
    });
};

defineExpose({ open });
</script>

<template>
  <el-dialog
    :title="'导入『站点信息』'"
    v-model="state.dialog.isShowDialog"
    width="75%"
    destroy-on-close
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    draggable
  >
    <el-button @click="handleOpenFile" plain type="success" class="mt5">
      请选择excel文件上传导入
    </el-button>
    <el-text type="primary" class="ml5">
      {{ state.uploadFileName }}
    </el-text>
    <input
      ref="fileInputRef"
      type="file"
      accept=".xls,.xlsx"
      style="display: none"
      @change="handleFileChange"
    />

    <div class="w100 mt5" v-if="state.excelForm.columns.length > 1">
      <div class="field-select-row">
        <div
          v-for="(field, idx) in state.excelForm.columns"
          :key="'select_' + idx"
          class="field-select-header"
        >
          <template v-if="idx === 0">
            <div class="idx-header">导入列选择</div>
          </template>
          <el-select
            v-else
            v-model="state.excelForm.importFields[idx]"
            placeholder="选择字段"
            style="width: 135px"
            clearable
            filterable
          >
            <el-option
              v-for="opt in state.excelForm.selectFields"
              :key="opt.value"
              :label="opt.label"
              :value="opt.value"
            />
          </el-select>
        </div>
      </div>

      <div class="table-wrap" :style="{ maxHeight: state.tableHeight + 'px' }">
        <el-table
          :data="state.excelForm.data"
          border
          :max-height="state.tableHeight"
          style="width: 100%"
          size="small"
        >
          <el-table-column
            v-for="(field, idx) in state.excelForm.columns"
            :key="idx"
            :prop="field.field"
            :label="field.name"
            :width="135"
            :fixed="field.fixed"
            show-overflow-tooltip
          >
            <template v-if="field.field === 'idx'" #default="{ $index }">
              <span>{{ $index + 1 }}</span>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="onClose" size="default">取 消</el-button>
        <el-button type="primary" @click="handleConfirm" :loading="state.importLoading" size="default">
          导入
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped lang="scss">
.field-select-row {
  display: flex;
  overflow-x: auto;
  margin-bottom: 8px;
}

.field-select-header {
  flex-shrink: 0;
  margin-right: 4px;
}

.idx-header {
  width: 135px;
  height: 32px;
  line-height: 32px;
  border: 1px solid #eee;
  text-align: center;
  font-size: 13px;
}

.table-wrap {
  overflow-x: auto;
}
</style>
