<template>
  <div v-loading="loading" :element-loading-text="loadingText">
    <el-steps :active="1" align-center simple>
      <el-step style="cursor: pointer;" @click.native="active = 0" title="上传质保单" icon="el-icon-upload" />
      <el-step style="cursor: pointer;" @click.native="active = 1" title="质保单处理" icon="el-icon-edit" />
      <el-step style="cursor: pointer;" @click.native="active = 2" title="质保单审核" icon="el-icon-check" />
    </el-steps>
    <div v-if="active === 0" style="padding: 30px;">
      <file-upload v-model="uploadQualityCertificateForm.qualityCertificate" />
    </div>

    <div v-if="active === 1">
      <el-row>
        <el-alert title="质保单处理" type="info" />
      </el-row>

      <!-- 提取质保单信息,选择使用ocr还是使用大模型 -->
      <el-row :gutter="20">
        <el-col :span="12">
          <div
            style="border: 1px solid #ccc; border-radius: 10px; padding: 20px; cursor: pointer; text-align: center; position: relative;">
            <!-- 齿轮图标，绝对定位在左上角 -->
            <i class="el-icon-setting"
              style="position: absolute; left: 10px; top: 10px; font-size: 20px; color: #606266; cursor: pointer; z-index: 2;"
              @click.stop="openKeyListDialog"></i>
            <div style="margin-bottom: 10px; display: flex; align-items: center; justify-content: center;">
              <span style="font-weight: bold; font-size: 16px;">OCR识别</span>
              <el-tooltip content="通过OCR自动识别PDF质保单内容" placement="top">
                <i class="el-icon-question" style="margin-left: 6px; color: #409EFF; cursor: pointer;"></i>
              </el-tooltip>
            </div>
            <img @click="handleOcr" :src="ocrImage" alt="ocr" style="width: 120px; height: 120px; object-fit: contain;"
              append-to-body />
          </div>
        </el-col>
        <el-col :span="12">
          <div style="border: 1px solid #ccc; border-radius: 10px; padding: 20px; cursor: pointer; text-align: center;">
            <div style="margin-bottom: 10px; display: flex; align-items: center; justify-content: center;">
              <span style="font-weight: bold; font-size: 16px;">大模型识别</span>
              <el-tooltip content="通过AI大模型识别图片质保单内容" placement="top">
                <i class="el-icon-question" style="margin-left: 6px; color: #409EFF; cursor: pointer;"></i>
              </el-tooltip>
            </div>
            <img @click="handleModel" :src="modelImage" alt="model"
              style="width: 120px; height: 120px; object-fit: contain;" />
          </div>
        </el-col>
      </el-row>
    </div>

    <div v-if="active === 2">
      <div v-if="resultDiff">
        <merger :info="info" :old-result="oldResult" :new-result="newResult" @confirm="handleMergerConfirm" />
      </div>
      <div v-else>
        <el-row>
          <el-alert title="请核对识别结果是否正确" type="success" />
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-table :data="newResult" style="width: 100%">
              <el-table-column prop="attrKey" label="属性名称" />
              <el-table-column prop="attrValue" label="属性值" />
            </el-table>
          </el-col>
          <el-col :span="12">
            <div>
              <img style="width: 100%; height: 100%;" :src="file.url" alt="">
            </div>
          </el-col>
        </el-row>
        <el-button type="primary" @click="handleConfirm">确认</el-button>
      </div>
    </div>

    <!-- keyList配置弹窗 -->
    <el-dialog title="配置OCR识别字段" :visible.sync="showKeyListDialog" width="400px" append-to-body>
      <div>
        <el-tag type="info" style="margin-bottom: 8px;">每行一个字段名，顺序影响识别</el-tag>
        <el-input type="textarea" :rows="8" v-model="keyListInput" placeholder="如：订货单位\n合同号\n产品名称..." />
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="showKeyListDialog = false">取消</el-button>
        <el-button type="primary" @click="saveKeyList">保存</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import FileUpload from '@/components/FileUpload'
import { listByIds } from '@/api/system/oss'
import { updatePurchasePlanDetail } from '@/api/wms/purchasePlanDetail'
import { recognizeText, recognizeBomByModel, recognizePdfText } from '@/api/system/ocr'
import { listBomItem } from '@/api/wms/bomItem'
import { getRawMaterial } from '@/api/wms/rawMaterial'
import Merger from './merger.vue'

