// ============================================================
// MES 프로세스별 통합 테스트 시스템
// 각 프로세스별 5건씩 테스트 + 채번관리 검증
// ============================================================

import {
  generateDocNo,
  generateIncomingLotNo,
  generateProductionLotNo,
  resetAllSequences,
  masterData,
  calculateFullBOM,
  createMaterialReceipt,
  createWorkLogData,
  createInspectionData,
  processWorkflows,
} from './mesCompleteIntegration';

import {
  generateItemCode,
  generateLotNo,
  otherCodeRules,
  itemCodeRules,
} from '../configs/codeRuleConfig';

import {
  defaultNumberRules,
  generateNumberByRule,
  formatDateCode,
} from '../configs/numberRuleConfig';

// ============================================================
// 테스트 결과 저장소
// ============================================================
const testResults = {
  summary: {
    totalTests: 0,
    passedTests: 0,
    failedTests: 0,
    startTime: null,
    endTime: null,
  },
  processes: {},
  numberingValidation: [],
  errors: [],
};

// 테스트 로그
const log = (process, message, status = 'info', data = null) => {
  const entry = {
    timestamp: new Date().toISOString(),
    process,
    message,
    status,
    data,
  };
  console.log(`[${status.toUpperCase()}] [${process}] ${message}`);
  return entry;
};

