import * as XLSX from 'xlsx';
import { saveAs } from 'file-saver';
import { calculatePurchaseQuantity } from './purchaseCalculator';

/**
 * 자재 목록을 카테고리별로 그룹화
 */
const groupMaterialsByCategory = (materials) => {
  const groups = {};
  
  materials.forEach(material => {
    const category = material.classified_category || material.category || 'UNCATEGORIZED';
    if (!groups[category]) {
      groups[category] = [];
    }
    groups[category].push(material);
  });
  
  return groups;
};

/**
 * 동일한 자재끼리 합치기 (자재 설명 + 사이즈 기준)
 * 엑셀 내보내기용 특별 처리:
 * - PIPE: 끝단 정보 제거 (BOE-POE, POE-TOE 등)
 * - NIPPLE: 길이별 구분 (75mm, 100mm 등)
 */
const consolidateMaterials = (materials, isComparison = false) => {
  const consolidated = {};
  
  materials.forEach(material => {
    const category = material.classified_category || material.category || 'UNCATEGORIZED';
    let description = material.original_description || material.description || '';
    const sizeSpec = material.size_spec || '';
    
    // 파이프 끝단 정보 제거 (엑셀 내보내기용)
    if (category === 'PIPE') {
      description = description
        .replace(/\s+(BOE-POE|POE-TOE|BOE-TOE|BOE-BBE|BBE-POE|BBE-BBE|POE-POE|TOE-TOE)\s*$/i, '')
        .replace(/\s+(BOE|POE|TOE|BBE)\s*-\s*(BOE|POE|TOE|BBE)\s*$/i, '')
        .trim();
    }
    
    // 니플의 경우 길이 정보를 그룹화 키에 포함
    let lengthInfo = '';
    if (category === 'FITTING' && description.toLowerCase().includes('nipple')) {
      const lengthMatch = description.match(/(\d+)\s*mm/i);
      if (lengthMatch) {
        lengthInfo = `_${lengthMatch[1]}mm`;
      }
    }
    
    // 그룹화 키: 카테고리 + 정제된자재설명 + 사이즈 + 길이정보
    const groupKey = `${category}|${description}|${sizeSpec}${lengthInfo}`;
    
    if (!consolidated[groupKey]) {
      consolidated[groupKey] = {
        ...material,
        // 정제된 설명으로 덮어쓰기
        original_description: description,
        description: description,
        quantity: 0,
        totalLength: 0, // 파이프용
        itemCount: 0,   // 파이프 개수
        lineNumbers: [], // 라인 번호들
        // 비교 모드용
        previous_quantity: 0,
        current_quantity: 0,
        quantity_change: 0
      };
    }
    
    const group = consolidated[groupKey];
    group.quantity += material.quantity || 0;
    
    // 비교 모드인 경우 이전/현재 수량도 합산
    if (isComparison) {
      group.previous_quantity += material.previous_quantity || 0;
      group.current_quantity += material.current_quantity || 0;
      group.quantity_change += material.quantity_change || 0;
    }
    
    // 파이프인 경우 길이 계산
    if (category === 'PIPE') {
      const lengthMm = material.pipe_details?.length_mm || 0;
      const lengthM = lengthMm / 1000;
      
      if (isComparison) {
        // 비교 모드에서는 이전/현재 길이 계산
        group.totalLength += lengthM * (material.current_quantity || material.quantity || 0);
        group.itemCount += material.current_quantity || material.quantity || 0;
        
        // 이전 길이도 저장
        if (!group.previousTotalLength) group.previousTotalLength = 0;
        group.previousTotalLength += lengthM * (material.previous_quantity || 0);
      } else {
        group.totalLength += lengthM * (material.quantity || 0);
        group.itemCount += material.quantity || 0;
      }
    }
    
    // 라인 번호 수집
    if (material.line_number) {
      group.lineNumbers.push(material.line_number);
    }
  });
  
  // 라인 번호를 문자열로 변환
  Object.values(consolidated).forEach(group => {
    group.line_number = group.lineNumbers.length > 0 
      ? group.lineNumbers.join(', ') 
      : '-';
  });
  
  return Object.values(consolidated);
};

/**
 * 벨브 연결방식 추출 함수
 */
const extractValveConnectionType = (description) => {
  const descUpper = description.toUpperCase();
  
  if (descUpper.includes('SW X THRD') || descUpper.includes('SW×THRD')) {
    return 'SW×THRD';
  } else if (descUpper.includes('FLG') || descUpper.includes('FLANGE')) {
    return 'FLG';
  } else if (descUpper.includes('SW') || descUpper.includes('SOCKET')) {
    return 'SW';
  } else if (descUpper.includes('THRD') || descUpper.includes('THREAD')) {
    return 'THRD';
  } else if (descUpper.includes('BW') || descUpper.includes('BUTT WELD')) {
    return 'BW';
  } else {
    return '-';
  }
};

/**
 * 벨브 추가 정보 추출 함수
 */
const extractValveAdditionalInfo = (description) => {
  const descUpper = description.toUpperCase();
  let additionalInfo = '';
  
  const additionalPatterns = [
    '3-WAY', '3WAY', 'THREE WAY',
    'DOUL PLATE', 'DOUBLE PLATE', 'DUAL PLATE',
    'DOUBLE DISC', 'DUAL DISC',
    'SWING', 'LIFT', 'TILTING',
    'WAFER', 'LUG', 'FLANGED',
    'FULL BORE', 'REDUCED BORE',
    'FIRE SAFE', 'ANTI STATIC'
  ];
  
  for (const pattern of additionalPatterns) {
    if (descUpper.includes(pattern)) {
      if (additionalInfo) {
        additionalInfo += ', ';
      }
      additionalInfo += pattern;
    }
  }
  
  return additionalInfo || '-';
};

/**
 * 자재 데이터를 엑셀용 형태로 변환
 */
