<template>
  <div class="import-wizard-container">
    <!-- 导入模式选择 -->
    <div class="import-mode-selector">
      <el-radio-group v-model="importMode" @change="reset">
        <el-radio label="validate">校验导入（推荐）</el-radio>
        <el-radio label="direct">直接导入（不校验）</el-radio>
      </el-radio-group>
    </div>

    <!-- 文件上传区域 -->
    <div class="file-upload-area" :class="{ disabled: importStatus === 'processing' }">
      <el-upload
        ref="upload"
        class="upload-excel"
        action=""
        :auto-upload="false"
        :show-file-list="false"
        :on-change="handleFileChange"
        accept=".xlsx,.xls"
        :disabled="importStatus === 'processing'"
      >
        <el-button type="primary" icon="el-icon-upload2">选择Excel文件</el-button>
      </el-upload>

      <!-- 操作按钮 -->
      <el-button
        type="success"
        icon="el-icon-check"
        @click="handleValidate"
        v-if="file && importMode === 'validate' && importStatus === 'idle'"
        :disabled="!file"
      >
        校验数据
      </el-button>
      <el-button
        type="warning"
        icon="el-icon-circle-check"
        @click="startImport"
        v-if="file && (importMode === 'direct' || (importMode === 'validate' && errorList.length === 0)) && importStatus === 'idle'"
        :disabled="!file || (importMode === 'validate' && errorList.length > 0)"
      >
        开始导入
      </el-button>
      <el-button
        type="default"
        icon="el-icon-refresh"
        @click="reset"
        :disabled="importStatus === 'processing'"
      >
        重置
      </el-button>
    </div>

    <!-- 校验错误提示 -->
    <div v-if="errorList.length > 0" class="error-list">
      <el-alert
        title="数据校验失败"
        type="error"
        description="以下行数据不符合格式要求，请修正后重新导入："
        show-icon
      />
      <el-table :data="errorList" border size="small" max-height="200">
        <el-table-column prop="rowNum" label="行号" width="80" />
        <el-table-column prop="errorMsg" label="错误信息" />
      </el-table>
    </div>

    <!-- 数据预览 -->
    <div v-if="tableData.length > 0 && importStatus === 'idle'" class="data-preview">
      <el-alert
        title="数据预览"
        type="info"
        :description="`共解析出 ${tableData.length} 条有效数据`"
        show-icon
        :closable="false"
      />
      <el-table :data="tableData" border size="small" max-height="300" stripe>
        <el-table-column prop="type" label="类型" width="80" />
        <el-table-column prop="logicWarehouse" label="逻辑库区" width="120" />
        <el-table-column prop="inboundCoilNo" label="入场卷号" width="150" />
        <el-table-column prop="factoryCoilNo" label="厂家卷号" width="150" />
        <el-table-column prop="weight" label="重量（吨）" width="120" />
        <el-table-column prop="remark" label="备注" min-width="100" />
        <el-table-column prop="name" label="名称" min-width="100" />
        <el-table-column prop="specification" label="规格" min-width="100" />
        <el-table-column prop="material" label="材质" width="100" />
        <el-table-column prop="manufacturer" label="厂家" min-width="100" />
        <el-table-column prop="surfaceTreatmentDesc" label="表面处理" width="120" />
        <el-table-column prop="zincLayer" label="锌层" width="100" />
      </el-table>
    </div>

    <!-- 导入进度展示 -->
    <div v-if="importStatus === 'processing'" class="import-progress">
      <el-alert
        title="正在导入数据"
        type="warning"
        :description="`当前进度：${progress}%`"
        show-icon
        :closable="false"
      />
      <el-progress :percentage="progress" status="success" />
      <p class="progress-tip">已导入 {{ importedCount }} / {{ totalCount }} 条数据</p>
    </div>

    <!-- 导入完成提示 -->
    <div v-if="importStatus === 'finished'" class="import-finished">
      <el-alert
        title="导入完成"
        type="success"
        :description="`共成功导入 ${importedCount} 条数据，总计 ${totalCount} 条`"
        show-icon
      />
    </div>

    <!-- 导入失败提示 -->
    <div v-if="importStatus === 'error'" class="import-error">
      <el-alert
        title="导入失败"
        type="error"
        :description="importErrorMsg"
        show-icon
      />
    </div>
  </div>
</template>

<script>
import * as XLSX from 'xlsx';
import { addMaterialCoil } from '@/api/wms/coil';
import { addPendingAction } from '@/api/wms/pendingAction';
import { listRawMaterial } from '@/api/wms/rawMaterial';
import { listProduct } from '@/api/wms/product';

