/**
 * MES 시스템 통합테스트 스크립트
 * 방화셔터 제조 MVP 기준
 *
 * 실행: node test-integration.js
 */

const fs = require('fs');
const path = require('path');

// 색상 코드
const colors = {
  reset: '\x1b[0m',
  green: '\x1b[32m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m',
  bold: '\x1b[1m'
};

// 테스트 결과 저장
const testResults = {
  passed: 0,
  failed: 0,
  warnings: 0,
  details: []
};

// 유틸리티 함수
function log(message, type = 'info') {
  const prefix = {
    pass: `${colors.green}[PASS]${colors.reset}`,
    fail: `${colors.red}[FAIL]${colors.reset}`,
    warn: `${colors.yellow}[WARN]${colors.reset}`,
    info: `${colors.blue}[INFO]${colors.reset}`,
    test: `${colors.cyan}[TEST]${colors.reset}`
  };
  console.log(`${prefix[type] || prefix.info} ${message}`);
}

function section(title) {
  console.log(`\n${colors.bold}${'='.repeat(60)}${colors.reset}`);
  console.log(`${colors.bold}${colors.cyan} ${title}${colors.reset}`);
  console.log(`${colors.bold}${'='.repeat(60)}${colors.reset}\n`);
}

function subsection(title) {
  console.log(`\n${colors.yellow}--- ${title} ---${colors.reset}\n`);
}

// 테스트 실행 함수
function test(description, condition, details = '') {
  if (condition) {
    testResults.passed++;
    testResults.details.push({ status: 'pass', description, details });
    log(`${description}`, 'pass');
  } else {
    testResults.failed++;
    testResults.details.push({ status: 'fail', description, details });
    log(`${description} ${details ? `- ${details}` : ''}`, 'fail');
  }
}

function warn(description, details = '') {
  testResults.warnings++;
  testResults.details.push({ status: 'warn', description, details });
  log(`${description} ${details ? `- ${details}` : ''}`, 'warn');
}

// ============================================================
// 1. 파일 구조 테스트
// ============================================================
function testFileStructure() {
  section('1. 파일 구조 테스트');

  const requiredFiles = [
    'src/App.jsx',
    'src/index.js',
    'src/configs/index.js',
    'src/configs/menuDefinitions.js',
    'src/configs/itemMasterConfig.js',
    'src/configs/processMasterConfig.js',
    'src/configs/inspectionMasterConfig.js',
    'src/configs/customerMasterConfig.js',
    'src/configs/siteMasterConfig.js',
    'src/configs/orderMasterConfig.js',
    'src/configs/documentTemplateConfig.js',
    'src/configs/commonSchema.js',
    'package.json'
  ];

  requiredFiles.forEach(file => {
    const filePath = path.join(__dirname, file);
    test(`파일 존재: ${file}`, fs.existsSync(filePath));
  });
}

// ============================================================
// 2. 메뉴 정의 테스트
// ============================================================
function testMenuDefinitions() {
  section('2. 메뉴 정의 테스트');

  const menuPath = path.join(__dirname, 'src/configs/menuDefinitions.js');
  const menuContent = fs.readFileSync(menuPath, 'utf-8');

  subsection('2.1 메뉴 그룹 검증');
  const menuGroups = ['masterMenus', 'salesMenus', 'logisticsMenus', 'productionMenus',
                       'qualityMenus', 'inventoryMenus', 'accountingMenus', 'systemMenus'];
  menuGroups.forEach(group => {
    test(`메뉴 그룹 정의: ${group}`, menuContent.includes(`export const ${group}`));
  });

  subsection('2.2 MVP 생산관리 메뉴 (5개)');
  const mvpProductionMenus = ['품목관리', '생산 현황판', '작업지시 관리', '작업실적', '작업자 화면'];
  mvpProductionMenus.forEach(menu => {
    test(`생산관리 메뉴: ${menu}`, menuContent.includes(menu));
  });

  // 제거된 메뉴 확인
  const removedMenus = ['BOM관리', '생산계획', '자재소요계획(MRP)', '생산입고'];
  removedMenus.forEach(menu => {
    const removed = !menuContent.includes(menu);
    test(`MVP에서 제거됨: ${menu}`, removed, removed ? '' : '아직 메뉴에 존재함');
  });

  subsection('2.3 MVP 자재관리 메뉴 (2개)');
  const mvpInventoryMenus = ['재고현황', '입고관리'];
  mvpInventoryMenus.forEach(menu => {
    test(`자재관리 메뉴: ${menu}`, menuContent.includes(menu));
  });

  // 제거된 자재 메뉴 확인
  const removedInventoryMenus = ['자재불출', '구매요청', '재고조정', 'LOT추적'];
  removedInventoryMenus.forEach(menu => {
    const removed = !menuContent.includes(menu);
    test(`MVP에서 제거됨: ${menu}`, removed, removed ? '' : '아직 메뉴에 존재함');
  });
}

