<template>
  <div class="qr-parser-container">

    <div class="card">
      <el-alert title="请将当前输入法切换到英文输入后再进行扫码操作" type="warning"></el-alert>
      <div class="card-header">
        <h2 class="title">二维码解析器</h2>
        <p class="subtitle">扫描或输入二维码内容进行解析</p>
      </div>

      <div class="input-section">
        <el-input v-model="text" @input="handleInput" @blur="handleBlur" ref="textarea"
          placeholder="请扫描二维码或粘贴二维码文本内容..." :rows="3" type="textarea"
          :class="{ 'invalid-input': !isValid && text.length > 0 }" />
        <div class="input-hint">
          <i class="el-icon-info-circle"></i>
          <span>{{ inputHint }}</span>
        </div>
      </div>

      <!-- 加载状态 -->
      <el-loading v-if="isLoading" text="正在解析数据..." class="loading-overlay"></el-loading>

      <!-- 二维码解析结果 - 只有数据有效时才显示 -->
      <div v-if="isValid" class="result-section fade-in">
        <div class="result-header">
          <h3>解析结果</h3>
          <el-tag :type="result.ioType === 'in' ? 'success' : 'warning'" size="small">
            {{ result.ioType === 'in' ? '入库' : '出库' }}
          </el-tag>
        </div>

        <el-descriptions :column="1" border class="result-table">
          <el-descriptions-item label="出入库类型" :span="1">
            {{ result.ioType === 'in' ? '入库' : '出库' }}
          </el-descriptions-item>
          <el-descriptions-item label="物料类型" :span="1">
            {{ formatItemType(result.itemType) }}
          </el-descriptions-item>
          <el-descriptions-item label="物料信息" :span="1">
            <ProductInfo v-if="result.itemType === 'product' || result.itemType === 'semi'"
              :productId="result.itemId" />
            <RawMaterialInfo v-else-if="result.itemType === 'raw_material'" :materialId="result.itemId" />
            <el-input v-else disabled v-model="result.itemId" placeholder="未知物料" :disabled="true"
              style="width: 100%;" />
          </el-descriptions-item>
          <el-descriptions-item label="数量" :span="1">
            {{ result.quantity }}
          </el-descriptions-item>
        </el-descriptions>

        <div class="action-buttons">
          <el-button type="primary" @click="handleSubmit" :loading="isSubmitting" icon="el-icon-check">
            确认执行
          </el-button>
          <el-button type="default" @click="handleReset" icon="el-icon-refresh-right">
            重置
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import ProductInfo from '@/components/KLPService/Renderer/ProductInfo';
import RawMaterialInfo from '@/components/KLPService/Renderer/RawMaterialInfo';
import { getGenerateRecord } from '@/api/wms/generateRecord';
import { addStockIoDetail } from '@/api/wms/stockIoDetail';

// 通用防抖高阶函数（可放在工具类中全局复用）
function debounce(fn, delay = 300) {
  let debounceTimer = null; // 闭包保存定时器，避免重复创建

  // 返回被包装后的函数（支持传递参数给业务函数）
  return function (...args) {
    // 1. 清除上一次未执行的定时器（核心：避免短时间内重复触发）
    if (debounceTimer) {
      clearTimeout(debounceTimer);
    }

    // 2. 延迟执行业务函数，this 绑定到调用者（适配 Vue 组件上下文）
    debounceTimer = setTimeout(() => {
      fn.apply(this, args); // 传递参数+保持this指向（Vue组件实例）
    }, delay);
  };
}