// ============================================================
// 1. 기준정보 프로세스 테스트
// ============================================================
export const testMasterDataProcess = () => {
  const results = {
    processName: '기준정보',
    tests: [],
    passed: 0,
    failed: 0,
  };

  // 테스트 1: 거래처 코드 채번 테스트
  const customerTest = {
    name: '거래처 코드 채번 테스트',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const customerCode = `C-${String(i + 101).padStart(3, '0')}`;
    const customer = {
      id: Date.now() + i,
      customerCode,
      customerName: `테스트거래처_${i + 1}`,
      businessNo: `123-45-${String(67890 + i).padStart(5, '0')}`,
      status: '활성',
    };

    const isValid = customerCode.match(/^C-\d{3}$/);
    customerTest.items.push({
      seq: i + 1,
      code: customerCode,
      name: customer.customerName,
      pattern: 'C-###',
      valid: !!isValid,
    });

    if (!isValid) customerTest.passed = false;
  }
  results.tests.push(customerTest);
  customerTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: 현장 코드 채번 테스트
  const siteTest = {
    name: '현장 코드 채번 테스트 (PJ-YYMMDD-##)',
    items: [],
    passed: true,
  };

  const today = new Date();
  for (let i = 0; i < 5; i++) {
    const siteCode = generateDocNo('SITE', today);
    const site = {
      id: Date.now() + i,
      siteCode,
      siteName: `테스트현장_${i + 1}`,
      address: `서울시 강남구 테스트로 ${i + 1}`,
      status: '활성',
    };

    // PJ-YYMMDD-## 형식 검증
    const dateCode = formatDateCode(today, 'YYMMDD');
    const isValid = siteCode.includes('PJ-') && siteCode.includes(dateCode);
    siteTest.items.push({
      seq: i + 1,
      code: siteCode,
      name: site.siteName,
      expectedPattern: `PJ-${dateCode}-##`,
      valid: isValid,
    });

    if (!isValid) siteTest.passed = false;
  }
  results.tests.push(siteTest);
  siteTest.passed ? results.passed++ : results.failed++;

  // 테스트 3: 품목 코드 생성 테스트 (부자재)
  const itemCodeTest = {
    name: '품목 코드 생성 테스트 (부자재)',
    items: [],
    passed: true,
  };

  const subMaterialTests = [
    { itemName: '스크린원단', spec: '0.5T', expected: '스크린원단-0.5T' },
    { itemName: '연동제어기', spec: '매립(유선)', expected: '연동제어기-매립(유선)' },
    { itemName: '체인', spec: '#35', expected: '체인-#35' },
    { itemName: '스프링', spec: '중형', expected: '스프링-중형' },
    { itemName: '슬랫', spec: '75mm', expected: '슬랫-75mm' },
  ];

  subMaterialTests.forEach((test, i) => {
    const generated = generateItemCode('부자재', {
      subMaterialItemName: test.itemName,
      subMaterialSpec: test.spec,
    });
    const isValid = generated === test.expected;
    itemCodeTest.items.push({
      seq: i + 1,
      itemName: test.itemName,
      spec: test.spec,
      expected: test.expected,
      generated,
      valid: isValid,
    });
    if (!isValid) itemCodeTest.passed = false;
  });
  results.tests.push(itemCodeTest);
  itemCodeTest.passed ? results.passed++ : results.failed++;

  // 테스트 4: 품목 코드 생성 테스트 (절곡 부품)
  const bendingCodeTest = {
    name: '품목 코드 생성 테스트 (절곡 부품)',
    items: [],
    passed: true,
  };

  const bendingTests = [
    { itemName: '가이드레일(벽면형)', partType: '본체', length: '2438', expected: 'RM24' },
    { itemName: '케이스', partType: '전면부', length: '3000', expected: 'CF30' },
    { itemName: '가이드레일(측면형)', partType: 'SUS마감재①', length: '4000', expected: 'SS40' },
  ];

  bendingTests.forEach((test, i) => {
    const generated = generateItemCode('부품', {
      partSubType: '절곡 부품',
      bendingPartItemName: test.itemName,
      bendingPartType: test.partType,
      bendingSizeLength: test.length,
    });
    const isValid = generated === test.expected;
    bendingCodeTest.items.push({
      seq: i + 1,
      itemName: test.itemName,
      partType: test.partType,
      length: test.length,
      expected: test.expected,
      generated,
      valid: isValid,
    });
    if (!isValid) bendingCodeTest.passed = false;
  });
  results.tests.push(bendingCodeTest);
  bendingCodeTest.passed ? results.passed++ : results.failed++;

  // 테스트 5: 채번 규칙 목록 검증
  const numberingRuleTest = {
    name: '채번 규칙 설정 검증',
    items: [],
    passed: true,
  };

  const requiredRules = [
    { target: '견적번호', expectedPrefix: 'KD-PR' },
    { target: '수주번호(스크린)', expectedPrefix: 'KD-TS' },
    { target: '수주번호(슬랫)', expectedPrefix: 'KD-SL' },
    { target: '작업지시번호', expectedPrefix: 'KD-WO' },
    { target: '출하번호', expectedPrefix: 'KD-SH' },
  ];

  requiredRules.forEach((req, i) => {
    const rule = defaultNumberRules.find(r => r.target === req.target);
    const isValid = rule && rule.prefix === req.expectedPrefix;
    numberingRuleTest.items.push({
      seq: i + 1,
      target: req.target,
      expectedPrefix: req.expectedPrefix,
      actualPrefix: rule?.prefix || 'NOT FOUND',
      valid: isValid,
    });
    if (!isValid) numberingRuleTest.passed = false;
  });
  results.tests.push(numberingRuleTest);
  numberingRuleTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 2. 견적 프로세스 테스트
// ============================================================
export const testQuoteProcess = () => {
  const results = {
    processName: '견적',
    tests: [],
    passed: 0,
    failed: 0,
  };

  const today = new Date();

  // 테스트 1: 견적번호 채번 테스트 (KD-PR-YYMMDD-##)
  const quoteNumberTest = {
    name: '견적번호 채번 테스트 (KD-PR-YYMMDD-##)',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const quoteNo = generateDocNo('QT', today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const expectedPattern = new RegExp(`^KD-PR-${dateCode}-\\d{2}$`);
    const isValid = expectedPattern.test(quoteNo);

    quoteNumberTest.items.push({
      seq: i + 1,
      quoteNo,
      expectedPattern: `KD-PR-${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) quoteNumberTest.passed = false;
  }
  results.tests.push(quoteNumberTest);
  quoteNumberTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: BOM 자동계산 테스트
  const bomTest = {
    name: 'BOM 자동계산 테스트',
    items: [],
    passed: true,
  };

  const sizeTests = [
    { W: 3000, H: 3000, productType: '스크린' },
    { W: 3500, H: 4000, productType: '스크린' },
    { W: 2500, H: 3000, productType: '철재' },
    { W: 4000, H: 4500, productType: '스크린' },
    { W: 5000, H: 5000, productType: '철재' },
  ];

  sizeTests.forEach((test, i) => {
    const bom = calculateFullBOM({
      openWidth: test.W,
      openHeight: test.H,
      productType: test.productType,
      qty: 1,
    });

    const hasItems = bom.items && bom.items.length > 0;
    const hasTotal = bom.summary && bom.summary.totalAmount > 0;
    const hasVariables = bom.variables && bom.variables.W1 && bom.variables.H1;
    const isValid = hasItems && hasTotal && hasVariables;

    bomTest.items.push({
      seq: i + 1,
      input: `W${test.W}×H${test.H} (${test.productType})`,
      itemCount: bom.items?.length || 0,
      totalAmount: bom.summary?.totalAmount || 0,
      W1: bom.variables?.W1,
      H1: bom.variables?.H1,
      valid: isValid,
    });
    if (!isValid) bomTest.passed = false;
  });
  results.tests.push(bomTest);
  bomTest.passed ? results.passed++ : results.failed++;

  // 테스트 3: 견적서 전체 데이터 생성 테스트
  const quoteDataTest = {
    name: '견적서 전체 데이터 생성 테스트',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const customer = masterData.customers[i];
    const site = masterData.sites[i];
    const quoteNo = generateDocNo('QT', today);
    const bom = calculateFullBOM({
      openWidth: 3000 + (i * 500),
      openHeight: 3000 + (i * 300),
      productType: i % 2 === 0 ? '스크린' : '철재',
      qty: i + 1,
    });

    const quote = {
      id: Date.now() + i,
      quoteNo,
      quoteDate: today.toISOString().split('T')[0],
      customerId: customer.id,
      customerName: customer.customerName,
      siteId: site.id,
      siteName: site.siteName,
      productName: `방화셔터 W${3000 + (i * 500)}×H${3000 + (i * 300)}`,
      qty: i + 1,
      items: bom.items,
      totalAmount: bom.summary.grandTotal,
      status: '견적완료',
    };

    const hasQuoteNo = quote.quoteNo && quote.quoteNo.includes('KD-PR');
    const hasCustomer = quote.customerId && quote.customerName;
    const hasSite = quote.siteId && quote.siteName;
    const hasAmount = quote.totalAmount > 0;
    const isValid = hasQuoteNo && hasCustomer && hasSite && hasAmount;

    quoteDataTest.items.push({
      seq: i + 1,
      quoteNo: quote.quoteNo,
      customer: quote.customerName,
      site: quote.siteName,
      amount: quote.totalAmount,
      valid: isValid,
    });
    if (!isValid) quoteDataTest.passed = false;
  }
  results.tests.push(quoteDataTest);
  quoteDataTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 3. 수주/생산지시 프로세스 테스트
// ============================================================
export const testOrderProcess = () => {
  const results = {
    processName: '수주/생산지시',
    tests: [],
    passed: 0,
    failed: 0,
  };

  const today = new Date();

  // 테스트 1: 수주번호 채번 테스트 (스크린: KD-TS, 슬랫: KD-SL, 절곡: KD-BD)
  const orderNumberTest = {
    name: '수주번호 채번 테스트 (제품유형별)',
    items: [],
    passed: true,
  };

  const orderTypes = [
    { type: 'SO-SCR', productType: '스크린', expectedPrefix: 'KD-TS' },
    { type: 'SO-SLT', productType: '슬랫', expectedPrefix: 'KD-SL' },
    { type: 'SO-BD', productType: '절곡', expectedPrefix: 'KD-BD' },
    { type: 'SO', productType: '스크린(기본)', expectedPrefix: 'KD-TS' },
    { type: 'SO-SCR', productType: '스크린2', expectedPrefix: 'KD-TS' },
  ];

  orderTypes.forEach((test, i) => {
    const orderNo = generateDocNo(test.type, today);
    const isValid = orderNo.includes(test.expectedPrefix);

    orderNumberTest.items.push({
      seq: i + 1,
      productType: test.productType,
      orderNo,
      expectedPrefix: test.expectedPrefix,
      valid: isValid,
    });
    if (!isValid) orderNumberTest.passed = false;
  });
  results.tests.push(orderNumberTest);
  orderNumberTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: 작업지시번호 채번 테스트 (KD-WO-YYMMDD-##)
  const workOrderNumberTest = {
    name: '작업지시번호 채번 테스트 (KD-WO-YYMMDD-##)',
    items: [],
    passed: true,
  };

  const woTypes = ['WO', 'WO-SCR', 'WO-SLT', 'WO-FLD', 'WO'];

  woTypes.forEach((type, i) => {
    const woNo = generateDocNo(type, today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const isValid = woNo.includes('KD-WO') && woNo.includes(dateCode);

    workOrderNumberTest.items.push({
      seq: i + 1,
      type,
      workOrderNo: woNo,
      expectedPattern: `KD-WO-${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) workOrderNumberTest.passed = false;
  });
  results.tests.push(workOrderNumberTest);
  workOrderNumberTest.passed ? results.passed++ : results.failed++;

  // 테스트 3: 생산LOT 채번 테스트 (KD-PL-YYMMDD-##)
  const productionLotTest = {
    name: '생산LOT 채번 테스트 (KD-PL-YYMMDD-##)',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const lotNo = generateDocNo('PL', today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const isValid = lotNo.includes('KD-PL') && lotNo.includes(dateCode);

    productionLotTest.items.push({
      seq: i + 1,
      lotNo,
      expectedPattern: `KD-PL-${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) productionLotTest.passed = false;
  }
  results.tests.push(productionLotTest);
  productionLotTest.passed ? results.passed++ : results.failed++;

  // 테스트 4: 수주→생산지시 연결 테스트
  const orderToWoTest = {
    name: '수주→생산지시 연결 테스트',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const orderNo = generateDocNo('SO', today);
    const workOrders = [];

    // 각 수주에 대해 공정별 작업지시 생성
    ['스크린', '절곡'].forEach((processType, j) => {
      const config = processWorkflows[processType];
      if (config) {
        workOrders.push({
          workOrderNo: generateDocNo(config.docType, today),
          processType,
          orderNo,
        });
      }
    });

    const hasWorkOrders = workOrders.length > 0;
    const allLinked = workOrders.every(wo => wo.orderNo === orderNo);
    const isValid = hasWorkOrders && allLinked;

    orderToWoTest.items.push({
      seq: i + 1,
      orderNo,
      workOrderCount: workOrders.length,
      workOrderNos: workOrders.map(wo => wo.workOrderNo).join(', '),
      valid: isValid,
    });
    if (!isValid) orderToWoTest.passed = false;
  }
  results.tests.push(orderToWoTest);
  orderToWoTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 4. 자재입고(입고LOT) 프로세스 테스트
// ============================================================
export const testMaterialReceiptProcess = () => {
  const results = {
    processName: '자재입고(입고LOT)',
    tests: [],
    passed: 0,
    failed: 0,
  };

  const today = new Date();

  // 테스트 1: 입고LOT 채번 테스트 (YYMMDD-##)
  const incomingLotTest = {
    name: '입고LOT 채번 테스트 (YYMMDD-##)',
    items: [],
    passed: true,
  };

  const materialTypes = ['원자재', '부자재', '소모품', '원자재', '부자재'];

  materialTypes.forEach((type, i) => {
    const lotNo = generateIncomingLotNo(type, today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const expectedPattern = new RegExp(`^${dateCode}-\\d{2}$`);
    const isValid = expectedPattern.test(lotNo);

    incomingLotTest.items.push({
      seq: i + 1,
      materialType: type,
      lotNo,
      expectedPattern: `${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) incomingLotTest.passed = false;
  });
  results.tests.push(incomingLotTest);
  incomingLotTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: 입고전표 생성 테스트
  const receiptTest = {
    name: '입고전표 생성 테스트',
    items: [],
    passed: true,
  };

  const materials = masterData.rawMaterials.slice(0, 5);

  materials.forEach((material, i) => {
    const receipt = createMaterialReceipt(material, 100 + (i * 50));

    const hasLotNo = receipt.lotNo && receipt.lotNo.match(/^\d{6}-\d{2}$/);
    const hasReceiptNo = receipt.receiptNo;
    const hasQty = receipt.qty > 0;
    const isValid = hasLotNo && hasReceiptNo && hasQty;

    receiptTest.items.push({
      seq: i + 1,
      itemCode: material.itemCode,
      itemName: material.itemName,
      lotNo: receipt.lotNo,
      receiptNo: receipt.receiptNo,
      qty: receipt.qty,
      valid: isValid,
    });
    if (!isValid) receiptTest.passed = false;
  });
  results.tests.push(receiptTest);
  receiptTest.passed ? results.passed++ : results.failed++;

  // 테스트 3: 입고검사LOT 채번 테스트
  const iqcLotTest = {
    name: '입고검사(IQC) LOT 채번 테스트',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const iqcNo = generateDocNo('IQC', today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const isValid = iqcNo.includes('KD-QC') && iqcNo.includes(dateCode);

    iqcLotTest.items.push({
      seq: i + 1,
      iqcNo,
      expectedPattern: `KD-QC-${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) iqcLotTest.passed = false;
  }
  results.tests.push(iqcLotTest);
  iqcLotTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 5. 작업진행 프로세스 테스트
// ============================================================
export const testWorkProgressProcess = () => {
  const results = {
    processName: '작업진행',
    tests: [],
    passed: 0,
    failed: 0,
  };

  const today = new Date();

  // 테스트 1: 작업일지 번호 채번 테스트
  const workLogTest = {
    name: '작업일지 번호 채번 테스트',
    items: [],
    passed: true,
  };

  const workLogTypes = ['WL-SCR', 'WL-SLT', 'WL-FLD', 'WL-STK', 'WL-SCR'];

  workLogTypes.forEach((type, i) => {
    const wlNo = generateDocNo(type, today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    // WL-STK는 고유 패턴 사용, 나머지는 KD-WO 패턴
    const expectedPrefix = type === 'WL-STK' ? 'WL-STK-' : 'KD-WO-';
    const isValid = wlNo.includes(expectedPrefix) && wlNo.includes(dateCode);

    workLogTest.items.push({
      seq: i + 1,
      type,
      workLogNo: wlNo,
      expectedPattern: `${expectedPrefix}${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) workLogTest.passed = false;
  });
  results.tests.push(workLogTest);
  workLogTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: 작업일지 데이터 생성 테스트
  const workLogDataTest = {
    name: '작업일지 데이터 생성 테스트',
    items: [],
    passed: true,
  };

  const processTypes = ['스크린', '슬랫', '절곡', '재고생산', '스크린'];

  processTypes.forEach((processType, i) => {
    const mockWorkOrder = {
      id: Date.now() + i,
      workOrderNo: generateDocNo('WO', today),
      processType,
      productName: `테스트제품_${i + 1}`,
      productSpec: `W3000×H3000`,
      totalQty: 5 + i,
      lotNo: `LOT-TEST-${i + 1}`,
    };

    const workLog = createWorkLogData(mockWorkOrder, {
      completedQty: mockWorkOrder.totalQty,
      defectQty: 0,
      steps: {},
    });

    const hasWorkLogNo = workLog.workLogNo && workLog.workLogNo.includes('KD-WO');
    const hasSteps = workLog.stepResults && workLog.stepResults.length > 0;
    const hasLinkedWO = workLog.workOrderNo === mockWorkOrder.workOrderNo;
    const isValid = hasWorkLogNo && hasSteps && hasLinkedWO;

    workLogDataTest.items.push({
      seq: i + 1,
      processType,
      workLogNo: workLog.workLogNo,
      workOrderNo: workLog.workOrderNo,
      stepCount: workLog.stepResults?.length || 0,
      valid: isValid,
    });
    if (!isValid) workLogDataTest.passed = false;
  });
  results.tests.push(workLogDataTest);
  workLogDataTest.passed ? results.passed++ : results.failed++;

  // 테스트 3: 공정별 단계 검증
  const processStepTest = {
    name: '공정별 작업단계 검증',
    items: [],
    passed: true,
  };

  Object.entries(processWorkflows).forEach(([key, workflow], i) => {
    if (i >= 5) return;

    const hasSteps = workflow.steps && workflow.steps.length > 0;
    const hasQcStep = workflow.steps?.some(s => s.isQC);
    const hasTeam = workflow.team;
    const isValid = hasSteps && hasTeam;

    processStepTest.items.push({
      seq: i + 1,
      processCode: workflow.code,
      processName: workflow.name,
      stepCount: workflow.steps?.length || 0,
      hasQcStep,
      team: workflow.team,
      valid: isValid,
    });
    if (!isValid) processStepTest.passed = false;
  });
  results.tests.push(processStepTest);
  processStepTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 6. 중간검사(PQC) 프로세스 테스트
// ============================================================
export const testPQCProcess = () => {
  const results = {
    processName: '중간검사(PQC)',
    tests: [],
    passed: 0,
    failed: 0,
  };

  const today = new Date();

  // 테스트 1: 중간검사LOT 채번 테스트 (KD-WE-YYMMDD-##)
  const pqcLotTest = {
    name: '중간검사LOT 채번 테스트 (KD-WE-YYMMDD-##)',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const pqcNo = generateDocNo('PQC', today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const isValid = pqcNo.includes('KD-WE') && pqcNo.includes(dateCode);

    pqcLotTest.items.push({
      seq: i + 1,
      pqcNo,
      expectedPattern: `KD-WE-${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) pqcLotTest.passed = false;
  }
  results.tests.push(pqcLotTest);
  pqcLotTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: 검사 데이터 생성 테스트
  const inspectionDataTest = {
    name: 'PQC 검사 데이터 생성 테스트',
    items: [],
    passed: true,
  };

  const processTypes = ['스크린', '슬랫', '절곡', '스크린', '절곡'];

  processTypes.forEach((processType, i) => {
    const mockWorkOrder = {
      id: Date.now() + i,
      workOrderNo: generateDocNo('WO', today),
      processType,
      productName: `테스트제품_${i + 1}`,
      productSpec: `W${3000 + i * 200}×H${3000 + i * 100}`,
      totalQty: 5,
      lotNo: `LOT-TEST-${i + 1}`,
    };

    const inspection = createInspectionData(mockWorkOrder, 'PQC', {
      passQty: 5,
      failQty: 0,
      result: '합격',
      inspector: '테스트검사원',
    });

    const hasInspectionNo = inspection.inspectionNo && inspection.inspectionNo.includes('KD-WE');
    const hasCheckItems = inspection.checkItems && inspection.checkItems.length > 0;
    const hasLinkedWO = inspection.workOrderNo === mockWorkOrder.workOrderNo;
    const isValid = hasInspectionNo && hasCheckItems && hasLinkedWO;

    inspectionDataTest.items.push({
      seq: i + 1,
      processType,
      inspectionNo: inspection.inspectionNo,
      workOrderNo: inspection.workOrderNo,
      checkItemCount: inspection.checkItems?.length || 0,
      result: inspection.result,
      valid: isValid,
    });
    if (!isValid) inspectionDataTest.passed = false;
  });
  results.tests.push(inspectionDataTest);
  inspectionDataTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 7. 출하(SL)/입금확인 프로세스 테스트
// ============================================================
export const testShipmentProcess = () => {
  const results = {
    processName: '출하(SL)/입금확인',
    tests: [],
    passed: 0,
    failed: 0,
  };

  const today = new Date();

  // 테스트 1: 출하번호 채번 테스트 (KD-SH-YYMMDD-##)
  const shipmentNumberTest = {
    name: '출하번호 채번 테스트 (KD-SH-YYMMDD-##)',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const shipmentNo = generateDocNo('SL', today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const isValid = shipmentNo.includes('KD-SH') && shipmentNo.includes(dateCode);

    shipmentNumberTest.items.push({
      seq: i + 1,
      shipmentNo,
      expectedPattern: `KD-SH-${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) shipmentNumberTest.passed = false;
  }
  results.tests.push(shipmentNumberTest);
  shipmentNumberTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: 출고번호 채번 테스트 (YYMMDD-P-##)
  const outboundNumberTest = {
    name: '출고번호 채번 테스트 (YYMMDD-P-##)',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const outNo = generateDocNo('OUT', today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    // 출고번호는 P- 패턴
    const isValid = outNo.includes('P-') && outNo.includes(dateCode);

    outboundNumberTest.items.push({
      seq: i + 1,
      outboundNo: outNo,
      expectedPattern: `${dateCode}-P-##`,
      valid: isValid,
    });
    if (!isValid) outboundNumberTest.passed = false;
  }
  results.tests.push(outboundNumberTest);
  outboundNumberTest.passed ? results.passed++ : results.failed++;

  // 테스트 3: 입금확인 데이터 테스트
  const depositTest = {
    name: '입금확인 데이터 테스트',
    items: [],
    passed: true,
  };

  const orderAmounts = [5000000, 8000000, 12000000, 3500000, 9500000];

  orderAmounts.forEach((amount, i) => {
    const depositAmount = Math.floor(amount * 0.3); // 계약금 30%
    const remainingAmount = amount - depositAmount;
    const depositNo = generateDocNo('DEP', today);

    const isValid = depositAmount > 0 && remainingAmount > 0 && depositNo;

    depositTest.items.push({
      seq: i + 1,
      orderAmount: amount,
      depositAmount,
      remainingAmount,
      depositNo,
      valid: isValid,
    });
    if (!isValid) depositTest.passed = false;
  });
  results.tests.push(depositTest);
  depositTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 8. 최종검사(FQC)/매출확정 프로세스 테스트
// ============================================================
export const testFQCAndSalesProcess = () => {
  const results = {
    processName: '최종검사(FQC)/매출확정',
    tests: [],
    passed: 0,
    failed: 0,
  };

  const today = new Date();

  // 테스트 1: 최종검사LOT 채번 테스트 (KD-SA-YYMMDD-##)
  const fqcLotTest = {
    name: '최종검사LOT 채번 테스트 (KD-SA-YYMMDD-##)',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const fqcNo = generateDocNo('FQC', today);
    const dateCode = formatDateCode(today, 'YYMMDD');
    const isValid = fqcNo.includes('KD-SA') && fqcNo.includes(dateCode);

    fqcLotTest.items.push({
      seq: i + 1,
      fqcNo,
      expectedPattern: `KD-SA-${dateCode}-##`,
      valid: isValid,
    });
    if (!isValid) fqcLotTest.passed = false;
  }
  results.tests.push(fqcLotTest);
  fqcLotTest.passed ? results.passed++ : results.failed++;

  // 테스트 2: 최종검사 데이터 생성 테스트
  const fqcDataTest = {
    name: '최종검사(FQC) 데이터 생성 테스트',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const mockWorkOrder = {
      id: Date.now() + i,
      workOrderNo: generateDocNo('WO', today),
      processType: '스크린',
      productName: `테스트제품_${i + 1}`,
      productSpec: `W${3000 + i * 200}×H${3000 + i * 100}`,
      totalQty: 5,
      lotNo: `LOT-TEST-${i + 1}`,
    };

    const inspection = createInspectionData(mockWorkOrder, 'FQC', {
      passQty: 5,
      failQty: 0,
      result: '합격',
      inspector: '테스트검사원',
    });

    const hasInspectionNo = inspection.inspectionNo && inspection.inspectionNo.includes('KD-SA');
    const hasCheckItems = inspection.checkItems && inspection.checkItems.length > 0;
    const hasFQCSpecificItems = inspection.checkItems?.some(
      item => item.code?.includes('FQC') || item.name?.includes('동작')
    );
    const isValid = hasInspectionNo && hasCheckItems;

    fqcDataTest.items.push({
      seq: i + 1,
      inspectionNo: inspection.inspectionNo,
      workOrderNo: inspection.workOrderNo,
      checkItemCount: inspection.checkItems?.length || 0,
      hasFQCItems: hasFQCSpecificItems,
      result: inspection.result,
      valid: isValid,
    });
    if (!isValid) fqcDataTest.passed = false;
  }
  results.tests.push(fqcDataTest);
  fqcDataTest.passed ? results.passed++ : results.failed++;

  // 테스트 3: 매출확정 데이터 테스트
  const salesTest = {
    name: '매출확정 데이터 테스트',
    items: [],
    passed: true,
  };

  for (let i = 0; i < 5; i++) {
    const totalAmount = (5000000 + i * 1000000);
    const depositAmount = Math.floor(totalAmount * 0.3);
    const remainingAmount = totalAmount - depositAmount;
    const salesNo = generateDocNo('INV', today);

    const sales = {
      id: Date.now() + i,
      salesNo,
      salesDate: today.toISOString().split('T')[0],
      totalAmount,
      depositAmount,
      remainingAmount,
      status: '청구완료',
    };

    const hasSalesNo = sales.salesNo;
    const hasCorrectAmounts = sales.totalAmount === sales.depositAmount + sales.remainingAmount;
    const isValid = hasSalesNo && hasCorrectAmounts;

    salesTest.items.push({
      seq: i + 1,
      salesNo: sales.salesNo,
      totalAmount: sales.totalAmount,
      depositAmount: sales.depositAmount,
      remainingAmount: sales.remainingAmount,
      amountValid: hasCorrectAmounts,
      valid: isValid,
    });
    if (!isValid) salesTest.passed = false;
  }
  results.tests.push(salesTest);
  salesTest.passed ? results.passed++ : results.failed++;

  return results;
};

// ============================================================
// 전체 프로세스 통합 테스트 실행
// ============================================================
export const runAllProcessTests = () => {
  // 시퀀스 초기화
  resetAllSequences();

  const startTime = new Date();

  console.log('═══════════════════════════════════════════════════════════════');
  console.log('  MES 프로세스별 통합 테스트 시작');
  console.log('  각 프로세스별 5건씩 테스트 + 채번관리 검증');
  console.log('═══════════════════════════════════════════════════════════════');

  const allResults = {
    summary: {
      totalProcesses: 0,
      totalTests: 0,
      passedTests: 0,
      failedTests: 0,
      startTime: startTime.toISOString(),
      endTime: null,
    },
    processes: [],
    numberingValidation: {
      passed: [],
      failed: [],
    },
  };

  // 1. 기준정보 테스트
  console.log('\n[1/8] 기준정보 프로세스 테스트...');
  const masterResult = testMasterDataProcess();
  allResults.processes.push(masterResult);

  // 2. 견적 테스트
  console.log('[2/8] 견적 프로세스 테스트...');
  const quoteResult = testQuoteProcess();
  allResults.processes.push(quoteResult);

  // 3. 수주/생산지시 테스트
  console.log('[3/8] 수주/생산지시 프로세스 테스트...');
  const orderResult = testOrderProcess();
  allResults.processes.push(orderResult);

  // 4. 자재입고 테스트
  console.log('[4/8] 자재입고(입고LOT) 프로세스 테스트...');
  const materialResult = testMaterialReceiptProcess();
  allResults.processes.push(materialResult);

  // 5. 작업진행 테스트
  console.log('[5/8] 작업진행 프로세스 테스트...');
  const workProgressResult = testWorkProgressProcess();
  allResults.processes.push(workProgressResult);

  // 6. 중간검사 테스트
  console.log('[6/8] 중간검사(PQC) 프로세스 테스트...');
  const pqcResult = testPQCProcess();
  allResults.processes.push(pqcResult);

  // 7. 출하/입금 테스트
  console.log('[7/8] 출하(SL)/입금확인 프로세스 테스트...');
  const shipmentResult = testShipmentProcess();
  allResults.processes.push(shipmentResult);

  // 8. 최종검사/매출확정 테스트
  console.log('[8/8] 최종검사(FQC)/매출확정 프로세스 테스트...');
  const fqcResult = testFQCAndSalesProcess();
  allResults.processes.push(fqcResult);

  // 결과 집계
  allResults.processes.forEach(process => {
    allResults.summary.totalProcesses++;
    process.tests.forEach(test => {
      allResults.summary.totalTests++;
      if (test.passed) {
        allResults.summary.passedTests++;
      } else {
        allResults.summary.failedTests++;
      }
    });
  });

  const endTime = new Date();
  allResults.summary.endTime = endTime.toISOString();
  allResults.summary.duration = `${(endTime - startTime)}ms`;

  console.log('\n═══════════════════════════════════════════════════════════════');
  console.log('  테스트 결과 요약');
  console.log('═══════════════════════════════════════════════════════════════');
  console.log(`  총 프로세스: ${allResults.summary.totalProcesses}개`);
  console.log(`  총 테스트: ${allResults.summary.totalTests}건`);
  console.log(`  성공: ${allResults.summary.passedTests}건`);
  console.log(`  실패: ${allResults.summary.failedTests}건`);
  console.log(`  성공률: ${((allResults.summary.passedTests / allResults.summary.totalTests) * 100).toFixed(1)}%`);
  console.log(`  소요시간: ${allResults.summary.duration}`);

  return allResults;
};

// ============================================================
// 채번관리 종합 검증
// ============================================================
export const validateNumberingRules = () => {
  const today = new Date();
  const dateCode = formatDateCode(today, 'YYMMDD');

  const validations = [
    { target: '견적번호', prefix: 'KD-PR', generator: () => generateDocNo('QT', today) },
    { target: '수주번호(스크린)', prefix: 'KD-TS', generator: () => generateDocNo('SO-SCR', today) },
    { target: '수주번호(슬랫)', prefix: 'KD-SL', generator: () => generateDocNo('SO-SLT', today) },
    { target: '수주번호(절곡)', prefix: 'KD-BD', generator: () => generateDocNo('SO-BD', today) },
    { target: '작업지시번호', prefix: 'KD-WO', generator: () => generateDocNo('WO', today) },
    { target: '중간검사LOT', prefix: 'KD-WE', generator: () => generateDocNo('PQC', today) },
    { target: '최종검사LOT', prefix: 'KD-SA', generator: () => generateDocNo('FQC', today) },
    { target: '출하번호', prefix: 'KD-SH', generator: () => generateDocNo('SL', today) },
    { target: '현장코드', prefix: 'PJ', generator: () => generateDocNo('SITE', today) },
    { target: '생산LOT', prefix: 'KD-PL', generator: () => generateDocNo('PL', today) },
    { target: '입고검사LOT', prefix: '', generator: () => generateIncomingLotNo('원자재', today) },
  ];

  const results = {
    date: today.toISOString().split('T')[0],
    dateCode,
    validations: [],
    summary: {
      total: validations.length,
      passed: 0,
      failed: 0,
    },
  };

  validations.forEach(v => {
    const generated = v.generator();
    const expectedPattern = v.prefix
      ? `${v.prefix}-${dateCode}-##`
      : `${dateCode}-##`;
    const isValid = v.prefix
      ? generated.includes(v.prefix) && generated.includes(dateCode)
      : generated.includes(dateCode);

    results.validations.push({
      target: v.target,
      expectedPrefix: v.prefix || '(없음)',
      expectedPattern,
      generated,
      valid: isValid,
    });

    if (isValid) {
      results.summary.passed++;
    } else {
      results.summary.failed++;
    }
  });

  return results;
};

export default {
  testMasterDataProcess,
  testQuoteProcess,
  testOrderProcess,
  testMaterialReceiptProcess,
  testWorkProgressProcess,
  testPQCProcess,
  testShipmentProcess,
  testFQCAndSalesProcess,
  runAllProcessTests,
  validateNumberingRules,
};
