/**
 * PIPE 시스템 공통 유틸리티
 * 
 * 모든 PIPE 관련 컴포넌트에서 공통으로 사용되는 함수들을 모아놓은 유틸리티 모듈
 */

// ========== PIPE 상수 정의 ==========

export const PIPE_CONSTANTS = {
    // 길이 관련
    STANDARD_PIPE_LENGTH_MM: 6000,  // 표준 파이프 길이 (6M)
    CUTTING_LOSS_PER_CUT_MM: 2,     // 절단당 손실 (2mm)
    
    // 분류 관련
    PIPE_CATEGORY: "PIPE",
    
    // 끝단 처리 타입
    END_PREPARATION_TYPES: {
        "무개선": "PLAIN",
        "한개선": "SINGLE_BEVEL", 
        "양개선": "DOUBLE_BEVEL"
    },
    
    // 상태 관련
    REVISION_TYPES: {
        NO_REVISION: "no_revision",
        PRE_CUTTING_PLAN: "pre_cutting_plan", 
        POST_CUTTING_PLAN: "post_cutting_plan"
    },
    
    CHANGE_TYPES: {
        ADDED: "added",
        REMOVED: "removed", 
        MODIFIED: "modified",
        UNCHANGED: "unchanged"
    },
    
    // UI 관련
    STATUS_COLORS: {
        success: '#28a745',
        warning: '#ffc107',
        danger: '#dc3545',
        info: '#17a2b8',
        primary: '#007bff'
    }
};

// ========== 계산 유틸리티 ==========

export class PipeCalculator {
    /**
     * PIPE 구매 수량 계산
     * @param {Array} materials - PIPE 자재 리스트
     * @returns {Object} 계산 결과
     */
    static calculatePipePurchaseQuantity(materials) {
        let totalBomLength = 0;
        let cuttingCount = 0;
        const pipeDetails = [];
        
        materials.forEach(material => {
            const lengthMm = parseFloat(material.length || material.length_mm || 0);
            const quantity = parseInt(material.quantity || 1);
            
            if (lengthMm > 0) {
                const totalLength = lengthMm * quantity;
                totalBomLength += totalLength;
                cuttingCount += quantity;
                
                pipeDetails.push({
                    description: material.description || '',
                    originalDescription: material.original_description || '',
                    drawingName: material.drawing_name || '',
                    lineNo: material.line_no || '',
                    lengthMm: lengthMm,
                    quantity: quantity,
                    totalLength: totalLength
                });
            }
        });
        
        // 절단 손실 계산
        const cuttingLoss = cuttingCount * PIPE_CONSTANTS.CUTTING_LOSS_PER_CUT_MM;
        
        // 총 필요 길이
        const requiredLength = totalBomLength + cuttingLoss;
        
        // 6M 단위로 올림 계산
        const pipesNeeded = requiredLength > 0 ? Math.ceil(requiredLength / PIPE_CONSTANTS.STANDARD_PIPE_LENGTH_MM) : 0;
        const totalPurchaseLength = pipesNeeded * PIPE_CONSTANTS.STANDARD_PIPE_LENGTH_MM;
        const wasteLength = pipesNeeded > 0 ? totalPurchaseLength - requiredLength : 0;
        
        return {
            bomQuantity: totalBomLength,
            cuttingCount: cuttingCount,
            cuttingLoss: cuttingLoss,
            requiredLength: requiredLength,
            pipesCount: pipesNeeded,
            calculatedQty: totalPurchaseLength,
            wasteLength: wasteLength,
            utilizationRate: totalPurchaseLength > 0 ? (requiredLength / totalPurchaseLength * 100) : 0,
            unit: 'mm',
            pipeDetails: pipeDetails,
            summary: {
                totalMaterials: materials.length,
                totalDrawings: new Set(materials.map(m => m.drawing_name).filter(Boolean)).size,
                averageLength: materials.length > 0 ? totalBomLength / materials.length : 0
            }
        };
    }
    
    /**
     * 길이 변화량 계산
     * @param {number} oldLength - 이전 길이
     * @param {number} newLength - 새로운 길이
     * @returns {Object} 변화량 정보
     */
    static calculateLengthDifference(oldLength, newLength) {
        const difference = newLength - oldLength;
        const percentage = oldLength > 0 ? (difference / oldLength * 100) : 0;
        
        return {
            oldLength: oldLength,
            newLength: newLength,
            difference: difference,
            percentage: percentage,
            changeType: difference > 0 ? 'increased' : difference < 0 ? 'decreased' : 'unchanged'
        };
    }
}