// ============================================================
// 3. Config 파일 테스트
// ============================================================
function testConfigFiles() {
  section('3. Config 파일 테스트');

  subsection('3.1 processMasterConfig (공정기준관리)');
  const processConfig = fs.readFileSync(
    path.join(__dirname, 'src/configs/processMasterConfig.js'), 'utf-8'
  );

  // 방화셔터 공정 카테고리
  test('공정 카테고리: 스크린', processConfig.includes("'스크린'"));
  test('공정 카테고리: 절곡', processConfig.includes("'절곡'"));
  test('공정 카테고리: 슬랫', processConfig.includes("'슬랫'"));
  test('공정 카테고리: 재고', processConfig.includes("'재고'"));
  test('공정 카테고리: 포장', processConfig.includes("'포장'"));

  // 제거된 필드 확인
  test('stdTime 제거됨', !processConfig.includes('stdTime'));
  test('setupTime 제거됨', !processConfig.includes('setupTime'));

  // dataSource 연결 확인
  test('담당부서 dataSource 연결', processConfig.includes("target: 'departments'"));
  test('작업일지 dataSource 연결', processConfig.includes("target: 'documentTemplates'"));

  subsection('3.2 orderMasterConfig (수주기준관리)');
  const orderConfig = fs.readFileSync(
    path.join(__dirname, 'src/configs/orderMasterConfig.js'), 'utf-8'
  );

  // 수주 유형 (실제 config에 정의된 값 기준)
  test('수주유형: 일반수주', orderConfig.includes("'일반수주'"));
  test('수주유형: 추가수주', orderConfig.includes("'추가수주'"));
  test('수주유형: 직접수주', orderConfig.includes("'직접수주'"));

  // 제품 카테고리 (품목명 기준)
  test('제품분류: 방화셔터', orderConfig.includes("'방화셔터'"));
  test('제품분류: 방연셔터', orderConfig.includes("'방연셔터'"));
  test('제품분류: 국민방화스크린셔터', orderConfig.includes("'국민방화스크린셔터'"));

  // 생산공정 카테고리
  test('카테고리: 스크린', orderConfig.includes("code: 'SCREEN'"));
  test('카테고리: 절곡', orderConfig.includes("code: 'FOLD'"));
  test('카테고리: 슬랫', orderConfig.includes("code: 'SLAT'"));

  subsection('3.3 configs/index.js 내보내기');
  const indexConfig = fs.readFileSync(
    path.join(__dirname, 'src/configs/index.js'), 'utf-8'
  );

  const configExports = [
    'itemMasterConfig', 'processMasterConfig', 'inspectionMasterConfig',
    'customerMasterConfig', 'siteMasterConfig', 'orderMasterConfig', 'documentTemplateConfig'
  ];
  configExports.forEach(cfg => {
    test(`Config 내보내기: ${cfg}`, indexConfig.includes(cfg));
  });

  test('masterConfigs 맵핑에 order 포함', indexConfig.includes("'order': orderMasterConfig"));
}