import modelImage from '@/assets/images/model.png'
import ocrImage from '@/assets/images/ocr.png'

const so = {
  annex: {
    loading: '正在保存质保单',
    handler: async (vm, newVal) => {
      return await updatePurchasePlanDetail({
        ...vm.info,
        annex: newVal
      })
    }
  },
  ocr: {
    loading: '等待ocr识别结果',
    handler: async (vm) => {
      function extractData(text) {
        // 优先读取localStorage配置的keyList
        let keyList = [];
        try {
          const local = localStorage.getItem('ocrKeyList');
          if (local) {
            keyList = local.split('\n').map(k => k.trim()).filter(k => k);
          }
        } catch { }
        // 默认keyList
        if (!keyList.length) {
          keyList = [
            "订货单位", "合同号", "产品名称", "执行标准",
            "卷号", "原料坯号", "规格", "材质",
            "表面状态", "调制度", "切边要求", "包装种类",
            "毛重", "净重", "参考长度"
          ];
        }
        // 预处理：将复合键合并（如"合同号"、"卷号"等）
        let normalizedText = text
          .replace(/卷\s*号/g, "卷号")
          .replace(/原料\s*坯号/g, "原料坯号")
          .replace(/切边\s*要求/g, "切边要求")
          .replace(/包装\s*种类/g, "包装种类");
        const lines = normalizedText.split(/\r?\n/).filter(line => line.trim());
        const result = [];
        // 核心数据行处理（跳过首行公司名）
        for (let i = 1; i < lines.length; i++) {
          let currentLine = lines[i];
          let remaining = currentLine;
          // 处理单行中的多组键值对
          while (remaining) {
            let found = false;
            // 检查剩余文本是否以已知键开头
            for (const key of keyList) {
              if (remaining.startsWith(key)) {
                found = true;
                // 移动到键之后的位置
                let afterKey = remaining.substring(key.length).trim();
                // 查找下一个键的起始位置
                let nextKeyIndex = afterKey.length;
                for (const k of keyList) {
                  const idx = afterKey.indexOf(k);
                  if (idx > -1 && idx < nextKeyIndex) {
                    nextKeyIndex = idx;
                  }
                }
                // 提取当前键的值
                const value = afterKey.substring(0, nextKeyIndex).trim();
                result.push({
                  attrKey: key,
                  attrValue: key === "毛重" || key === "净重"
                    ? value.replace(/\D/g, "") // 提取数字部分
                    : value
                });
                // 更新剩余文本
                remaining = afterKey.substring(nextKeyIndex).trim();
                break;
              }
            }
            // 如果没有找到更多键，结束循环
            if (!found) break;
          }
        }
        return result;
      }
      const { text } = (await recognizePdfText({ pdfUrl: vm.file.url })).data
      console.log(text)
      const result = extractData(text)
      console.log(result)
      vm.newResult = result;
      return result;
    }
  },
  model: {
    loading: '等待大模型识别结果',
    handler: async (vm) => {
      const res = await recognizeBomByModel({ imageUrl: vm.file.url })
      vm.newResult = res.data.attributes;
      vm.$modal.msgSuccess("识别成功");
      return res;
    }
  },
  bom: {
    loading: '正在处理BOM'
  },
  oss: {
    loading: '正在获取质保单',
    handler: async (vm, newVal) => {
      const res = await listByIds(newVal)
      vm.file = res.data[0];
      vm.active = 1;
      return res.data[0];
    }
  },
  old: {
    loading: '正在获取历史质保单',
    handler: async (vm, newVal) => {
      // 查询对应的bomId
      const res = await getRawMaterial(vm.info.rawMaterialId)
      const bomId = res.data.bomId;
      const bomItemRes = await listBomItem({
        bomId,
      })
      vm.oldResult = bomItemRes.rows;
      return bomItemRes.rows;
    }
  },
  compare: {
    loading: '正在比较新旧质保单',
    handler: async (vm) => {
      // 先检查新旧result是否一致
      if (vm.oldResult.length !== vm.newResult.length) {
        vm.resultDiff = true;
        return;
      }
      // 比较新旧result是否一致
      for (let i = 0; i < vm.oldResult.length; i++) {
        if (vm.oldResult[i].attrKey !== vm.newResult[i].attrKey || vm.oldResult[i].attrValue !== vm.newResult[i].attrValue) {
          vm.resultDiff = true;
          return;
        }
      }
      vm.resultDiff = false;
      return false;
    }
  }
}