// ========== 비교 유틸리티 ==========

export class PipeComparator {
    /**
     * 단관 데이터 비교
     * @param {Array} oldSegments - 이전 단관 데이터
     * @param {Array} newSegments - 새로운 단관 데이터
     * @returns {Object} 비교 결과
     */
    static comparePipeSegments(oldSegments, newSegments) {
        // 키 생성 함수
        const createSegmentKey = (segment) => {
            return [
                segment.drawing_name || '',
                segment.material_grade || '',
                segment.length || 0,
                segment.end_preparation || '무개선'
            ].join('|');
        };
        
        // 기존 데이터를 키로 매핑
        const oldMap = {};
        oldSegments.forEach(segment => {
            const key = createSegmentKey(segment);
            if (!oldMap[key]) oldMap[key] = [];
            oldMap[key].push(segment);
        });
        
        // 새로운 데이터를 키로 매핑
        const newMap = {};
        newSegments.forEach(segment => {
            const key = createSegmentKey(segment);
            if (!newMap[key]) newMap[key] = [];
            newMap[key].push(segment);
        });
        
        // 비교 결과 생성
        const changes = {
            added: [],
            removed: [],
            modified: [],
            unchanged: []
        };
        
        const allKeys = new Set([...Object.keys(oldMap), ...Object.keys(newMap)]);
        
        allKeys.forEach(key => {
            const oldCount = oldMap[key] ? oldMap[key].length : 0;
            const newCount = newMap[key] ? newMap[key].length : 0;
            
            if (oldCount === 0) {
                // 새로 추가된 항목
                newMap[key].forEach(segment => {
                    changes.added.push({
                        ...segment,
                        changeType: 'added',
                        quantityChange: newCount
                    });
                });
            } else if (newCount === 0) {
                // 삭제된 항목
                oldMap[key].forEach(segment => {
                    changes.removed.push({
                        ...segment,
                        changeType: 'removed',
                        quantityChange: -oldCount
                    });
                });
            } else if (oldCount !== newCount) {
                // 수량이 변경된 항목
                const baseSegment = newMap[key][0] || oldMap[key][0];
                changes.modified.push({
                    ...baseSegment,
                    changeType: 'modified',
                    oldQuantity: oldCount,
                    newQuantity: newCount,
                    quantityChange: newCount - oldCount
                });
            } else {
                // 변경되지 않은 항목
                const baseSegment = newMap[key][0];
                changes.unchanged.push({
                    ...baseSegment,
                    changeType: 'unchanged',
                    quantity: oldCount
                });
            }
        });
        
        // 통계 생성
        const stats = {
            totalOld: oldSegments.length,
            totalNew: newSegments.length,
            addedCount: changes.added.length,
            removedCount: changes.removed.length,
            modifiedCount: changes.modified.length,
            unchangedCount: changes.unchanged.length,
            changedDrawings: new Set([
                ...changes.added,
                ...changes.removed,
                ...changes.modified
            ].map(item => item.drawing_name).filter(Boolean)).size
        };
        
        return {
            changes: changes,
            statistics: stats,
            hasChanges: stats.addedCount + stats.removedCount + stats.modifiedCount > 0
        };
    }
}

// ========== 검증 유틸리티 ==========

export class PipeValidator {
    /**
     * PIPE 데이터 유효성 검증
     * @param {Object} pipeData - 검증할 PIPE 데이터
     * @returns {Object} 검증 결과
     */
    static validatePipeData(pipeData) {
        const errors = [];
        const warnings = [];
        
        // 필수 필드 검증
        const requiredFields = ['drawing_name', 'material_grade', 'length'];
        requiredFields.forEach(field => {
            if (!pipeData[field]) {
                errors.push(`필수 필드 누락: ${field}`);
            }
        });
        
        // 길이 검증
        const length = parseFloat(pipeData.length || 0);
        if (length <= 0) {
            errors.push("길이는 0보다 커야 합니다");
        } else if (length > 20000) {  // 20m 초과시 경고
            warnings.push(`길이가 비정상적으로 큽니다: ${length}mm`);
        }
        
        // 수량 검증
        const quantity = parseInt(pipeData.quantity || 1);
        if (quantity <= 0) {
            errors.push("수량은 0보다 커야 합니다");
        }
        
        // 도면명 검증
        const drawingName = pipeData.drawing_name || '';
        if (drawingName === 'UNKNOWN') {
            warnings.push("도면명이 지정되지 않았습니다");
        }
        
        return {
            isValid: errors.length === 0,
            errors: errors,
            warnings: warnings,
            errorCount: errors.length,
            warningCount: warnings.length
        };
    }
    