// ============================================================
// 4. App.jsx 컴포넌트 테스트
// ============================================================
function testAppComponents() {
  section('4. App.jsx 컴포넌트 테스트');

  const appContent = fs.readFileSync(
    path.join(__dirname, 'src/App.jsx'), 'utf-8'
  );

  subsection('4.1 MVP 핵심 컴포넌트 존재');
  const coreComponents = [
    { name: 'WorkOrderList', desc: '작업지시 목록' },
    { name: 'WorkOrderCreate', desc: '작업지시 등록' },
    { name: 'WorkOrderDetail', desc: '작업지시 상세' },
    { name: 'WorkOrderEdit', desc: '작업지시 수정' },
    { name: 'WorkResultInput', desc: '작업실적 입력' },
    { name: 'OrderDetail', desc: '수주 상세' },
    { name: 'InspectionStandardList', desc: '검사기준 목록' },
  ];

  coreComponents.forEach(comp => {
    test(`컴포넌트: ${comp.desc} (${comp.name})`, appContent.includes(`const ${comp.name}`));
  });

  subsection('4.2 라우팅 케이스 확인');
  // work-order-create는 work-order-list 내에서 등록 모드로 처리됨
  const routeCases = [
    'work-order-list', 'work-order', 'work-order-detail', 'work-order-edit',
    'order', 'quote', 'shipment', 'inspection', 'stock', 'inbound'
  ];

  routeCases.forEach(route => {
    test(`라우트: ${route}`, appContent.includes(`case '${route}'`) || appContent.includes(`'${route}'`));
  });

  subsection('4.3 자재 투입 기능');
  test('자재 투입 모달', appContent.includes('투입자재'));
  test('자재 투입 이력', appContent.includes('자재 투입 이력'));
  test('LOT 번호 처리', appContent.includes('LOT') || appContent.includes('lotNo'));
  test('onUseMaterial 핸들러', appContent.includes('onUseMaterial'));

  subsection('4.4 수주-작업지시 연동');
  test('생산지시 기능', appContent.includes('생산지시'));
  test('bomData 생성', appContent.includes('bomData'));
  test('작업지시 자동 생성', appContent.includes('onCreateWorkOrder'));
}

// ============================================================
// 5. 빌드 테스트
// ============================================================
function testBuild() {
  section('5. 빌드 테스트');

  const { execSync } = require('child_process');

  try {
    log('빌드 실행 중...', 'test');
    execSync('npm run build', {
      cwd: __dirname,
      stdio: 'pipe',
      timeout: 120000
    });
    test('빌드 성공', true);

    // 빌드 결과물 확인
    const buildPath = path.join(__dirname, 'build');
    test('build 폴더 생성됨', fs.existsSync(buildPath));
    test('index.html 생성됨', fs.existsSync(path.join(buildPath, 'index.html')));
    test('static/js 폴더 생성됨', fs.existsSync(path.join(buildPath, 'static/js')));

  } catch (error) {
    test('빌드 성공', false, error.message);
  }
}

// ============================================================
// 6. MVP 흐름 검증
// ============================================================
function testMVPFlow() {
  section('6. MVP 흐름 검증');

  const appContent = fs.readFileSync(
    path.join(__dirname, 'src/App.jsx'), 'utf-8'
  );

  subsection('6.1 수주 → 생산지시 흐름');
  test('수주 목록 화면', appContent.includes("case 'order'"));
  test('수주 상세 화면', appContent.includes('OrderDetail'));
  test('생산지시 버튼', appContent.includes('생산지시'));
  test('분할 생산지시', appContent.includes('분할'));

  subsection('6.2 작업지시 → 자재투입 흐름');
  test('작업지시 상세에서 자재투입', appContent.includes('자재 투입'));
  test('재고에서 자재 선택', appContent.includes('inventory'));
  test('LOT 번호 입력', appContent.includes('lotNo'));

  subsection('6.3 작업실적 → 검사 흐름');
  test('작업실적 입력', appContent.includes('WorkResultInput'));
  test('검사기준 관리', appContent.includes('InspectionStandard'));
  test('검사 생성', appContent.includes('검사 생성') || appContent.includes('handleCreateInspection'));

  subsection('6.4 출하 흐름');
  test('출하관리 화면', appContent.includes("case 'shipment'"));
  test('출하지시서', appContent.includes('출하지시서'));
}