const formatMaterialForExcel = (material, includeComparison = false) => {
  const category = material.classified_category || material.category || '-';
  
  // 엑셀용 자재 설명 정제
  let cleanDescription = material.original_description || material.description || '-';
  
  // 파이프 끝단 정보 제거
  if (category === 'PIPE') {
    cleanDescription = cleanDescription
      .replace(/\s+(BOE-POE|POE-TOE|BOE-TOE|BOE-BBE|BBE-POE|BBE-BBE|POE-POE|TOE-TOE)\s*$/i, '')
      .replace(/\s+(BOE|POE|TOE|BBE)\s*-\s*(BOE|POE|TOE|BBE)\s*$/i, '')
      .trim();
  }
  
  // 니플의 경우 길이 정보 명시적 추가
  if (category === 'FITTING' && cleanDescription.toLowerCase().includes('nipple')) {
    if (material.fitting_details && material.fitting_details.length_mm) {
      const lengthMm = Math.round(material.fitting_details.length_mm);
      if (!cleanDescription.match(/\d+\s*mm/i)) {
        cleanDescription += ` ${lengthMm}mm`;
      }
    } else {
      const lengthMatch = material.original_description?.match(/(\d+)\s*mm/i);
      if (lengthMatch && !cleanDescription.match(/\d+\s*mm/i)) {
        cleanDescription += ` ${lengthMatch[1]}mm`;
      }
    }
  }
  
  // 구매 수량 계산
  const purchaseInfo = calculatePurchaseQuantity(material);
  
  // 변수 선언 (먼저 선언)
  let itemName = '';
  let detailInfo = '';
  let gasketMaterial = '';
  let gasketThickness = '';
  if (category === 'PIPE') {
    // 파이프 상세 타입 표시 개선
    const pipeDetails = material.pipe_details || {};
    const manufacturingMethod = pipeDetails.manufacturing_method || '';
    const endPreparation = pipeDetails.end_preparation || '';
    
    // 제조방법만으로 상세 타입 생성 (끝단처리 정보 제거)
    if (manufacturingMethod) {
      itemName = `${manufacturingMethod} PIPE`;
    } else {
      // description에서 제조방법 추출 시도
      const desc = cleanDescription.toUpperCase();
      if (desc.includes('SEAMLESS')) {
        itemName = 'SEAMLESS PIPE';
      } else if (desc.includes('WELDED')) {
        itemName = 'WELDED PIPE';
      } else if (desc.includes('ERW')) {
        itemName = 'ERW PIPE';
      } else if (desc.includes('SMLS')) {
        itemName = 'SEAMLESS PIPE';
      } else {
        itemName = 'PIPE';
      }
    }
  } else if (category === 'FITTING') {
    // 피팅 상세 타입 표시 - 프론트엔드 표시와 동일한 로직 사용
    const fittingDetails = material.fitting_details || {};
    const classificationDetails = material.classification_details || {};
    const fittingTypeInfo = classificationDetails.fitting_type || {};
    
    const fittingType = fittingTypeInfo.type || fittingDetails.fitting_type || '';
    const fittingSubtype = fittingTypeInfo.subtype || fittingDetails.fitting_subtype || '';
    
    // 프론트엔드와 동일한 displayType 로직 사용
    let displayType = '';
    
    if (fittingType === 'OLET') {
      // OLET 풀네임 표시
      switch (fittingSubtype) {
        case 'SOCKOLET':
          displayType = 'SOCK-O-LET';
          break;
        case 'WELDOLET':
          displayType = 'WELD-O-LET';
          break;
        case 'ELLOLET':
          displayType = 'ELL-O-LET';
          break;
        case 'THREADOLET':
          displayType = 'THREAD-O-LET';
          break;
        case 'ELBOLET':
          displayType = 'ELB-O-LET';
          break;
        case 'NIPOLET':
          displayType = 'NIP-O-LET';
          break;
        case 'COUPOLET':
          displayType = 'COUP-O-LET';
          break;
        default:
          // Description에서 직접 추출
          const descUpper = cleanDescription.toUpperCase();
          if (descUpper.includes('SOCK-O-LET') || descUpper.includes('SOCKOLET')) {
            displayType = 'SOCK-O-LET';
          } else if (descUpper.includes('WELD-O-LET') || descUpper.includes('WELDOLET')) {
            displayType = 'WELD-O-LET';
          } else if (descUpper.includes('ELL-O-LET') || descUpper.includes('ELLOLET')) {
            displayType = 'ELL-O-LET';
          } else if (descUpper.includes('THREAD-O-LET') || descUpper.includes('THREADOLET')) {
            displayType = 'THREAD-O-LET';
          } else if (descUpper.includes('ELB-O-LET') || descUpper.includes('ELBOLET')) {
            displayType = 'ELB-O-LET';
          } else if (descUpper.includes('NIP-O-LET') || descUpper.includes('NIPOLET')) {
            displayType = 'NIP-O-LET';
          } else if (descUpper.includes('COUP-O-LET') || descUpper.includes('COUPOLET')) {
            displayType = 'COUP-O-LET';
          } else {
            displayType = 'OLET';
          }
      }
    } else if (fittingType === 'TEE' && fittingSubtype === 'REDUCING') {
      displayType = 'TEE REDUCING';
    } else if (fittingType === 'REDUCER' && fittingSubtype === 'CONCENTRIC') {
      displayType = 'REDUCER CONC';
    } else if (fittingType === 'REDUCER' && fittingSubtype === 'ECCENTRIC') {
      displayType = 'REDUCER ECC';
    } else if (cleanDescription.toUpperCase().includes('TEE RED')) {
      displayType = 'TEE REDUCING';
    } else if (cleanDescription.toUpperCase().includes('RED CONC')) {
      displayType = 'REDUCER CONC';
    } else if (cleanDescription.toUpperCase().includes('RED ECC')) {
      displayType = 'REDUCER ECC';
    } else if (cleanDescription.toUpperCase().includes('CAP')) {
      if (cleanDescription.includes('NPT(F)')) {
        displayType = 'CAP NPT(F)';
      } else if (cleanDescription.includes('SW')) {
        displayType = 'CAP SW';
      } else if (cleanDescription.includes('BW')) {
        displayType = 'CAP BW';
      } else {
        displayType = 'CAP';
      }
    } else if (cleanDescription.toUpperCase().includes('PLUG')) {
      if (cleanDescription.toUpperCase().includes('HEX')) {
        if (cleanDescription.includes('NPT(M)')) {
          displayType = 'HEX PLUG NPT(M)';
        } else {
          displayType = 'HEX PLUG';
        }
      } else if (cleanDescription.includes('NPT(M)')) {
        displayType = 'PLUG NPT(M)';
      } else if (cleanDescription.includes('NPT')) {
        displayType = 'PLUG NPT';
      } else {
        displayType = 'PLUG';
      }
    } else if (fittingType === 'NIPPLE') {
      const length = fittingDetails.length_mm || fittingDetails.avg_length_mm;
      let nippleType = 'NIPPLE';
      if (length) nippleType += ` ${length}mm`;
      displayType = nippleType;
    } else if (fittingType === 'ELBOW') {
      // 엘보 상세 정보 표시
      let elbowDetails = [];
      
      // 각도 정보
      if (fittingSubtype.includes('90DEG') || cleanDescription.includes('90')) {
        elbowDetails.push('90°');
      } else if (fittingSubtype.includes('45DEG') || cleanDescription.includes('45')) {
        elbowDetails.push('45°');
      }
      
      // 반경 정보
      if (fittingSubtype.includes('LONG_RADIUS') || cleanDescription.toUpperCase().includes('LR')) {
        elbowDetails.push('LR');
      } else if (fittingSubtype.includes('SHORT_RADIUS') || cleanDescription.toUpperCase().includes('SR')) {
        elbowDetails.push('SR');
      }
      
      displayType = elbowDetails.length > 0 ? `ELBOW ${elbowDetails.join(' ')}` : 'ELBOW';
    } else {
      displayType = fittingType || 'FITTING';
    }
    
    itemName = displayType;
  } else if (category === 'FLANGE') {
    // 플랜지 상세 타입 표시 - 프론트엔드 표시와 동일한 로직 사용
    const flangeDetails = material.flange_details || {};
    const rawFlangeType = flangeDetails.flange_type || '';
    const rawFacingType = flangeDetails.facing_type || '';
    
    // 플랜지 타입 풀네임 매핑 (영어)
    const flangeTypeMap = {
      'WN': 'WELD NECK FLANGE',
      'WELD_NECK': 'WELD NECK FLANGE',
      'SO': 'SLIP ON FLANGE',
      'SLIP_ON': 'SLIP ON FLANGE',
      'SW': 'SOCKET WELD FLANGE',
      'SOCKET_WELD': 'SOCKET WELD FLANGE',
      'THREADED': 'THREADED FLANGE',
      'THD': 'THREADED FLANGE',
      'BLIND': 'BLIND FLANGE',
      'LAP_JOINT': 'LAP JOINT FLANGE',
      'LJ': 'LAP JOINT FLANGE',
      'REDUCING': 'REDUCING FLANGE',
      'ORIFICE': 'ORIFICE FLANGE',
      'SPECTACLE': 'SPECTACLE BLIND',
      'SPECTACLE_BLIND': 'SPECTACLE BLIND',
      'PADDLE': 'PADDLE BLIND',
      'PADDLE_BLIND': 'PADDLE BLIND',
      'SPACER': 'SPACER',
      'SWIVEL': 'SWIVEL FLANGE',
      'DRIP_RING': 'DRIP RING',
      'NOZZLE': 'NOZZLE FLANGE'
    };

    // rawFlangeType에서 facing 정보 분리 (예: "WN RF" -> "WN")
    let cleanFlangeType = rawFlangeType;
    if (rawFlangeType.includes(' RF')) {
      cleanFlangeType = rawFlangeType.replace(' RF', '').trim();
    } else if (rawFlangeType.includes(' FF')) {
      cleanFlangeType = rawFlangeType.replace(' FF', '').trim();
    } else if (rawFlangeType.includes(' RTJ')) {
      cleanFlangeType = rawFlangeType.replace(' RTJ', '').trim();
    }

    let displayType = flangeTypeMap[cleanFlangeType] || '';

    // Description에서 추출 (매핑되지 않은 경우)
    if (!displayType) {
      const desc = cleanDescription.toUpperCase();
      if (desc.includes('ORIFICE')) {
        displayType = 'ORIFICE FLANGE';
      } else if (desc.includes('SPECTACLE')) {
        displayType = 'SPECTACLE BLIND';
      } else if (desc.includes('PADDLE')) {
        displayType = 'PADDLE BLIND';
      } else if (desc.includes('SPACER')) {
        displayType = 'SPACER';
      } else if (desc.includes('REDUCING') || desc.includes('RED')) {
        displayType = 'REDUCING FLANGE';
      } else if (desc.includes('BLIND')) {
        displayType = 'BLIND FLANGE';
      } else if (desc.includes('WN RF') || desc.includes('WN-RF')) {
        displayType = 'WELD NECK FLANGE';
      } else if (desc.includes('WN FF') || desc.includes('WN-FF')) {
        displayType = 'WELD NECK FLANGE';
      } else if (desc.includes('WN RTJ') || desc.includes('WN-RTJ')) {
        displayType = 'WELD NECK FLANGE';
      } else if (desc.includes('WN')) {
        displayType = 'WELD NECK FLANGE';
      } else if (desc.includes('SO RF') || desc.includes('SO-RF')) {
        displayType = 'SLIP ON FLANGE';
      } else if (desc.includes('SO FF') || desc.includes('SO-FF')) {
        displayType = 'SLIP ON FLANGE';
      } else if (desc.includes('SO')) {
        displayType = 'SLIP ON FLANGE';
      } else if (desc.includes('SW')) {
        displayType = 'SOCKET WELD FLANGE';
      } else {
        displayType = 'FLANGE';
      }
    }
    
    itemName = displayType;
  } else if (category === 'VALVE') {
    // 밸브 상세 타입 표시
    const valveDetails = material.valve_details || {};
    const valveType = valveDetails.valve_type || '';
    
    if (valveType === 'GATE') {
      itemName = '게이트 밸브';
    } else if (valveType === 'BALL') {
      itemName = '볼 밸브';
    } else if (valveType === 'GLOBE') {
      itemName = '글로브 밸브';
    } else if (valveType === 'CHECK') {
      itemName = '체크 밸브';
    } else if (valveType === 'BUTTERFLY') {
      itemName = '버터플라이 밸브';
    } else if (valveType === 'NEEDLE') {
      itemName = '니들 밸브';
    } else if (valveType === 'RELIEF') {
      itemName = '릴리프 밸브';
    } else {
      // description에서 추출 (BOM 페이지와 동일한 로직)
      const desc = cleanDescription.toUpperCase();
      if (desc.includes('SIGHT GLASS') || desc.includes('사이트글라스')) {
        itemName = 'SIGHT GLASS';
      } else if (desc.includes('STRAINER') || desc.includes('스트레이너')) {
        itemName = 'STRAINER';
      } else if (desc.includes('GATE') || desc.includes('게이트')) {
        itemName = 'GATE VALVE';
      } else if (desc.includes('BALL') || desc.includes('볼')) {
        itemName = 'BALL VALVE';
      } else if (desc.includes('CHECK') || desc.includes('체크')) {
        itemName = 'CHECK VALVE';
      } else if (desc.includes('GLOBE') || desc.includes('글로브')) {
        itemName = 'GLOBE VALVE';
      } else if (desc.includes('BUTTERFLY') || desc.includes('버터플라이')) {
        itemName = 'BUTTERFLY VALVE';
      } else if (desc.includes('NEEDLE') || desc.includes('니들')) {
        itemName = 'NEEDLE VALVE';
      } else if (desc.includes('RELIEF') || desc.includes('릴리프')) {
        itemName = 'RELIEF VALVE';
      } else {
        itemName = 'VALVE';
      }
    }
  } else if (category === 'GASKET') {
    // BOM 페이지의 타입을 따라가도록 - 프론트엔드 parseGasketInfo와 동일한 로직
    const gasketDetails = material.gasket_details || {};
    const gasketType = gasketDetails.gasket_type || '';
    
    // 가스켓 타입 매핑 (프론트엔드와 동일)
    const gasketTypeMap = {
      'SWG': 'SPIRAL WOUND GASKET',
      'SPIRAL_WOUND': 'SPIRAL WOUND GASKET',
      'RTJ': 'RING TYPE JOINT GASKET',
      'RING_JOINT': 'RING TYPE JOINT GASKET',
      'FF': 'FULL FACE GASKET',
      'FULL_FACE': 'FULL FACE GASKET',
      'RF': 'RAISED FACE GASKET',
      'RAISED_FACE': 'RAISED FACE GASKET'
    };
    
    // Description에서 가스켓 타입 추출
    const descUpper = cleanDescription.toUpperCase();
    let extractedType = '';
    
    if (descUpper.includes('SWG') || descUpper.includes('SPIRAL')) {
      extractedType = 'SWG';
    } else if (descUpper.includes('RTJ') || descUpper.includes('RING')) {
      extractedType = 'RTJ';
    } else if (descUpper.includes('FF') || descUpper.includes('FULL FACE')) {
      extractedType = 'FF';
    } else if (descUpper.includes('RF') || descUpper.includes('RAISED')) {
      extractedType = 'RF';
    }
    
    // 풀네임으로 변환
    if (gasketType && gasketTypeMap[gasketType]) {
      itemName = gasketTypeMap[gasketType];
    } else if (extractedType && gasketTypeMap[extractedType]) {
      itemName = gasketTypeMap[extractedType];
      } else {
        itemName = 'GASKET';
      }
  } else if (category === 'BOLT') {
    // 볼트 상세 타입 표시
    const boltDetails = material.bolt_details || {};
    const boltType = boltDetails.bolt_type || '';
    
    // BOM 페이지의 타입을 따라가도록 - 프론트엔드 parseBoltInfo와 동일한 로직
    let boltSubtype = 'BOLT_GENERAL';
    
    if (boltType && boltType !== 'UNKNOWN' && boltType !== 'UNCLASSIFIED') {
      boltSubtype = boltType;
    } else {
      // 원본 설명에서 특수 볼트 타입 추출 (프론트엔드와 동일)
      const desc = cleanDescription.toUpperCase();
      if (desc.includes('PSV')) {
        boltSubtype = 'PSV_BOLT';
      } else if (desc.includes('LT')) {
        boltSubtype = 'LT_BOLT';
      } else if (desc.includes('CK')) {
        boltSubtype = 'CK_BOLT';
      }
    }
    
    // BOM 페이지와 동일한 타입명 사용
    itemName = boltSubtype;
  } else if (category === 'SUPPORT' || category === 'U_BOLT') {
    // 서포트 상세 타입 표시
    const desc = cleanDescription.toUpperCase();
    if (desc.includes('URETHANE') || desc.includes('BLOCK SHOE')) {
      itemName = 'URETHANE BLOCK SHOE';
      // 우레탄 블럭슈의 경우 두께 정보는 품목명에 포함하지 않음 (재질 열에서 처리)
    } else if (desc.includes('CLAMP')) {
      // 클램프 타입 상세 분류 (CL-1, CL-2, CL-3 등)
      const clampMatch = desc.match(/CL[-\s]*(\d+)/i);
      if (clampMatch) {
        itemName = `CLAMP CL-${clampMatch[1]}`;
      } else {
        itemName = 'CLAMP CL-1'; // 기본값
      }
    } else if (desc.includes('U-BOLT') || desc.includes('U BOLT')) {
      itemName = 'U-BOLT';
    } else if (desc.includes('HANGER')) {
      itemName = 'HANGER';
    } else if (desc.includes('SPRING')) {
      itemName = 'SPRING HANGER';
    } else if (desc.includes('GUIDE')) {
      itemName = 'GUIDE';
    } else if (desc.includes('ANCHOR')) {
      itemName = 'ANCHOR';
    } else {
      itemName = 'SUPPORT';
    }
  } else if (category === 'SPECIAL') {
    // 스페셜 자재 타입 추출 (큰 범주)
    const desc = cleanDescription.toUpperCase();
    if (desc.includes('FLG') || desc.includes('FLANGE')) {
      itemName = 'SPECIAL FLANGE';
    } else if (desc.includes('OIL PUMP') || desc.includes('PUMP')) {
      itemName = 'SPECIAL OIL PUMP';
    } else if (desc.includes('COMPRESSOR')) {
      itemName = 'SPECIAL COMPRESSOR';
    } else if (desc.includes('VALVE')) {
      itemName = 'SPECIAL VALVE';
    } else if (desc.includes('FITTING')) {
      itemName = 'SPECIAL FITTING';
    } else if (desc.includes('PIPE')) {
      itemName = 'SPECIAL PIPE';
    } else {
      itemName = 'SPECIAL ITEM';
    }
  } else if (category === 'UNCLASSIFIED') {
    // 미분류 자재는 원본 설명을 품목명으로 사용
    itemName = cleanDescription || 'UNCLASSIFIED ITEM';
  } else {
    itemName = category || 'UNCLASSIFIED';
  }
  
  // 압력 등급 추출 (카테고리별 처리)
  let pressure = '-';
  
  if (category === 'GASKET') {
    // 가스켓의 경우 gasket_details에서 압력등급 추출
    if (material.gasket_details && material.gasket_details.pressure_rating) {
      pressure = material.gasket_details.pressure_rating;
    } else {
      // gasket_details가 없으면 description에서 추출
      const pressureMatch = cleanDescription.match(/(\d+)LB/i);
      if (pressureMatch) {
        pressure = `${pressureMatch[1]}LB`;
      }
    }
  } else {
    // 다른 카테고리는 기존 방식
    const pressureMatch = cleanDescription.match(/(\d+)LB/i);
    if (pressureMatch) {
      pressure = `${pressureMatch[1]}LB`;
    }
  }
  
  // 스케줄/길이 추출 (카테고리별 처리)
  let schedule = '-';
  
  if (category === 'BOLT') {
    // 볼트의 경우 길이 정보 추출 (백엔드와 동일한 패턴 사용)
    const lengthPatterns = [
      /(\d+(?:\.\d+)?)\s*LG/i,  // 145.0000 LG, 75 LG (최우선)
      /(\d+(?:\.\d+)?)\s*MM\s*LG/i,  // 70MM LG 형태
      /L\s*(\d+(?:\.\d+)?)\s*MM/i,
      /LENGTH\s*(\d+(?:\.\d+)?)\s*MM/i,
      /(\d+(?:\.\d+)?)\s*MM\s*LONG/i,
      /X\s*(\d+(?:\.\d+)?)\s*MM/i,  // M8 X 20MM 형태
      /,\s*(\d+(?:\.\d+)?)\s*LG/i,  // ", 145.0000 LG" 형태 (PSV, LT 볼트용)
      /,\s*(\d+(?:\.\d+)?)\s+(?:CK|PSV|LT)/i,  // ", 140 CK" 형태 (PSV 볼트용)
      /PSV\s+(\d+(?:\.\d+)?)/i,  // PSV 140 형태 (PSV 볼트 전용)
      /(\d+(?:\.\d+)?)\s+PSV/i,  // 140 PSV 형태 (PSV 볼트 전용)
      /(\d+(?:\.\d+)?)\s*CK/i,  // 140CK 형태 (체크밸브용 볼트)
      /(\d+(?:\.\d+)?)\s*LT/i,  // 140LT 형태 (저온용 볼트)
      /(\d+(?:\.\d+)?)\s*mm/i,  // 50mm
      /(\d+(?:\.\d+)?)\s*MM/i,  // 50MM
      /LG[,\s]*(\d+(?:\.\d+)?)/i // LG, 75 형태
    ];
    
    for (const pattern of lengthPatterns) {
      const match = cleanDescription.match(pattern);
      if (match) {
        let lengthValue = match[1];
        // 소수점 제거 (145.0000 → 145)
        if (lengthValue.includes('.') && lengthValue.endsWith('.0000')) {
          lengthValue = lengthValue.split('.')[0];
        } else if (lengthValue.includes('.') && /\.0+$/.test(lengthValue)) {
          lengthValue = lengthValue.split('.')[0];
        }
        schedule = `${lengthValue}mm`;
        break;
      }
    }
  } else {
    // 다른 카테고리는 스케줄 추출
    const scheduleMatch = cleanDescription.match(/SCH\s*(\d+[A-Z]*(?:\s*[xX×]\s*SCH\s*\d+[A-Z]*)?)/i);
    if (scheduleMatch) {
      schedule = scheduleMatch[0];
    }
  }
  
  // 재질 추출 (카테고리별 처리)
  let grade = '-';
  
  if (category === 'GASKET') {
    // 가스켓의 경우 재질 필드에는 H/F/I/O 타입 정보 표시
    const hfioMatch = cleanDescription.match(/H\/F\/I\/O/i);
    if (hfioMatch) {
      grade = 'H/F/I/O';
    } else {
      // 다른 가스켓 타입들
      if (cleanDescription.includes('SWG') || cleanDescription.includes('SPIRAL')) {
        grade = 'SWG';
      } else if (cleanDescription.includes('RTJ') || cleanDescription.includes('RING')) {
        grade = 'RTJ';
      } else if (cleanDescription.includes('FF') || cleanDescription.includes('FULL FACE')) {
        grade = 'FF';
      } else if (cleanDescription.includes('RF') || cleanDescription.includes('RAISED')) {
        grade = 'RF';
      } else {
        grade = 'GASKET';
      }
    }
  } else if (category === 'BOLT') {
    // 볼트 전용 재질 추출 (복합 ASTM 패턴 지원)
    const boltGradePatterns = [
      // 복합 ASTM 패턴 (A193/A194 GR B7/2H)
      /(ASTM\s+A\d+\/A\d+\s+GR\s+[A-Z0-9\/]+)/i,
      // 단일 ASTM 패턴 (ASTM A193 GR B7)
      /(ASTM\s+A\d+\s+GR\s+[A-Z0-9]+)/i,
      // ASTM 번호만 (ASTM A193/A194)
      /(ASTM\s+A\d+(?:\/A\d+)?)/i,
      // 일반 ASTM 패턴
      /(ASTM\s+[A-Z0-9\s\/]+(?:TP\d+|GR\s*[A-Z0-9\/]+|WP\d+)?)/i
    ];
    
    for (const pattern of boltGradePatterns) {
      const match = cleanDescription.match(pattern);
      if (match) {
        grade = match[1].trim();
        break;
      }
    }
    
    // ASTM이 없는 경우 기본 재질 패턴 시도
    if (grade === '-') {
      const basicGradeMatch = cleanDescription.match(/(A\d+(?:\/A\d+)?\s+(?:GR\s+)?[A-Z0-9\/]+)/i);
      if (basicGradeMatch) {
        grade = basicGradeMatch[1].trim();
      }
    }
    
    // 백엔드에서 제공하는 재질 정보 우선 사용
    if (material.full_material_grade && material.full_material_grade !== '-') {
      grade = material.full_material_grade;
    } else if (material.material_grade && material.material_grade !== '-') {
      grade = material.material_grade;
    }
  } else {
    // 기존 ASTM 패턴 (다른 카테고리용)
    const gradeMatch = cleanDescription.match(/(ASTM\s+[A-Z0-9\s]+(?:TP\d+|GR\s*[A-Z0-9]+|WP\d+)?)/i);
    if (gradeMatch) {
      grade = gradeMatch[1].trim();
    }
  }
  
  // 카테고리별 상세 정보 추출 (이미 위에서 선언됨)
  
  if (category === 'BOLT') {
    // 볼트의 경우 표면처리 정보 추출
    const surfaceTreatments = [];
    
    // 원본 설명에서 표면처리 패턴 확인
    const surfacePatterns = {
      'ELEC.GALV': 'ELEC.GALV',
      'ELEC GALV': 'ELEC.GALV',
      'GALVANIZED': 'GALVANIZED',
      'GALV': 'GALV',
      'HOT DIP GALV': 'HDG',
      'HDG': 'HDG',
      'ZINC PLATED': 'ZINC PLATED',
      'ZINC': 'ZINC',
      'PLAIN': 'PLAIN'
    };
    
    for (const [pattern, treatment] of Object.entries(surfacePatterns)) {
      if (cleanDescription.includes(pattern)) {
        surfaceTreatments.push(treatment);
        break; // 첫 번째 매치만 사용
      }
    }
    
    detailInfo = surfaceTreatments.join(', ') || '-';
  } else if (category === 'GASKET') {
    // 실제 재질 구성 정보 - description에서 우선 추출
    // SS304/GRAPHITE/SS304/SS304 패턴 먼저 찾기
    const fullMaterialMatch = cleanDescription.match(/SS304\/GRAPHITE\/SS304\/SS304/i);
    if (fullMaterialMatch) {
      gasketMaterial = 'SS304/GRAPHITE/SS304/SS304';
    } else {
      // 4개 재질 패턴 (다양한 재질 조합)
      const fourMaterialMatch = cleanDescription.match(/(SS\d+|304|316|CS)\/(GRAPHITE|PTFE|VITON|EPDM)\/(SS\d+|304|316|CS)\/(SS\d+|304|316|CS)/i);
      if (fourMaterialMatch) {
        gasketMaterial = `${fourMaterialMatch[1]}/${fourMaterialMatch[2]}/${fourMaterialMatch[3]}/${fourMaterialMatch[4]}`;
      } else {
        // DB에서 가져온 정보로 구성 (fallback)
    if (material.gasket_details) {
      const materialType = material.gasket_details.material_type || '';
      const fillerMaterial = material.gasket_details.filler_material || '';
      
      if (materialType && fillerMaterial) {
        gasketMaterial = `${materialType}/${fillerMaterial}`;
      }
    }
    
        // 마지막으로 간단한 패턴
    if (!gasketMaterial) {
        const simpleMaterialMatch = cleanDescription.match(/(SS\d+|304|316)\s*[\/+]\s*(GRAPHITE|PTFE|VITON|EPDM)/i);
        if (simpleMaterialMatch) {
          gasketMaterial = `${simpleMaterialMatch[1]}/${simpleMaterialMatch[2]}`;
          }
        }
      }
    }
    
    // 두께 정보 별도 추출
    if (material.gasket_details && material.gasket_details.thickness) {
      gasketThickness = `${material.gasket_details.thickness}mm`;
    } else {
      // description에서 두께 추출 (4.5mm 패턴)
      const thicknessMatch = cleanDescription.match(/(\d+\.?\d*)\s*mm/i);
      if (thicknessMatch) {
        gasketThickness = `${thicknessMatch[1]}mm`;
      }
    }
    
    // 기타 상세 정보 (Fire Safe 등)
    const otherDetails = [];
    if (material.gasket_details && material.gasket_details.fire_safe) {
      otherDetails.push('Fire Safe');
    }
    
    detailInfo = otherDetails.join(', ');
  }

  // 수량 계산 (PIPE는 본 단위)
  let quantity = purchaseInfo.purchaseQuantity || material.quantity || 0;
  
  if (category === 'PIPE') {
    // PIPE의 경우 본 단위로 계산
    if (material.total_length) {
      // 총 길이를 6000mm로 나누어 본 수 계산
      quantity = Math.ceil(material.total_length / 6000);
    } else if (material.pipe_details && material.pipe_details.total_length_mm) {
      quantity = Math.ceil(material.pipe_details.total_length_mm / 6000);
    } else if (material.pipe_count) {
      quantity = material.pipe_count;
    }
  } else if (category === 'BOLT') {
    // BOLT의 경우 플랜지당 볼트 세트 수를 고려한 수량 계산 (BOM 페이지와 동일)
    const qty = Math.round(material.quantity || 0);
    
    // 플랜지당 볼트 세트 수 추출 (예: (8), (4))
    const boltDetails = material.bolt_details || {};
    let boltsPerFlange = boltDetails.dimensions?.bolts_per_flange || 1;
    
    // 백엔드에서 정보가 없으면 원본 설명에서 직접 추출
    if (boltsPerFlange === 1) {
      const description = material.original_description || '';
      const flangePattern = description.match(/\((\d+)\)/);
      if (flangePattern) {
        boltsPerFlange = parseInt(flangePattern[1]);
      }
    }
    
    // 실제 필요한 볼트 수 = 플랜지 수 × 플랜지당 볼트 세트 수
    const totalBoltsNeeded = qty * boltsPerFlange;
    const safetyQty = Math.ceil(totalBoltsNeeded * 1.05); // 5% 여유율
    const purchaseQty = Math.ceil(safetyQty / 4) * 4; // 4의 배수
    
    quantity = purchaseQty;
  }

  // 새로운 엑셀 양식: A~E 고정, F~O 카테고리별, P 납기일
  const base = {
    'TAGNO': '', // A열: 비워둠
    '품목명': itemName, // B열: 카테고리별 상세 타입
    '수량': quantity, // C열: 수량
    '통화구분': 'KRW', // D열: 기본값
    '단가': 1 // E열: 일괄 1로 설정
  };

  // 모든 카테고리에서 단위 컬럼 제거 (수량만 사용)

  // F~O열: 카테고리별 전용 컬럼 구성 (10개 컬럼)
  if (category === 'PIPE') {
    // 파이프 전용 컬럼 (F~O) - 끝단처리, 압력등급 제거
    base['크기'] = material.size_spec || '-'; // F열
    base['스케줄'] = schedule; // G열
    base['재질'] = grade; // H열
    base['제조방법'] = material.pipe_details?.manufacturing_method || '-'; // I열
    base['사용자요구'] = material.user_requirements?.join(', ') || ''; // J열 (분류기에서 추출)
    base['추가요청사항'] = material.user_requirement || ''; // K열 (사용자 입력)
    base['관리항목1'] = ''; // L열
    base['관리항목2'] = ''; // M열
    base['관리항목3'] = ''; // N열
    base['관리항목4'] = ''; // O열
  } else if (category === 'FITTING') {
    // 피팅 전용 컬럼 (F~O) - 새로운 구조
    base['크기'] = material.size_spec || '-'; // F열
    base['압력등급'] = pressure; // G열
    base['스케줄'] = schedule; // H열
    base['재질'] = grade; // I열
    base['사용자요구'] = material.user_requirements?.join(', ') || ''; // J열 (분류기에서 추출)
    base['추가요청사항'] = material.user_requirement || ''; // K열 (사용자 입력)
    base['관리항목1'] = ''; // L열
    base['관리항목2'] = ''; // M열
    base['관리항목3'] = ''; // N열
    base['관리항목4'] = ''; // O열
  } else if (category === 'FLANGE') {
    // 플랜지 전용 컬럼 (F~O) - 크기 이후에 페이싱, 압력, 스케줄, Material Grade, 추가요구사항 순서
    base['크기'] = material.size_spec || '-'; // F열
    
    // 페이싱 정보 (G열)
    const rawFacingType = material.flange_details?.facing_type || '';
    const facingTypeMap = {
      'RF': 'RAISED FACE',
      'RAISED_FACE': 'RAISED FACE',
      'FF': 'FLAT FACE',
      'FLAT_FACE': 'FLAT FACE',
      'RTJ': 'RING TYPE JOINT',
      'RING_TYPE_JOINT': 'RING TYPE JOINT'
    };
    base['페이싱'] = facingTypeMap[rawFacingType] || rawFacingType || '-'; // G열
    
    base['압력등급'] = pressure; // H열
    base['스케줄'] = schedule; // I열
    base['재질'] = grade; // J열
    base['추가요구사항'] = material.user_requirement || ''; // K열
    base['관리항목1'] = ''; // L열
    base['관리항목2'] = ''; // M열
    base['관리항목3'] = ''; // N열
    base['관리항목4'] = ''; // O열
  } else if (category === 'VALVE') {
    // 밸브 전용 컬럼 (F~O) - 새로운 구조
    base['크기'] = material.size_spec || material.main_nom || '-'; // F열
    base['압력등급'] = pressure; // G열
    base['브랜드'] = material.brand || '-'; // H열 (사용자 입력)
    base['추가정보'] = extractValveAdditionalInfo(cleanDescription); // I열 (3-WAY, DOUL PLATE 등)
    base['연결방식'] = material.connection_type || extractValveConnectionType(cleanDescription); // J열
    base['추가요청사항'] = material.user_requirement || ''; // K열
    base['관리항목1'] = ''; // L열
    base['관리항목2'] = ''; // M열
    base['관리항목3'] = ''; // N열
    base['관리항목4'] = ''; // O열
  } else if (category === 'GASKET') {
    // 가스켓 전용 컬럼 (F~O) - 재질을 2개로 분리
    // 재질 분리 로직: SS304/GRAPHITE/SS304/SS304 → 재질1: SS304/GRAPHITE, 재질2: /SS304/SS304
    let material1 = '-';
    let material2 = '-';
    
    if (gasketMaterial && gasketMaterial.includes('/')) {
      const materialParts = gasketMaterial.split('/');
      
      if (materialParts.length >= 4) {
        // 4개 재질인 경우: SS304/GRAPHITE/SS304/SS304
        material1 = `${materialParts[0]}/${materialParts[1]}`;
        material2 = `/${materialParts[2]}/${materialParts[3]}`;
      } else if (materialParts.length === 3) {
        // 3개 재질인 경우: SS304/GRAPHITE/SS304
        material1 = `${materialParts[0]}/${materialParts[1]}`;
        material2 = `/${materialParts[2]}`;
      } else if (materialParts.length === 2) {
        // 2개 재질인 경우: SS304/GRAPHITE
        material1 = gasketMaterial;
        material2 = '-';
      }
    } else if (gasketMaterial) {
      material1 = gasketMaterial;
    }
    
    base['크기'] = material.size_spec || '-'; // F열
    base['압력등급'] = pressure; // G열
    base['구조'] = grade; // H열: H/F/I/O, SWG 등
    base['재질1'] = material1; // I열: SS304/GRAPHITE
    base['재질2'] = material2; // J열: SS304/SS304
    base['두께'] = gasketThickness || '-'; // K열: 4.5mm
    base['사용자요구'] = detailInfo; // L열: 분류기에서 추출된 요구사항
    base['추가요청사항'] = material.user_requirement || ''; // M열: 사용자 입력 요구사항
    base['관리항목1'] = ''; // N열
    base['관리항목2'] = ''; // O열
        } else if (category === 'BOLT') {
    // 볼트 전용 컬럼 (F~O) - User Requirements와 Additional Request 분리
    base['크기'] = material.size_spec || '-'; // F열
    base['압력등급'] = pressure; // G열
    base['길이'] = schedule; // H열: 볼트는 길이 정보
    base['재질'] = grade; // I열
    base['사용자요구'] = detailInfo || '-'; // J열: ELEC.GALV 등 (분류기 추출)
    base['추가요청사항'] = material.user_requirement || ''; // K열: 사용자 입력
    base['관리항목1'] = ''; // L열
    base['관리항목2'] = ''; // M열
    base['관리항목3'] = ''; // N열
    base['관리항목4'] = ''; // O열
  } else if (category === 'SUPPORT') {
    // 서포트 전용 컬럼 (F~O) - 압력등급, 상세내역 제거
    base['크기'] = material.size_spec || material.main_nom || '-'; // F열
    base['재질'] = grade; // G열
    base['사용자요구'] = material.user_requirements?.join(', ') || ''; // H열 (분류기에서 추출)
    base['추가요청사항'] = material.user_requirement || ''; // I열 (사용자 입력)
    base['관리항목1'] = ''; // J열
    base['관리항목2'] = ''; // K열
    base['관리항목3'] = ''; // L열
    base['관리항목4'] = ''; // M열
    base['관리항목5'] = ''; // N열
    base['관리항목6'] = ''; // O열
  } else if (category === 'SPECIAL') {
    // 스페셜 전용 컬럼 (F~O) - Type은 품목명에 포함, 나머지는 항목별로 분리
    const description = cleanDescription || '';
    const parts = description
      .split(/[,;|\/]/)
      .map(part => part.trim())
      .filter(part => part.length > 0);
    
    base['도면'] = material.drawing_name || material.line_no || '-'; // F열
    base['상세1'] = parts[0] || '-'; // G열
    base['상세2'] = parts[1] || '-'; // H열
    base['상세3'] = parts[2] || '-'; // I열
    base['상세4'] = parts[3] || '-'; // J열
    base['추가요청사항'] = material.user_requirement || ''; // K열
    base['관리항목1'] = ''; // L열
    base['관리항목2'] = ''; // M열
    base['관리항목3'] = ''; // N열
    base['관리항목4'] = ''; // O열
  } else if (category === 'UNCLASSIFIED') {
    // 미분류 전용 컬럼 (F~O) - 원본 정보 그대로 표시
    base['크기'] = material.main_nom || material.size_spec || '-'; // F열
    base['도면'] = material.drawing_name || '-'; // G열
    base['라인번호'] = material.line_no || '-'; // H열
    base['추가요청사항'] = material.user_requirement || ''; // I열
    base['관리항목1'] = ''; // J열
    base['관리항목2'] = ''; // K열
    base['관리항목3'] = ''; // L열
    base['관리항목4'] = ''; // M열
    base['관리항목5'] = ''; // N열
    base['관리항목6'] = ''; // O열
  } else {
    // 기타 카테고리 기본 컬럼 (F~O) - 타입 제거, 품목명에 포함됨
    base['크기'] = material.size_spec || '-'; // F열
    base['압력등급'] = pressure; // G열
    base['스케줄'] = schedule; // H열
    base['재질'] = grade; // I열
    base['상세내역'] = detailInfo || '-'; // J열
    base['사용자요구'] = material.user_requirement || ''; // K열
    base['관리항목1'] = ''; // L열
    base['관리항목2'] = ''; // M열
    base['관리항목3'] = ''; // N열
    base['관리항목4'] = ''; // O열
  }

  // P열: 납기일 (고정)
  base['납기일(YYYY-MM-DD)'] = new Date().toISOString().split('T')[0];

  // 비교 모드인 경우 추가 정보
  if (includeComparison) {
    if (material.previous_quantity !== undefined) {
      const prevPurchaseInfo = calculatePurchaseQuantity({
        ...material,
        quantity: material.previous_quantity,
        totalLength: material.previousTotalLength || 0
      });
      
      base['이전수량'] = prevPurchaseInfo.purchaseQuantity || 0;
      base['수량변경'] = (purchaseInfo.purchaseQuantity - prevPurchaseInfo.purchaseQuantity);
    }
    
    base['변경유형'] = material.change_type || (
      material.previous_quantity !== undefined ? '수량 변경' :
      material.quantity_change === undefined ? '신규' : '변경'
    );
  }

  return base;
};