    /**
     * Cutting Plan 데이터 전체 검증
     * @param {Array} cuttingPlan - Cutting Plan 데이터 리스트
     * @returns {Object} 검증 결과
     */
    static validateCuttingPlanData(cuttingPlan) {
        const totalErrors = [];
        const totalWarnings = [];
        let validItems = 0;
        
        cuttingPlan.forEach((item, index) => {
            const validation = PipeValidator.validatePipeData(item);
            
            if (validation.isValid) {
                validItems++;
            } else {
                validation.errors.forEach(error => {
                    totalErrors.push(`항목 ${index + 1}: ${error}`);
                });
            }
            
            validation.warnings.forEach(warning => {
                totalWarnings.push(`항목 ${index + 1}: ${warning}`);
            });
        });
        
        return {
            isValid: totalErrors.length === 0,
            totalItems: cuttingPlan.length,
            validItems: validItems,
            invalidItems: cuttingPlan.length - validItems,
            errors: totalErrors,
            warnings: totalWarnings,
            validationRate: cuttingPlan.length > 0 ? (validItems / cuttingPlan.length * 100) : 0
        };
    }
}

// ========== 포맷팅 유틸리티 ==========

export class PipeFormatter {
    /**
     * 길이 포맷팅
     * @param {number} lengthMm - 길이 (mm)
     * @param {string} unit - 표시 단위
     * @returns {string} 포맷된 길이 문자열
     */
    static formatLength(lengthMm, unit = 'mm') {
        if (unit === 'm') {
            return `${(lengthMm / 1000).toFixed(3)}m`;
        } else if (unit === 'mm') {
            return `${Math.round(lengthMm)}mm`;
        } else {
            return `${lengthMm}`;
        }
    }
    
    /**
     * PIPE 설명 포맷팅
     * @param {Object} pipeData - PIPE 데이터
     * @returns {string} 포맷된 설명
     */
    static formatPipeDescription(pipeData) {
        const parts = [];
        
        if (pipeData.material_grade) {
            parts.push(pipeData.material_grade);
        }
        
        if (pipeData.main_nom) {
            parts.push(pipeData.main_nom);
        }
        
        if (pipeData.schedule) {
            parts.push(pipeData.schedule);
        }
        
        if (pipeData.length) {
            parts.push(PipeFormatter.formatLength(pipeData.length));
        }
        
        return parts.length > 0 ? parts.join(' ') : 'PIPE';
    }
    
    /**
     * 변경사항 요약 포맷팅
     * @param {Object} changes - 변경사항 딕셔너리
     * @returns {string} 포맷된 요약 문자열
     */
    static formatChangeSummary(changes) {
        const summaryParts = [];
        
        if (changes.added && changes.added.length > 0) {
            summaryParts.push(`추가 ${changes.added.length}개`);
        }
        
        if (changes.removed && changes.removed.length > 0) {
            summaryParts.push(`삭제 ${changes.removed.length}개`);
        }
        
        if (changes.modified && changes.modified.length > 0) {
            summaryParts.push(`수정 ${changes.modified.length}개`);
        }
        
        if (summaryParts.length === 0) {
            return "변경사항 없음";
        }
        
        return summaryParts.join(', ');
    }
    
    /**
     * 숫자를 천 단위 콤마로 포맷팅
     * @param {number} number - 포맷할 숫자
     * @returns {string} 포맷된 숫자 문자열
     */
    static formatNumber(number) {
        return new Intl.NumberFormat('ko-KR').format(number);
    }
    
    /**
     * 백분율 포맷팅
     * @param {number} value - 백분율 값
     * @param {number} decimals - 소수점 자리수
     * @returns {string} 포맷된 백분율 문자열
     */
    static formatPercentage(value, decimals = 1) {
        return `${value.toFixed(decimals)}%`;
    }
}

// ========== UI 유틸리티 ==========

export class PipeUIUtils {
    /**
     * 변경 타입에 따른 색상 반환
     * @param {string} changeType - 변경 타입
     * @returns {string} CSS 색상 코드
     */
    static getChangeTypeColor(changeType) {
        const colors = {
            added: PIPE_CONSTANTS.STATUS_COLORS.success,
            removed: PIPE_CONSTANTS.STATUS_COLORS.danger,
            modified: PIPE_CONSTANTS.STATUS_COLORS.warning,
            unchanged: PIPE_CONSTANTS.STATUS_COLORS.info
        };
        
        return colors[changeType] || PIPE_CONSTANTS.STATUS_COLORS.primary;
    }
    