// ============================================================
// 7. 권한 및 역할 테스트
// ============================================================
function testPermissions() {
  section('7. 권한 및 역할 테스트');

  const appContent = fs.readFileSync(
    path.join(__dirname, 'src/App.jsx'), 'utf-8'
  );

  test('권한 매트릭스 정의', appContent.includes('menuPermissions'));
  test('역할별 대시보드', appContent.includes('ceo-dashboard') && appContent.includes('worker-dashboard'));
  test('생산팀 권한', appContent.includes("production: '✓'") || appContent.includes('production: true'));
}

// ============================================================
// 8. 데이터 정합성 테스트
// ============================================================
function testDataIntegrity() {
  section('8. 데이터 정합성 테스트');

  const appContent = fs.readFileSync(
    path.join(__dirname, 'src/App.jsx'), 'utf-8'
  );

  subsection('8.1 샘플 데이터');
  test('수주 샘플 데이터', appContent.includes('initialOrders') || appContent.includes('sampleOrders'));
  test('작업지시 샘플 데이터', appContent.includes('initialWorkOrders') || appContent.includes('workOrders'));
  test('재고 샘플 데이터', appContent.includes('initialInventory') || appContent.includes('inventory'));

  subsection('8.2 통합 데이터');
  test('통합 고객 마스터', appContent.includes('integratedCustomerMaster'));
  test('통합 수주 마스터', appContent.includes('integratedOrderMaster'));
  test('통합 작업지시 마스터', appContent.includes('integratedWorkOrderMaster'));
}