/**
 * 일반 자재 목록 엑셀 내보내기
 */
export const exportMaterialsToExcel = (materials, filename, additionalInfo = {}) => {
  try {
    console.log('🔧 exportMaterialsToExcel 시작:', materials.length, '개 자재');
    
    // 카테고리별로 그룹화
    const categoryGroups = groupMaterialsByCategory(materials);
    console.log('📁 카테고리별 그룹:', Object.keys(categoryGroups).map(k => `${k}: ${categoryGroups[k].length}개`));
    
    // 전체 자재 합치기 (먼저 계산)
    const consolidatedMaterials = consolidateMaterials(materials);
    console.log('📦 합쳐진 자재:', consolidatedMaterials.length, '개');
    
    // 새 워크북 생성
    const workbook = XLSX.utils.book_new();
    
    // 카테고리별 시트 생성 (합쳐진 자재)
    Object.entries(categoryGroups).forEach(([category, items]) => {
      console.log(`📄 ${category} 시트 생성 중... (${items.length}개 자재)`);
      const consolidatedItems = consolidateMaterials(items);
      console.log(`  → 합쳐진 결과: ${consolidatedItems.length}개`);
      
      const formattedItems = consolidatedItems.map(material => formatMaterialForExcel(material));
      console.log(`  → 포맷 완료: ${formattedItems.length}개`);
      
      if (formattedItems.length > 0) {
        const categorySheet = XLSX.utils.json_to_sheet(formattedItems);
        
        // 헤더 스타일링 (연하늘색 배경)
        const range = XLSX.utils.decode_range(categorySheet['!ref']);
        
        // 헤더 행에 스타일 적용 (첫 번째 행)
        for (let col = range.s.c; col <= range.e.c; col++) {
          const cellRef = XLSX.utils.encode_cell({ r: 0, c: col });
          
          if (categorySheet[cellRef]) {
            // 기존 셀 값 유지하면서 스타일만 추가
            const cellValue = categorySheet[cellRef].v;
            const cellType = categorySheet[cellRef].t;
            
            categorySheet[cellRef] = {
              v: cellValue,
              t: cellType || 's',
              s: {
                fill: {
                  patternType: "solid",
                  fgColor: { rgb: "B3D9FF" }
                },
                font: {
                  bold: true,
                  color: { rgb: "000000" },
                  sz: 12,
                  name: "맑은 고딕"
                },
                alignment: {
                  horizontal: "center",
                  vertical: "center"
                },
                border: {
                  top: { style: "thin", color: { rgb: "666666" } },
                  bottom: { style: "thin", color: { rgb: "666666" } },
                  left: { style: "thin", color: { rgb: "666666" } },
                  right: { style: "thin", color: { rgb: "666666" } }
                }
              }
            };
          }
        }
        
        // 컬럼 너비 자동 조정
        const colWidths = [];
        if (formattedItems.length > 0) {
          const headers = Object.keys(formattedItems[0]);
          
          headers.forEach((header, index) => {
            let maxWidth = header.length; // 헤더 길이
            
            // 각 행의 데이터 길이 확인
            formattedItems.forEach(item => {
              const cellValue = String(item[header] || '');
              maxWidth = Math.max(maxWidth, cellValue.length);
            });
            
            // 최소 10, 최대 50으로 제한
            colWidths[index] = { wch: Math.min(Math.max(maxWidth + 2, 10), 50) };
          });
        }
        
        categorySheet['!cols'] = colWidths;
        
        // 시트명에서 특수문자 제거 (엑셀 시트명 규칙)
        const sheetName = category.replace(/[\\\/\*\?\[\]]/g, '_').substring(0, 31);
        XLSX.utils.book_append_sheet(workbook, categorySheet, sheetName);
      }
    });
    
    // 워크북 속성 설정 (스타일 지원)
    workbook.Props = {
      Title: "자재 목록",
      Subject: "TK-MP-Project 자재 관리",
      Author: "TK-MP System",
      CreatedDate: new Date()
    };
    
    // 파일 저장 (스타일 포함)
    const excelBuffer = XLSX.write(workbook, { 
      bookType: 'xlsx', 
      type: 'array',
      cellStyles: true // 스타일 활성화
    });
    const data = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    
    const finalFilename = `${filename}_${new Date().toISOString().split('T')[0]}.xlsx`;
    saveAs(data, finalFilename);
    
    return true;
  } catch (error) {
    console.error('엑셀 내보내기 실패:', error);
    alert('엑셀 파일 생성에 실패했습니다: ' + error.message);
    return false;
  }
};

