<!-- AI入库 -->
<template>
  <div>
    <el-dialog title="批量入库" width="1000px" v-model="visible" @close="dialogCloseHandle">
      <div class="content">
        <div class="title_wrap">
          <span class="t">第一步：上传图片</span>
        </div>
        <div class="upload_wrap" v-loading="uploadLoading">
          <div class="upload_btn">
            <SingleImageUpload v-model="imgUrl" @upload="uploadLoading = true" @on-success="uploadSuccess"
              @clear="resId = null" />
          </div>
          <div class="btn">
            <el-button type="primary" :disabled="resId === null" @click="startCheckOcrRes">开始解析</el-button>
          </div>
        </div>
        <div class="title_wrap">
          <span class="t">第二步：编辑信息</span>
        </div>
        <div class="table" v-if="form.bodyList">
          <el-form :model="form" label-width="120px" label-position="top">
            <el-form-item label="供应商信息">
              <el-select v-model="form.vendorId" style="width: 200px;" :disabled="stockInStatus">
                <el-option v-for="item in vendorList" :key="item.id" :label="item.name" :value="item.id" />
              </el-select>
            </el-form-item>
            <el-form-item label="耗材信息">
              <div class="header_wrap">
                <div class="item">
                  <span class="tb">共{{ form.bodyList.length }}种耗材，</span>
                  <span class="tb">金额合计：￥{{multiplyAndFormat(form.bodyList.reduce((sum, item) => sum +
                    (item.purchasePrice || 0) *
                    (item.inOutNumber || 0), 0), 1)}}</span>
                </div>
                <div class="item">
                  <el-button type="primary" @click="consumableListRef.show(form.bodyList)"
                    v-if="!stockInStatus">选择耗材</el-button>
                </div>
              </div>
              <el-table :data="form.bodyList" border stripe width="100%" v-loading="confirmLoading">
                <el-table-column prop="conName" label="耗材名称">
                  <template v-slot="scope">
                    <el-input v-model="scope.row.conName" :maxlength="8" :disabled="stockInStatus"></el-input>
                  </template>
                </el-table-column>
                <el-table-column prop="purchasePrice" label="单价">
                  <template v-slot="scope">
                    <el-input v-model="scope.row.purchasePrice" :maxlength="8"
                      @input="e => scope.row.purchasePrice = filterNumberInput(e)" :disabled="stockInStatus"></el-input>
                  </template>
                </el-table-column>
                <el-table-column prop="unitName" label="单位">
                  <template v-slot="scope">
                    <el-input v-model="scope.row.unitName" :maxlength="8" :disabled="stockInStatus"></el-input>
                  </template>
                </el-table-column>
                <el-table-column prop="inOutNumber" label="数量">
                  <template v-slot="scope">
                    <el-input v-model="scope.row.inOutNumber" @input="e => scope.row.inOutNumber = filterNumberInput(e)"
                      :disabled="stockInStatus"></el-input>
                  </template>
                </el-table-column>
                <el-table-column prop="subTotal" label="小计">
                  <template v-slot="scope">
                    {{ multiplyAndFormat(scope.row.purchasePrice || 0, scope.row.inOutNumber || 0) }}
                  </template>
                </el-table-column>
                <el-table-column label="状态" width="120">
                  <template v-slot="scope">
                    <div v-if="stockInStatus">
                      <el-text type="success" v-if="scope.row.conId">入库成功</el-text>
                      <div class="column" v-else>
                        <div>
                          <el-text type="danger">入库失败</el-text>
                        </div>
                        <div>
                          <el-text type="info" size="small">失败原因：{{ scope.row.failReason }}</el-text>
                        </div>
                      </div>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="操作" width="80">
                  <template v-slot="scope">
                    <el-button type="danger" link @click="form.bodyList.splice(scope.$index, 1)"
                      v-if="!stockInStatus">删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-form-item>
          </el-form>
          <div class="result_wrap" v-if="stockInStatus">
            上传完成 共{{ form.bodyList.length }}条数据，其中成功
            <el-text type="success">{{form.bodyList.filter(item => item.conId).length}} </el-text> 条，失败 <el-text
              type="danger">{{form.bodyList.filter(item => !item.conId).length}} </el-text>条
          </div>
        </div>
        <div class="tips" v-else>
          <el-text type="danger">请解析后使用</el-text>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer" v-if="form.bodyList && !stockInStatus">
          <el-button @click="visible = false">取消</el-button>
          <el-button type="primary" :loading="confirmLoading" @click="submitHandle">提交</el-button>
        </div>
      </template>
    </el-dialog>
    <el-dialog title="扫描结果查询中..." width="500px" v-model="checkLoading" :show-close="false"
      :close-on-click-modal="false">
      <div class="loading_wrap" ref="loadingWrap" v-loading="checkLoading" :element-loading-text="loadingText"></div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="danger" @click="closeCheckOcrHandle">取消查询</el-button>
        </div>
      </template>
    </el-dialog>
    <consumableList ref="consumableListRef" @success="consumableListRes" />
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick } from "vue";
import SingleImageUpload from "@/components/Upload/SingleImageUpload.vue"
import productApi from "@/api/product/index";
import { ElMessage } from "element-plus";
import { filterNumberInput, multiplyAndFormat } from '@/utils'
import consumableList from "../../operation_in/components/consumableList.vue";

const consumableListRef = ref(null);