// 原子操作, 用于细化的进度展示, 無論其同步還是異步一律視作異步函數執行, 並返回一個Promise
const atoms = {

}

export default {
  name: 'QualityCerticate',
  components: {
    FileUpload,
    Merger
  },
  props: {
    info: {
      type: Object,
      default: () => ({})
    }
  },
  watch: {
    info: {
      handler(newVal) {
        this.active = 0;
        if (newVal.annex) {
          this.uploadQualityCertificateForm.qualityCertificate = newVal.annex;
        } else {
          this.uploadQualityCertificateForm.qualityCertificate = undefined;
        }
      },
      deep: true,
      immediate: true
    },
    'uploadQualityCertificateForm.qualityCertificate': {
      handler(newVal) {
        if (newVal) {
          this.loadingMethod('oss')
        }
        this.loadingMethod('annex')
      },
      immediate: true
    }
  },
  data() {
    return {
      uploadQualityCertificateForm: {
        qualityCertificate: undefined,
        qualityCertificateType: undefined,
      },
      active: 0,
      file: undefined,
      loading: false,
      loadingText: '加载中...',
      resultDiff: true,
      oldResult: [],
      newResult: [],
      modelImage,
      ocrImage,
      showKeyListDialog: false,
      keyListInput: '',
    }
  },
  methods: {
    handleOcr() {
      // 识别file是不是pdf, 只有pdf可以使用ocr
      if (!this.file.url.endsWith('.pdf')) {
        this.$modal.msgError('质保单不是pdf格式');
        return;
      }
      this.loadingMethod('ocr', async (res) => {
        await this.loadingMethod('old')
        await this.loadingMethod('compare')
        this.active = 2;
      })
    },
    handleModel() {
      this.loadingMethod('model', async (res) => {
        await this.loadingMethod('old')
        await this.loadingMethod('compare')
        this.active = 2;
      })

    },
    async handleConfirm() {
      // 变更状态
      this.active = 3;
      this.$emit('confirm')
    },
    handleMergerConfirm(res) {
      if (res.status === 'start') {
        this.loading = true;
        this.loadingText = '正在处理产品BOM';
      } else if (res.status === 'success') {
        this.loading = false;
        this.active = 3;
        this.$emit('confirm')
      } else if (res.status === 'error') {
        this.loading = false;
        this.$modal.msgError('质保单处理失败');
      }
    },
    async loadingMethod(key, fn) {
      this.loading = true;
      this.loadingText = so[key].loading;
      try {
        const res = await so[key].handler(this, this.uploadQualityCertificateForm.qualityCertificate)
        fn && await fn(res)
        return res;
      } catch {
        this.$modal.msgError('操作失败');
      } finally {
        this.loading = false;
      }
    },
    // 比较新旧result是否一致
    handleCompareResult() {
      // 先检查新旧result是否一致
      if (this.oldResult.length !== this.newResult.length) {
        this.resultDiff = true;
        return;
      }
      // 比较新旧result是否一致
      for (let i = 0; i < this.oldResult.length; i++) {
        if (this.oldResult[i].attrKey !== this.newResult[i].attrKey || this.oldResult[i].attrValue !== this.newResult[i].attrValue) {
          this.resultDiff = true;
          return;
        }
      }
      this.resultDiff = false;
    },
    // 保存keyList到localStorage
    saveKeyList() {
      localStorage.setItem('ocrKeyList', this.keyListInput)
      this.showKeyListDialog = false
      this.$message.success('已保存OCR字段配置')
    },
    // 打开弹窗时初始化内容
    openKeyListDialog() {
      let local = ''
      try {
        local = localStorage.getItem('ocrKeyList') || ''
      } catch { }
      if (local) {
        this.keyListInput = local
      } else {
        this.keyListInput = [
          "订货单位", "合同号", "产品名称", "执行标准",
          "卷号", "原料坯号", "规格", "材质",
          "表面状态", "调制度", "切边要求", "包装种类",
          "毛重", "净重", "参考长度"
        ].join('\n')
      }
      this.showKeyListDialog = true
    },
  }
}
</script>

<style scoped>
.el-row {
  margin-bottom: 20px;
  margin-top: 20px;
}
</style>