/**
 * 리비전 비교 결과 엑셀 내보내기
 */
export const exportComparisonToExcel = (comparisonData, filename, additionalInfo = {}) => {
  try {
    const { summary, new_items = [], modified_items = [], removed_items = [] } = comparisonData;
    
    // 새 워크북 생성
    const workbook = XLSX.utils.book_new();
    
    // 요약 시트
    const summaryData = [
      ['리비전 비교 정보', ''],
      ['Job No', additionalInfo.jobNo || ''],
      ['현재 리비전', additionalInfo.currentRevision || ''],
      ['이전 리비전', additionalInfo.previousRevision || ''],
      ['비교일', new Date().toLocaleDateString()],
      ['', ''],
      ['비교 결과 요약', ''],
      ['구분', '건수'],
      ['총 현재 자재', summary?.total_current_items || 0],
      ['총 이전 자재', summary?.total_previous_items || 0],
      ['신규 자재', summary?.new_items_count || 0],
      ['변경 자재', summary?.modified_items_count || 0],
      ['삭제 자재', summary?.removed_items_count || 0]
    ];
    
    const summarySheet = XLSX.utils.aoa_to_sheet(summaryData);
    XLSX.utils.book_append_sheet(workbook, summarySheet, '비교 요약');
    
    // 신규 자재 시트 (카테고리별, 합쳐진 자재)
    if (new_items.length > 0) {
      const newItemsGroups = groupMaterialsByCategory(new_items);
      Object.entries(newItemsGroups).forEach(([category, items]) => {
        const consolidatedItems = consolidateMaterials(items, true);
        const formattedItems = consolidatedItems.map(material => formatMaterialForExcel(material, true));
        const sheet = XLSX.utils.json_to_sheet(formattedItems);
        const sheetName = `신규_${category.replace(/[\\\/\*\?\[\]]/g, '_')}`.substring(0, 31);
        XLSX.utils.book_append_sheet(workbook, sheet, sheetName);
      });
    }
    
    // 변경 자재 시트 (카테고리별, 합쳐진 자재)
    if (modified_items.length > 0) {
      const modifiedItemsGroups = groupMaterialsByCategory(modified_items);
      Object.entries(modifiedItemsGroups).forEach(([category, items]) => {
        const consolidatedItems = consolidateMaterials(items, true);
        const formattedItems = consolidatedItems.map(material => formatMaterialForExcel(material, true));
        const sheet = XLSX.utils.json_to_sheet(formattedItems);
        const sheetName = `변경_${category.replace(/[\\\/\*\?\[\]]/g, '_')}`.substring(0, 31);
        XLSX.utils.book_append_sheet(workbook, sheet, sheetName);
      });
    }
    
    // 삭제 자재 시트 (카테고리별, 합쳐진 자재)
    if (removed_items.length > 0) {
      const removedItemsGroups = groupMaterialsByCategory(removed_items);
      Object.entries(removedItemsGroups).forEach(([category, items]) => {
        const consolidatedItems = consolidateMaterials(items, true);
        const formattedItems = consolidatedItems.map(material => formatMaterialForExcel(material, true));
        const sheet = XLSX.utils.json_to_sheet(formattedItems);
        const sheetName = `삭제_${category.replace(/[\\\/\*\?\[\]]/g, '_')}`.substring(0, 31);
        XLSX.utils.book_append_sheet(workbook, sheet, sheetName);
      });
    }
    
    // 파일 저장
    const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
    const data = new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
    
    const finalFilename = `${filename}_비교결과_${new Date().toISOString().split('T')[0]}.xlsx`;
    saveAs(data, finalFilename);
    
    return true;
  } catch (error) {
    console.error('엑셀 내보내기 실패:', error);
    alert('엑셀 파일 생성에 실패했습니다: ' + error.message);
    return false;
  }
}; 
// 엑셀 Blob 생성 함수 (서버 업로드용)
export const createExcelBlob = async (materials, filename, options = {}) => {
  try {
    console.log('📊 createExcelBlob 시작:', materials.length, '개 자료');
    
    // 기존 exportMaterialsToExcel 로직을 사용하되 Blob만 반환
    const formattedData = materials.map(material => formatMaterialForExcel(material, options.category));
    
    // 헤더 추출 및 순서 정의 (모든 카테고리에서 단위 제거)
    const allHeaders = Array.from(new Set(formattedData.flatMap(Object.keys)));
    const fixedHeaders = ['TAGNO', '품목명', '수량', '통화구분', '단가'];
    const categorySpecificHeadersOrder = {
      'PIPE': ['크기', '스케줄', '재질', '제조방법', '사용자요구', '추가요청사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4'],
      'FITTING': ['크기', '압력등급', '스케줄', '재질', '사용자요구', '추가요청사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4'],
      'FLANGE': ['크기', '페이싱', '압력등급', '스케줄', '재질', '추가요구사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4'],
      'VALVE': ['크기', '압력등급', '브랜드', '추가정보', '연결방식', '추가요청사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4'],
      'GASKET': ['크기', '압력등급', '구조', '재질1', '재질2', '두께', '사용자요구', '추가요청사항', '관리항목1', '관리항목2'],
      'BOLT': ['크기', '압력등급', '길이', '재질', '사용자요구', '추가요청사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4'],
      'SUPPORT': ['크기', '재질', '사용자요구', '추가요청사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4', '관리항목5', '관리항목6'],
      'SPECIAL': ['도면', '상세1', '상세2', '상세3', '상세4', '추가요청사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4'],
      'UNCLASSIFIED': ['크기', '도면', '라인번호', '추가요청사항', '관리항목1', '관리항목2', '관리항목3', '관리항목4', '관리항목5', '관리항목6'],
    };

    const deliveryDateHeader = '납기일(YYYY-MM-DD)';
    let orderedHeaders = [...fixedHeaders];
    if (categorySpecificHeadersOrder[options.category]) {
      orderedHeaders = orderedHeaders.concat(categorySpecificHeadersOrder[options.category]);
    }
    orderedHeaders.push(deliveryDateHeader);

    // 데이터 정렬
    const finalData = formattedData.map(row => {
      const newRow = {};
      orderedHeaders.forEach(header => {
        newRow[header] = row[header] !== undefined ? row[header] : '';
      });
      return newRow;
    });

    // XLSX 워크북 생성
    const workbook = XLSX.utils.book_new();
    const worksheet = XLSX.utils.json_to_sheet(finalData, { header: orderedHeaders });

    // 컬럼 너비 자동 조정
    const colWidths = orderedHeaders.map(header => ({
      wch: Math.max(
        header.toString().length,
        ...finalData.map(row => (row[header] ? row[header].toString().length : 0))
      ) + 2
    }));
    worksheet['!cols'] = colWidths;

    XLSX.utils.book_append_sheet(workbook, worksheet, options.category || 'Materials');

    // Blob 생성
    const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
    const blob = new Blob([excelBuffer], { 
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
    });
    
    console.log('✅ createExcelBlob 완료:', blob.size, 'bytes');
    return blob;

  } catch (error) {
    console.error('엑셀 Blob 생성 실패:', error);
    throw error;
  }
};