    /**
     * 변경 타입에 따른 아이콘 반환
     * @param {string} changeType - 변경 타입
     * @returns {string} 아이콘 클래스명
     */
    static getChangeTypeIcon(changeType) {
        const icons = {
            added: '➕',
            removed: '➖',
            modified: '🔄',
            unchanged: '✅'
        };
        
        return icons[changeType] || '❓';
    }
    
    /**
     * 상태에 따른 배지 스타일 생성
     * @param {string} status - 상태
     * @returns {Object} 스타일 객체
     */
    static createStatusBadge(status) {
        const styles = {
            success: {
                backgroundColor: PIPE_CONSTANTS.STATUS_COLORS.success,
                color: 'white'
            },
            warning: {
                backgroundColor: PIPE_CONSTANTS.STATUS_COLORS.warning,
                color: 'black'
            },
            danger: {
                backgroundColor: PIPE_CONSTANTS.STATUS_COLORS.danger,
                color: 'white'
            },
            info: {
                backgroundColor: PIPE_CONSTANTS.STATUS_COLORS.info,
                color: 'white'
            }
        };
        
        return {
            padding: '4px 8px',
            borderRadius: '4px',
            fontSize: '12px',
            fontWeight: 'bold',
            display: 'inline-block',
            ...styles[status]
        };
    }
}

// ========== 데이터 변환 유틸리티 ==========

export class PipeDataTransformer {
    /**
     * API 응답 데이터를 UI용 데이터로 변환
     * @param {Object} apiData - API 응답 데이터
     * @returns {Object} 변환된 데이터
     */
    static transformApiDataForUI(apiData) {
        if (!apiData) return null;
        
        return {
            ...apiData,
            formattedLength: PipeFormatter.formatLength(apiData.length || 0),
            formattedDescription: PipeFormatter.formatPipeDescription(apiData),
            changeTypeColor: PipeUIUtils.getChangeTypeColor(apiData.change_type),
            changeTypeIcon: PipeUIUtils.getChangeTypeIcon(apiData.change_type)
        };
    }
    
    /**
     * UI 데이터를 API 전송용 데이터로 변환
     * @param {Object} uiData - UI 데이터
     * @returns {Object} 변환된 데이터
     */
    static transformUIDataForAPI(uiData) {
        const apiData = { ...uiData };
        
        // UI 전용 필드 제거
        delete apiData.formattedLength;
        delete apiData.formattedDescription;
        delete apiData.changeTypeColor;
        delete apiData.changeTypeIcon;
        
        // 숫자 타입 변환
        if (apiData.length) {
            apiData.length = parseFloat(apiData.length);
        }
        if (apiData.quantity) {
            apiData.quantity = parseInt(apiData.quantity);
        }
        
        return apiData;
    }
}

// ========== 로깅 유틸리티 ==========

export class PipeLogger {
    /**
     * PIPE 작업 로깅
     * @param {string} operation - 작업 유형
     * @param {string} jobNo - 작업 번호
     * @param {Object} details - 상세 정보
     */
    static logPipeOperation(operation, jobNo, details = {}) {
        const message = `🔧 PIPE ${operation} | Job: ${jobNo}`;
        
        if (Object.keys(details).length > 0) {
            const detailParts = Object.entries(details).map(([key, value]) => `${key}: ${value}`);
            console.log(`${message} | ${detailParts.join(', ')}`);
        } else {
            console.log(message);
        }
    }
    
    /**
     * PIPE 오류 로깅
     * @param {string} operation - 작업 유형
     * @param {string} jobNo - 작업 번호
     * @param {Error} error - 오류 객체
     * @param {Object} context - 컨텍스트 정보
     */
    static logPipeError(operation, jobNo, error, context = {}) {
        const message = `❌ PIPE ${operation} 실패 | Job: ${jobNo} | Error: ${error.message}`;
        
        if (Object.keys(context).length > 0) {
            const contextParts = Object.entries(context).map(([key, value]) => `${key}: ${value}`);
            console.error(`${message} | Context: ${contextParts.join(', ')}`);
        } else {
            console.error(message);
        }
        
        console.error(error);
    }
}

// 기본 export
export default {
    PIPE_CONSTANTS,
    PipeCalculator,
    PipeComparator,
    PipeValidator,
    PipeFormatter,
    PipeUIUtils,
    PipeDataTransformer,
    PipeLogger
};