export default {
  data() {
    return {
      text: '',
      isLoading: false,
      isSubmitting: false,
      inputHint: '请输入二维码内容，系统将自动解析',
    };
  },
  components: {
    ProductInfo,
    RawMaterialInfo,
  },
  created() {
     // 包装“输入解析+提交”的业务函数，生成带防抖的版本
     this.debouncedHandleInput = debounce(
      this.actualParseAndSubmit, // 实际的业务逻辑函数
      500       // 防抖延迟时间
    );
  },
  computed: {
    result() {
      try {
        const text = JSON.parse(this.text)
        return text;
      } catch (error) {
        return {};
      }
    },
    // 验证数据是否有效
    isValid() {
      const requiredFields = ['ioType', 'itemType', 'itemId', 'quantity'];
      // 检查是否包含所有必要字段
      const hasAllFields = requiredFields.every(field => this.result.hasOwnProperty(field));
      // 检查出入库类型是否有效
      const isIoTypeValid = this.result.ioType === 'in' || this.result.ioType === 'out';
      // 检查物料类型是否有效
      const isItemTypeValid = ['product', 'semi', 'raw_material'].includes(this.result.itemType);
      // 检查数量是否为有效数字
      const isQuantityValid = !isNaN(Number(this.result.quantity)) && Number(this.result.quantity) > 0;

      return hasAllFields && isIoTypeValid && isItemTypeValid && isQuantityValid;
    }
  },
  methods: {
    handleInput(value) {
      const trimmedValue = value.trim();

      // 空值场景：立即反馈，不触发防抖逻辑
      if (!trimmedValue) {
        this.inputHint = "请输入二维码内容，系统将自动解析";
        return;
      }

      // 基础校验不通过：立即反馈，不触发防抖逻辑
      if (!this.isValid) {
        this.inputHint = "输入内容不符合基础格式要求，请检查";
        return;
      }

      // 触发防抖后的业务逻辑（此时已自动防抖）
      this.debouncedHandleInput(trimmedValue);
    },

    // 5. 实际的“JSON解析+提交”业务逻辑（纯业务，无防抖代码）
    async actualParseAndSubmit(validValue) {
      this.isLoading = true;
      try {
        // 1. 解析JSON
        const res = await getGenerateRecord(validValue);
        const parsedData = JSON.stringify(res.data.content);

        this.result = parsedData;
        // 3. 解析成功：反馈+提交
        this.inputHint = "数据解析成功，可以提交操作";
        this.$message.success({
          message: "数据解析成功",
          duration: 1500,
        });
        this.handleSubmit(parsedData); // 调用提交接口
      } catch (error) {
        // 6. 解析失败：错误处理
        this.inputHint = "无法解析数据，请确保输入的是有效的二维码内容";
        this.$message.error({
          message: "解析失败，请检查输入内容",
          duration: 2000,
        });
      } finally {
        // 7. 无论成功/失败，结束加载状态
        this.isLoading = false;
      }
    },

    handleBlur() {
      // 自动重新聚焦，方便连续扫描
      this.$nextTick(() => {
        this.$refs.textarea.focus();
      });
    },
    handleSubmit() {
      if (!this.isValid) return;

      this.isSubmitting = true;

      addStockIoDetail({
        ...this.result,
        recordType: 1, // recordType为1标识扫码录入
      })
        .then(res => {
          this.$message.success({
            message: '操作成功',
            duration: 2000
          });
        })
        .catch(err => {
          this.$message.error({
            message: '操作失败: ' + (err.message || '未知错误'),
            duration: 3000
          });
        })
        .finally(() => {
          this.isSubmitting = false;
          // 提交成功后重置表单，方便下一次操作
          this.handleReset();
        });
    },
    handleReset() {
      this.text = '';
      this.inputHint = '请输入二维码内容，系统将自动解析';
      // 重置后重新聚焦
      this.$nextTick(() => {
        this.$refs.textarea.focus();
      });
    },
    // 格式化物料类型显示文本
    formatItemType(type) {
      const typeMap = {
        'product': '成品',
        'semi': '半成品',
        'raw_material': '原材料'
      };
      return typeMap[type] || '未知类型';
    }
  },
  mounted() {
    // 确保组件挂载后自动聚焦
    this.$nextTick(() => {
      this.$refs.textarea.focus();
    });
  }
}
</script>

<style scoped>
.qr-parser-container {
  display: flex;
  justify-content: center;
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

.card {
  width: 100%;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

.card-header {
  padding: 20px 24px;
  border-bottom: 1px solid #e8e8e8;
}

.title {
  margin: 0;
  font-size: 20px;
  color: #1f2329;
  font-weight: 600;
}

.subtitle {
  margin: 5px 0 0;
  font-size: 14px;
  color: #6b7280;
}

.input-section {
  padding: 24px;
}

.el-input {
  transition: all 0.3s ease;
}

.el-input.invalid-input .el-textarea__inner {
  border-color: #f56c6c;
  box-shadow: 0 0 0 2px rgba(245, 108, 108, 0.2);
}

.input-hint {
  margin-top: 8px;
  font-size: 12px;
  color: #6b7280;
  display: flex;
  align-items: center;
}

.input-hint i {
  margin-right: 4px;
  font-size: 14px;
}

.result-section {
  padding: 0 24px 24px;
}

.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.result-header h3 {
  margin: 0;
  font-size: 16px;
  color: #1f2329;
  font-weight: 500;
}

.result-table {
  margin-bottom: 24px;
}

.action-buttons {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

/* 淡入动画 */
.fade-in {
  animation: fadeIn 0.5s ease-in-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