export default {
  name: 'MaterialCoilImportWizard',
  data() {
    return {
      // 导入模式：validate-校验导入 direct-直接导入
      importMode: 'validate',
      // 文件对象
      file: null,
      // 解析后的原始数据
      rawData: [],
      // 格式化后用于展示/导入的数据
      tableData: [],
      // 校验错误列表
      errorList: [],
      // 导入进度（0-100）
      progress: 0,
      // 已导入条数
      importedCount: 0,
      // 总数据条数
      totalCount: 0,
      // 导入状态：idle-闲置 processing-处理中 finished-完成 error-失败
      importStatus: 'idle',
      // 导入错误信息
      importErrorMsg: '',
      // 规定的表头（顺序和名称必须匹配）
      requiredHeaders: [
        '类型', '逻辑库区', '入场卷号', '厂家卷号', '重量（吨）', '备注', 
        '名称', '规格', '材质', '厂家', '表面处理', '锌层'
      ],
      // 表头映射（中文表头 -> 字段名）
      headerMap: {
        '类型': 'type',
        '逻辑库区': 'logicWarehouse',
        '入场卷号': 'inboundCoilNo',
        '厂家卷号': 'factoryCoilNo',
        '重量（吨）': 'weight',
        '备注': 'remark',
        '名称': 'name',
        '规格': 'specification',
        '材质': 'material',
        '厂家': 'manufacturer',
        '表面处理': 'surfaceTreatmentDesc',
        '锌层': 'zincLayer'
      }
    };
  },
  methods: {
    /**
     * 处理文件选择
     */
    handleFileChange(file) {
      this.file = file.raw;
      // 选择文件后自动读取Excel
      this.readExcel();
    },

    /**
     * 读取Excel文件内容
     */
    async readExcel() {
      if (!this.file) return;

      try {
        const fileReader = new FileReader();
        fileReader.readAsArrayBuffer(this.file);
        
        fileReader.onload = async (e) => {
          try {
            const data = new Uint8Array(e.target.result);
            const workbook = XLSX.read(data, { type: 'array' });
            // 取第一个sheet
            const sheetName = workbook.SheetNames[0];
            const worksheet = workbook.Sheets[sheetName];
            // 解析为JSON（跳过表头，从第二行开始）
            const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

            // 校验表头
            this.validateHeaders(jsonData[0]);
            // 解析数据行（从第二行开始）
            this.rawData = jsonData.slice(1).filter(row => row.length > 0); // 过滤空行
            // 格式化数据
            this.formatExcel();

            this.$message.success(`成功解析Excel，共读取到 ${this.rawData.length} 条数据`);
          } catch (error) {
            this.$message.error(`解析Excel失败：${error.message}`);
            this.importStatus = 'error';
            this.importErrorMsg = `解析Excel失败：${error.message}`;
          }
        };
      } catch (error) {
        this.$message.error(`读取文件失败：${error.message}`);
        this.importStatus = 'error';
        this.importErrorMsg = `读取文件失败：${error.message}`;
      }
    },

    /**
     * 校验表头是否匹配
     */
    validateHeaders(headers) {
      this.errorList = [];
      // 校验表头数量和名称
      if (headers.length !== this.requiredHeaders.length) {
        this.errorList.push({
          rowNum: 1,
          errorMsg: `表头数量不匹配，要求${this.requiredHeaders.length}列，实际${headers.length}列`
        });
        return;
      }

      // 校验每列表头名称
      headers.forEach((header, index) => {
        if (header !== this.requiredHeaders[index]) {
          this.errorList.push({
            rowNum: 1,
            errorMsg: `第${index + 1}列表头错误，要求："${this.requiredHeaders[index]}"，实际："${header}"`
          });
        }
      });

      if (this.errorList.length > 0) {
        this.$message.error('Excel表头格式不符合要求，请检查！');
      }
    },

    /**
     * 校验Excel数据格式
     */
    async validateExcel() {
      if (this.rawData.length === 0) {
        this.$message.warning('暂无数据可校验');
        return;
      }

      this.errorList = [];

      // 逐行校验
      for (let i = 0; i < this.rawData.length; i++) {
        const row = this.rawData[i];
        const rowNum = i + 2; // 数据行从第二行开始，行号=索引+2
        const rowObj = this.formatRowData(row, rowNum);

        // 1. 校验必填项
        const requiredFields = [
          { key: 'type', label: '类型', value: rowObj.type },
          { key: 'logicWarehouse', label: '逻辑库区', value: rowObj.logicWarehouse },
          { key: 'inboundCoilNo', label: '入场卷号', value: rowObj.inboundCoilNo },
          { key: 'name', label: '名称', value: rowObj.name },
          { key: 'specification', label: '规格', value: rowObj.specification },
        ];

        // 检查必填项为空
        for (const field of requiredFields) {
          if (!field.value || field.value.toString().trim() === '') {
            this.errorList.push({
              rowNum,
              errorMsg: `${field.label}不能为空`
            });
          }
        }

        // 2. 校验类型只能是“原料”或“成品”
        if (rowObj.type && !['原料', '成品'].includes(rowObj.type.trim())) {
          this.errorList.push({
            rowNum,
            errorMsg: '类型只能是"原料"或"成品"'
          });
        }

        // 3. 校验重量是数字且大于0
        if (rowObj.weight) {
          const weight = Number(rowObj.weight);
          if (isNaN(weight) || weight <= 0) {
            this.errorList.push({
              rowNum,
              errorMsg: '重量必须是大于0的数字'
            });
          }
        } else {
          this.errorList.push({
            rowNum,
            errorMsg: '重量不能为空'
          });
        }

        // 4. 预校验itemId是否存在（仅校验模式）
        if (rowObj.type && ['原料', '成品'].includes(rowObj.type.trim()) && !this.errorList.some(err => err.rowNum === rowNum)) {
          const itemId = await this._findItemId(rowObj);
          if (!itemId) {
            this.errorList.push({
              rowNum,
              errorMsg: `未找到唯一匹配的${rowObj.type}（名称：${rowObj.name}，规格：${rowObj.specification}）`
            });
          }
        }
      }

      if (this.errorList.length > 0) {
        this.$message.error(`数据校验失败，共发现${this.errorList.length}条错误`);
      } else {
        this.$message.success('数据校验通过，可以开始导入');
      }
    },

    /**
     * 格式化Excel行数据
     */
    formatExcel() {
      this.tableData = [];
      if (this.rawData.length === 0) return;

      // 逐行格式化
      this.rawData.forEach((row, index) => {
        const rowNum = index + 2;
        const rowObj = this.formatRowData(row, rowNum);
        this.tableData.push(rowObj);
      });
    },

    /**
     * 格式化单行数据
     */
    formatRowData(row, rowNum) {
      const rowObj = {};
      // 映射表头和字段
      this.requiredHeaders.forEach((header, index) => {
        const field = this.headerMap[header];
        // 处理空值，统一转为字符串
        rowObj[field] = row[index] ? row[index].toString().trim() : '';
      });
      // 重量转数字
      rowObj.weight = rowObj.weight ? Number(rowObj.weight) : 0;
      // 增加行号
      rowObj.rowNum = rowNum;
      return rowObj;
    },

    /**
     * 处理校验按钮点击
     */
    async handleValidate() {
      if (!this.file) {
        this.$message.warning('请先选择Excel文件');
        return;
      }
      await this.validateExcel();
    },

    /**
     * 开始导入数据
     */
    async startImport() {
      if (!this.file || this.tableData.length === 0) {
        this.$message.warning('暂无数据可导入');
        return;
      }

      // 直接导入模式下先快速校验基础格式
      if (this.importMode === 'direct') {
        await this.validateExcel();
        if (this.errorList.length > 0) {
          this.$message.error('直接导入模式下基础格式校验失败，请修正');
          return;
        }
      }

      // 初始化导入状态
      this.importStatus = 'processing';
      this.progress = 0;
      this.importedCount = 0;
      this.totalCount = this.tableData.length;
      this.importErrorMsg = '';

      try {
        await this.batchImport();
        this.importStatus = 'finished';
        this.$message.success(`导入完成！共成功导入${this.importedCount}条数据`);
      } catch (error) {
        this.importStatus = 'error';
        this.importErrorMsg = `导入失败：${error.message}，已导入${this.importedCount}条数据`;
        this.$message.error(this.importErrorMsg);
      }
    },

    /**
     * 批量导入数据
     */
    async batchImport() {
      // 遍历所有数据行，逐个导入
      for (let i = 0; i < this.tableData.length; i++) {
        if (this.importStatus === 'error') break; // 发生错误则停止

        const row = this.tableData[i];
        try {
          await this.importOneRecord(row);
          this.importedCount++;
          // 更新进度
          this.progress = Math.round(((i + 1) / this.totalCount) * 100);
        } catch (error) {
          // 单条失败可选择继续或终止，这里选择终止
          throw new Error(`第${row.rowNum}行导入失败：${error.message}`);
        }
      }
    },

    /**
     * 导入单条记录
     */
    async importOneRecord(row) {
      try {
        // 1. 查找itemId
        const itemId = await this._findItemId(row);
        if (!itemId) {
          throw new Error(`未找到唯一的${row.type}信息`);
        }

        const itemType = row.type === '原料' ? 'raw_material' : 'product';

        // 2. 插入钢卷数据（dataType=10）
        const coilParams = {
          itemId,
          itemType,
          logicWarehouse: row.logicWarehouse,
          inboundCoilNo: row.inboundCoilNo,
          factoryCoilNo: row.factoryCoilNo,
          weight: row.weight,
          remark: row.remark,
          dataType: 10 // 钢卷数据类型固定为10
        };
        const coilRes = await addMaterialCoil(coilParams);
        if (!coilRes.success) { // 假设接口返回success标识
          throw new Error(`钢卷数据插入失败：${coilRes.message || '接口返回异常'}`);
        }
        const coilId = coilRes.data?.coilId; // 假设返回钢卷ID

        // 3. 插入待处理操作（actionStatus=0）
        const actionParams = {
          coilId,
          actionStatus: 0, // 待处理状态固定为0
          itemType,
          itemId,
          operationType: 'import', // 操作类型：导入
          remark: `Excel导入：${row.inboundCoilNo}`
        };
        const actionRes = await addPendingAction(actionParams);
        if (!actionRes.success) {
          throw new Error(`待处理操作插入失败：${actionRes.message || '接口返回异常'}`);
        }

      } catch (error) {
        throw new Error(error.message);
      }
    },

    /**
     * 根据条件查找唯一的itemId
     */
    async _findItemId(row) {
      const itemType = row.type === '原料' ? 'raw_material' : 'product';
      let res = null;

      try {
        if (itemType === 'raw_material') {
          res = await listRawMaterial({
            rawMaterialName: row.name,
            specification: row.specification,
            material: row.material,
            manufacturer: row.manufacturer,
            surfaceTreatmentDesc: row.surfaceTreatmentDesc,
            zincLayer: row.zincLayer
          });
        } else {
          res = await listProduct({
            productName: row.name,
            specification: row.specification,
            material: row.material,
            manufacturer: row.manufacturer,
            surfaceTreatmentDesc: row.surfaceTreatmentDesc,
            zincLayer: row.zincLayer
          });
        }

        // 校验返回结果数量
        // 如果锌层，表面处理，厂家未传递，则需要从结果中取出这些值未空的记录
        const record = res.data.filter(item => 
          (!row.zincLayer || item.zincLayer === row.zincLayer) &&
          (!row.surfaceTreatmentDesc || item.surfaceTreatmentDesc === row.surfaceTreatmentDesc) &&
          (!row.manufacturer || item.manufacturer === row.manufacturer)
        );
        if (record.length !== 1) {
          return null;
        }

        // 返回对应ID
        return itemType === 'raw_material' 
          ? res.data[0].rawMaterialId 
          : res.data[0].productId;
      } catch (error) {
        this.$message.error(`查询${row.type}信息失败：${error.message}`);
        return null;
      }
    },

    /**
     * 重置所有状态
     */
    reset() {
      this.file = null;
      this.rawData = [];
      this.tableData = [];
      this.errorList = [];
      this.progress = 0;
      this.importedCount = 0;
      this.totalCount = 0;
      this.importStatus = 'idle';
      this.importErrorMsg = '';
      this.$refs.upload?.clearFiles(); // 清空上传组件文件
    }
  }
};
</script>

<style scoped>
.import-wizard-container {
  padding: 20px;
  background: #fff;
  border-radius: 4px;
}

.import-mode-selector {
  margin-bottom: 20px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
}

.file-upload-area {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.file-upload-area.disabled {
  opacity: 0.6;
  pointer-events: none;
}

.error-list {
  margin-bottom: 20px;
}

.data-preview {
  margin-bottom: 20px;
}

.import-progress {
  margin-bottom: 20px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
}

.progress-tip {
  margin: 10px 0 0 0;
  color: #666;
  font-size: 14px;
}

.import-finished, .import-error {
  margin-bottom: 20px;
}
</style>