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 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 = '';
  if (category === 'PIPE') {
    itemName = material.pipe_details?.manufacturing_method || 'PIPE';
  } else if (category === 'FITTING') {
    itemName = material.fitting_details?.fitting_type || 'FITTING';
  } else if (category === 'FLANGE') {
    itemName = 'FLANGE';
  } else if (category === 'VALVE') {
    itemName = 'VALVE';
  } else if (category === 'GASKET') {
    // 가스켓 상세 타입 추출
    if (material.gasket_details) {
      const gasketType = material.gasket_details.gasket_type || '';
      const gasketSubtype = material.gasket_details.gasket_subtype || '';
      
      if (gasketSubtype && gasketSubtype !== gasketType) {
        itemName = gasketSubtype;
      } else if (gasketType) {
        itemName = gasketType;
      } else {
        itemName = 'GASKET';
      }
    } else {
      // gasket_details가 없으면 description에서 추출
      if (cleanDescription.includes('SWG') || cleanDescription.includes('SPIRAL')) {
        itemName = 'SWG';
      } else if (cleanDescription.includes('RTJ') || cleanDescription.includes('RING')) {
        itemName = 'RTJ';
      } else if (cleanDescription.includes('FF') || cleanDescription.includes('FULL FACE')) {
        itemName = 'FF';
      } else if (cleanDescription.includes('RF') || cleanDescription.includes('RAISED')) {
        itemName = 'RF';
      } else {
        itemName = 'GASKET';
      }
    }
  } else if (category === 'BOLT') {
    itemName = 'BOLT';
  } else {
    itemName = category || 'UNKNOWN';
  }
  
  // 압력 등급 추출 (카테고리별 처리)
  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/i,  // 50mm
      /(\d+(?:\.\d+)?)\s*MM/i,  // 50MM
      /,\s*(\d+(?:\.\d+)?)\s*LG/i, // ", 145.0000 LG" 형태
      /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();
    }
  }
  
  // 카테고리별 상세 정보 추출
  let detailInfo = '';
  let gasketMaterial = '';
  let gasketThickness = '';
  
  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') {
    // 실제 재질 구성 정보 (SS304/GRAPHITE/SS304/SS304)
    if (material.gasket_details) {
      const materialType = material.gasket_details.material_type || '';
      const fillerMaterial = material.gasket_details.filler_material || '';
      
      if (materialType && fillerMaterial) {
        // DB에서 가져온 정보로 구성
        gasketMaterial = `${materialType}/${fillerMaterial}`;
      }
    }
    
    // gasket_details가 없거나 불완전하면 description에서 추출
    if (!gasketMaterial) {
      // SS304/GRAPHITE/SS304/SS304 패턴 추출
      const fullMaterialMatch = cleanDescription.match(/SS304\/GRAPHITE\/SS304\/SS304/i);
      if (fullMaterialMatch) {
        gasketMaterial = 'SS304/GRAPHITE/SS304/SS304';
      } else {
        // 간단한 패턴 (SS304/GRAPHITE)
        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(', ');
  }

  // 새로운 엑셀 양식에 맞춘 데이터 구조
  const base = {
    'TAGNO': '', // 비워둠
    '품목명': itemName,
    '수량': purchaseInfo.purchaseQuantity || material.quantity || 0,
    '통화구분': 'KRW', // 기본값
    '단가': 1, // 일괄 1로 설정
    '크기': material.size_spec || '-',
    '압력등급': pressure
  };

  // 카테고리별 전용 컬럼 구성
  if (category === 'GASKET') {
    // 가스켓 전용 컬럼 순서
    base['타입/구조'] = grade; // H/F/I/O, SWG 등 (스케줄 대신)
    base['재질'] = gasketMaterial || '-'; // SS304/GRAPHITE/SS304/SS304
    base['두께'] = gasketThickness || '-'; // 4.5mm
    base['사용자요구'] = material.user_requirement || '';
    base['관리항목8'] = ''; // 빈칸
    base['관리항목9'] = ''; // 빈칸
    base['관리항목10'] = ''; // 빈칸
    base['납기일(YYYY-MM-DD)'] = new Date().toISOString().split('T')[0]; // 가장 마지막
        } else if (category === 'BOLT') {
          // 볼트 전용 컬럼 순서 (스케줄 → 길이)
          base['길이'] = schedule; // 볼트는 길이 정보
          base['재질'] = grade;
          base['추가요구'] = detailInfo || '-'; // 상세내역 → 추가요구로 변경
          base['사용자요구'] = material.user_requirement || '';
          base['관리항목1'] = ''; // 빈칸
          base['관리항목7'] = ''; // 빈칸
          base['관리항목8'] = ''; // 빈칸
          base['관리항목9'] = ''; // 빈칸
          base['관리항목10'] = ''; // 빈칸
          base['납기일(YYYY-MM-DD)'] = new Date().toISOString().split('T')[0]; // 가장 마지막
        } else {
    // 다른 카테고리는 기존 방식
    base['스케줄'] = schedule;
    base['재질'] = grade;
    base['상세내역'] = detailInfo || '-';
    base['사용자요구'] = material.user_requirement || '';
    base['관리항목1'] = ''; // 빈칸
    base['관리항목7'] = ''; // 빈칸
    base['관리항목8'] = ''; // 빈칸
    base['관리항목9'] = ''; // 빈칸
    base['관리항목10'] = ''; // 빈칸
    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 {
    // 카테고리별로 그룹화
    const categoryGroups = groupMaterialsByCategory(materials);
    
    // 전체 자재 합치기 (먼저 계산)
    const consolidatedMaterials = consolidateMaterials(materials);
    
    // 새 워크북 생성
    const workbook = XLSX.utils.book_new();
    
    // 카테고리별 시트 생성 (합쳐진 자재)
    Object.entries(categoryGroups).forEach(([category, items]) => {
      const consolidatedItems = consolidateMaterials(items);
      const formattedItems = consolidatedItems.map(material => formatMaterialForExcel(material));
      
      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;
  }
}; 