// ============================================================
// 9. 전체 유저플로우 데이터 연결 테스트
// ============================================================
function testUserFlowDataIntegration() {
  section('9. 전체 유저플로우 데이터 연결 테스트');

  const appContent = fs.readFileSync(
    path.join(__dirname, 'src/App.jsx'), 'utf-8'
  );

  // 데이터 추출 함수 (정규식으로 배열 데이터 파싱)
  function extractArrayData(content, varName) {
    const regex = new RegExp(`const ${varName} = \\[([\\s\\S]*?)\\];`, 'm');
    const match = content.match(regex);
    if (match) {
      try {
        // 간단한 객체 배열 파싱 시도
        const arrStr = match[0];
        const idMatches = arrStr.match(/id:\s*(\d+)/g);
        return idMatches ? idMatches.map(m => parseInt(m.replace('id:', '').trim())) : [];
      } catch (e) {
        return [];
      }
    }
    return [];
  }

  // 연결 필드 존재 확인 함수
  function checkFieldExists(content, varName, fieldName) {
    const regex = new RegExp(`const ${varName}[\\s\\S]*?${fieldName}:`, 'm');
    return regex.test(content);
  }

  subsection('9.1 거래처 → 현장 연결');
  log('거래처(Customer) → 현장(Site) 관계 검증', 'test');

  // integratedCustomerMaster 존재 확인
  test('거래처 마스터 정의', appContent.includes('integratedCustomerMaster'));
  test('현장 마스터 정의', appContent.includes('integratedSiteMaster'));

  // 현장에 customerId 필드 존재 확인
  test('현장에 customerId 연결', checkFieldExists(appContent, 'integratedSiteMaster', 'customerId'));
  test('현장에 customerName 연결', checkFieldExists(appContent, 'integratedSiteMaster', 'customerName'));

  // 거래처-현장 수량 확인 (10개 거래처, 100개 현장)
  const customerCount = (appContent.match(/integratedCustomerMaster\s*=\s*\[/g) || []).length > 0;
  const siteCount = (appContent.match(/integratedSiteMaster\s*=\s*\[/g) || []).length > 0;
  test('거래처-현장 마스터 데이터 존재', customerCount && siteCount);

  subsection('9.2 품목관리 데이터');
  log('품목 마스터(itemPriceMaster) 검증', 'test');

  test('품목 단가 마스터 정의', appContent.includes('itemPriceMaster'));
  test('품목 코드 필드', appContent.includes("itemCode:"));
  test('품목 명칭 필드', appContent.includes("itemName:"));
  test('단가(unitPrice) 필드', appContent.includes("unitPrice:"));
  test('판매가(sellingPrice) 필드', appContent.includes("sellingPrice:"));

  // 품목 카테고리 확인
  const itemCategories = ['가이드레일', '케이스', '하단마감재', '전동개폐기', '연동제어기', '감기샤프트'];
  itemCategories.forEach(cat => {
    test(`품목 카테고리: ${cat}`, appContent.includes(`'${cat}'`));
  });

  subsection('9.3 견적 → 수주 플로우');
  log('견적(Quote) → 수주(Order) 전환 검증', 'test');

  test('견적 마스터 정의', appContent.includes('integratedQuoteMaster'));
  test('수주 마스터 정의', appContent.includes('integratedOrderMaster'));

  // 수주에 견적 연결 필드 확인
  test('수주에 quoteId 연결', checkFieldExists(appContent, 'integratedOrderMaster', 'quoteId'));
  test('수주에 quoteNo 연결', checkFieldExists(appContent, 'integratedOrderMaster', 'quoteNo'));

  // 견적 → 수주 전환 로직 확인
  test('견적 수주전환 상태', appContent.includes("status === '수주전환'"));
  test('견적에서 수주 생성 로직', appContent.includes('convertedQuotes'));

  subsection('9.4 수주 → 생산관리 연결');
  log('수주(Order) → 생산지시(ProductionOrder) → 작업지시(WorkOrder) 검증', 'test');

  test('생산지시 마스터 정의', appContent.includes('integratedProductionOrderMaster'));
  test('작업지시 마스터 정의', appContent.includes('integratedWorkOrderMaster'));

  // 생산지시에 수주 연결
  test('생산지시에 orderId 연결', checkFieldExists(appContent, 'integratedProductionOrderMaster', 'orderId'));
  test('생산지시에 orderNo 연결', checkFieldExists(appContent, 'integratedProductionOrderMaster', 'orderNo'));

  // 작업지시에 수주 연결
  test('작업지시에 orderId 연결', checkFieldExists(appContent, 'integratedWorkOrderMaster', 'orderId'));
  test('작업지시에 orderNo 연결', checkFieldExists(appContent, 'integratedWorkOrderMaster', 'orderNo'));

  // 공정 정보 확인
  const processes = ['스크린', '절곡', '샤프트', '조립'];
  processes.forEach(proc => {
    test(`공정 정의: ${proc}`, appContent.includes(`'${proc}'`));
  });

  // BOM-공정 매핑 확인
  test('품목-공정 매핑 테이블', appContent.includes('itemProcessMapping'));

  subsection('9.5 생산 → 출하관리 연결');
  log('생산완료 → 출하(Shipment) 검증', 'test');

  test('출하 마스터 정의', appContent.includes('integratedShipmentMaster'));

  // 출하에 수주 연결
  test('출하에 orderId 연결', checkFieldExists(appContent, 'integratedShipmentMaster', 'orderId'));
  test('출하에 orderNo 연결', checkFieldExists(appContent, 'integratedShipmentMaster', 'orderNo'));

  // 출하 상태 확인
  const shipmentStatuses = ['출하대기', '배송중', '배송완료'];
  shipmentStatuses.forEach(status => {
    test(`출하 상태: ${status}`, appContent.includes(`'${status}'`));
  });

  // 출하 조건 확인 (생산완료 이상)
  test('출하 대상 필터링 (생산완료/출하중/출하완료/완료)',
    appContent.includes("['출하중', '출하완료', '완료'].includes"));

  subsection('9.6 품질관리(IQC/PQC/FQC) 연결');
  log('품질검사(Quality) 데이터 검증', 'test');

  test('품질검사 마스터 정의', appContent.includes('integratedQualityMaster'));

  // 품질검사에 작업지시 연결
  test('품질검사에 workOrderId 연결', checkFieldExists(appContent, 'integratedQualityMaster', 'workOrderId'));
  test('품질검사에 workOrderNo 연결', checkFieldExists(appContent, 'integratedQualityMaster', 'workOrderNo'));

  // 검사 유형 확인
  test('검사 유형: 중간검사', appContent.includes("'중간검사'"));
  test('검사 유형: 제품검사', appContent.includes("'제품검사'"));

  // 검사 결과 확인
  test('검사 결과: 합격', appContent.includes("result === '합격'") || appContent.includes("'합격'"));
  test('검사 결과: 불합격', appContent.includes("result === '불합격'") || appContent.includes("'불합격'"));

  // 검사 항목 확인
  test('검사 항목 배열', appContent.includes('checkItems'));

  subsection('9.7 자재관리 연결');
  log('재고/자재 데이터 검증', 'test');

  // 재고 관련 데이터 확인
  test('재고 데이터 정의', appContent.includes('inventory') || appContent.includes('stockData'));
  test('LOT 번호 관리', appContent.includes('lotNo') || appContent.includes('LOT'));

  // 자재 투입 기능 확인
  test('자재 투입 기능', appContent.includes('투입자재') || appContent.includes('onUseMaterial'));
  test('자재 투입 이력', appContent.includes('자재 투입 이력') || appContent.includes('materialUsage'));

  subsection('9.8 상태 흐름 검증');
  log('전체 상태 흐름 검증', 'test');

  // 수주 상태 흐름
  const orderStatuses = ['수주확정', '생산중', '생산완료', '출하중', '출하완료', '완료'];
  orderStatuses.forEach(status => {
    test(`수주 상태: ${status}`, appContent.includes(`'${status}'`));
  });

  // 작업지시 상태 흐름
  const workOrderStatuses = ['대기', '진행중', '완료'];
  workOrderStatuses.forEach(status => {
    test(`작업지시 상태: ${status}`, appContent.includes(`status === '${status}'`) || appContent.includes(`'${status}'`));
  });

  subsection('9.9 데이터 통계 검증');
  log('통합 데이터 통계 검증', 'test');

  // 통계 데이터 확인
  test('통계 요약 객체', appContent.includes('integratedSummary') || appContent.includes('orderStats'));

  // 각 마스터 데이터 카운트 로직 확인
  test('수주 건수 집계', appContent.includes('integratedOrderMaster.length'));
  test('작업지시 건수 집계', appContent.includes('integratedWorkOrderMaster.length'));
  test('출하 건수 집계', appContent.includes('integratedShipmentMaster.length'));
}

// ============================================================
// 결과 요약
// ============================================================
function printSummary() {
  section('테스트 결과 요약');

  const total = testResults.passed + testResults.failed;
  const passRate = ((testResults.passed / total) * 100).toFixed(1);

  console.log(`${colors.green}통과: ${testResults.passed}${colors.reset}`);
  console.log(`${colors.red}실패: ${testResults.failed}${colors.reset}`);
  console.log(`${colors.yellow}경고: ${testResults.warnings}${colors.reset}`);
  console.log(`\n${colors.bold}통과율: ${passRate}%${colors.reset}`);

  if (testResults.failed > 0) {
    console.log(`\n${colors.red}${colors.bold}실패 항목:${colors.reset}`);
    testResults.details
      .filter(d => d.status === 'fail')
      .forEach(d => console.log(`  - ${d.description} ${d.details ? `(${d.details})` : ''}`));
  }

  console.log(`\n${'='.repeat(60)}`);

  if (testResults.failed === 0) {
    console.log(`${colors.green}${colors.bold}모든 테스트 통과! MVP 배포 준비 완료.${colors.reset}`);
  } else {
    console.log(`${colors.red}${colors.bold}일부 테스트 실패. 위 항목을 확인하세요.${colors.reset}`);
  }
}

// ============================================================
// 메인 실행
// ============================================================
console.log(`\n${colors.bold}${colors.cyan}`);
console.log('╔════════════════════════════════════════════════════════════╗');
console.log('║          MES 시스템 통합테스트 (방화셔터 MVP)              ║');
console.log('╚════════════════════════════════════════════════════════════╝');
console.log(`${colors.reset}`);
console.log(`실행 시간: ${new Date().toLocaleString('ko-KR')}\n`);

try {
  testFileStructure();
  testMenuDefinitions();
  testConfigFiles();
  testAppComponents();
  testBuild();
  testMVPFlow();
  testPermissions();
  testDataIntegrity();
  testUserFlowDataIntegration();
  printSummary();
} catch (error) {
  console.error(`${colors.red}테스트 실행 중 오류 발생: ${error.message}${colors.reset}`);
  process.exit(1);
}