function consumableListRes(e) {
  console.log(e);
  if (e.length) {
    let arr = e.map(item => ({
      id: item.id,
      conId: item.id,
      conName: item.conName,
      purchasePrice: item.price,
      unitName: item.conUnit,
      inOutNumber: 1,
    }));
    form.value.bodyList.push(...arr);
  }
}

const emits = defineEmits(['update']);

const visible = ref(false);

const show = () => {
  visible.value = true;
};

const dialogCloseHandle = () => {
  emits('update');
  resId.value = null;
  form.value = {};
  stockInStatus.value = false;
  imgUrl.value = "";
};

// 上传图片
let resId = ref(null);
const uploadLoading = ref(false);
const imgUrl = ref("");
async function uploadSuccess(url) {
  try {
    imgUrl.value = url;
    uploadLoading.value = true;
    resId.value = await productApi.stockOcr({ url: imgUrl.value });
  } catch (error) {
    console.error('上传图片失败', error);
  }
  setTimeout(() => {
    uploadLoading.value = false;
  }, 500);
}

// 查询OCR结果
const form = ref({})
function startCheckOcrRes() {
  stockInStatus.value = false;
  startQueryInterval()
    .then((res) => {
      console.log('查询成功', JSON.stringify(res));
      form.value = res;
    })
    .catch((error) => {
      console.error('查询失败', error);
    });
}

// 启动查询方法，每5秒查询一次，五分钟后超时停止查询
const checkLoading = ref(false);
const speed = 10000; // 查询间隔时间，单位毫秒
const timeout = 300000; // 超时时间，单位毫秒
// const timeout = 15000; // 超时时间，单位毫秒
const interval = ref(null);
const checkNumber = ref(0);
const loadingText = computed(() => `每${speed / 1000}秒查询1次，已查询：${checkNumber.value}次`);
const loadingWrap = ref(null);

function updateOverlayText() {
  nextTick(() => {
    try {
      const el = loadingWrap.value && loadingWrap.value.querySelector && loadingWrap.value.querySelector('.el-loading-text');
      if (el) el.textContent = loadingText.value;
    } catch (e) {
      // ignore
    }
  });
}

watch(loadingText, () => {
  if (checkLoading.value) updateOverlayText();
});

watch(checkLoading, (val) => {
  if (val) updateOverlayText();
});
function startQueryInterval() {
  return new Promise((resolve, reject) => {
    if (!resId.value) {
      reject(new Error('无效的 resId，无法查询'));
      return;
    }

    // 重置计数并显示 loading
    checkNumber.value = 0;
    checkLoading.value = true;
    updateOverlayText();

    const startTime = Date.now();
    interval.value = null;

    async function checkOnce() {
      try {
        checkNumber.value++;
        console.log('ocr checkNumber:', checkNumber.value);
        checkLoading.value = true;
        const res = await productApi.ocrResult({ id: resId.value });
        if (res && res.batchNo) {
          ElMessage.success('查询成功');
          checkLoading.value = false;
          clearInterval(interval.value);
          resolve(res);
          return;
        }

        // 如果还未超时，则继续等待下一轮查询
        if (Date.now() - startTime >= timeout) {
          checkLoading.value = false;
          ElMessage.error('查询超时');
          clearInterval(interval.value);
          reject(new Error('查询超时'));
        }
      } catch (error) {
        ElMessage.error('查询失败');
        checkLoading.value = false;
        clearInterval(interval.value);
        reject(error);
      }
    }

    // 立即执行一次查询，然后按间隔继续查询
    checkOnce();
    interval.value = setInterval(checkOnce, speed);
  });
}

// 取消查询
function closeCheckOcrHandle() {
  checkLoading.value = false;
  clearInterval(interval.value);
  // 清空 overlay 文本（如果存在）以避免残留描述
  nextTick(() => {
    try {
      const el = loadingWrap.value && loadingWrap.value.querySelector && loadingWrap.value.querySelector('.el-loading-text');
      if (el) el.textContent = '';
    } catch (e) { }
  });
}

// 供应商列表
const vendorList = ref([]);
async function vendorListAjax() {
  try {
    vendorList.value = await productApi.vendorList();
  } catch (error) {
    console.log(error);
  }
}

// 最终提交
const confirmLoading = ref(false);
const stockInStatus = ref(false);
async function submitHandle() {
  try {
    confirmLoading.value = true;
    const res = await productApi.stockIn(form.value)
    form.value = res;
    stockInStatus.value = true;
    ElMessage.success('提交成功');
  } catch (error) {
    console.error('提交失败', error);
  }
  setTimeout(() => {
    confirmLoading.value = false;
    // visible.value = false;
  }, 500);
}

defineExpose({
  show,
});

onMounted(() => {
  vendorListAjax();
});
</script>

<style scoped lang="scss">
.content {
  .title_wrap {
    background-color: #F8F8F8;
    height: 54px;
    display: flex;
    align-items: center;
    padding: 0 42px;

    .t {
      font-size: 16px;
      color: #333;
    }
  }

  .upload_wrap {
    display: flex;
    justify-content: space-between;
    padding: 14px 0;

    .upload_btn {
      width: 152px;
      height: 152px;
    }
  }
}

.loading_wrap {
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.table {
  width: 100%;
  padding-top: 14px;
}

.result_wrap {
  padding: 14px 0;
  display: flex;
  justify-content: center;
}

.tips {
  padding: 14px 0;
  display: flex;
  justify-content: center;
}

.column {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.header_wrap {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 14px;

  .tb {
    font-size: 16px;
    font-weight: bold;
  }
}
</style>