/**
 * 프론트엔드 오류 로깅 시스템
 * 테스트 및 디버깅을 위한 오류 수집 및 전송
 */

import api from '../api';

class ErrorLogger {
    constructor() {
        this.isEnabled = false; // 긴급 비활성화 - 무한 루프 방지
        this.maxRetries = 3;
        this.retryDelay = 1000; // 1초
        this.errorQueue = [];
        this.isProcessing = false;
        
        // 전역 오류 핸들러 설정
        // this.setupGlobalErrorHandlers(); // 비활성화
    }

    /**
     * 전역 오류 핸들러 설정
     */
    setupGlobalErrorHandlers() {
        // JavaScript 오류 캐치
        window.addEventListener('error', (event) => {
            this.logError({
                type: 'javascript_error',
                message: event.message,
                filename: event.filename,
                lineno: event.lineno,
                colno: event.colno,
                stack: event.error?.stack,
                timestamp: new Date().toISOString(),
                url: window.location.href,
                userAgent: navigator.userAgent
            });
        });

        // Promise rejection 캐치
        window.addEventListener('unhandledrejection', (event) => {
            this.logError({
                type: 'promise_rejection',
                message: event.reason?.message || 'Unhandled Promise Rejection',
                stack: event.reason?.stack,
                timestamp: new Date().toISOString(),
                url: window.location.href,
                userAgent: navigator.userAgent
            });
        });

        // React Error Boundary에서 사용할 수 있도록 전역에 등록
        window.errorLogger = this;
    }

    /**
     * 오류 로깅
     * @param {Object} errorInfo - 오류 정보
     */
    async logError(errorInfo) {
        if (!this.isEnabled) return;

        const errorData = {
            ...errorInfo,
            sessionId: this.getSessionId(),
            userId: this.getUserId(),
            timestamp: errorInfo.timestamp || new Date().toISOString(),
            level: errorInfo.level || 'error'
        };

        // 콘솔에도 출력 (개발 환경)
        if (process.env.NODE_ENV === 'development') {
            console.error('🚨 Frontend Error:', errorData);
        }

        // 로컬 스토리지에 임시 저장
        this.saveToLocalStorage(errorData);

        // 서버로 전송 (큐에 추가)
        this.errorQueue.push(errorData);
        this.processErrorQueue();
    }

    /**
     * API 오류 로깅
     * @param {Object} error - API 오류 객체
     * @param {string} endpoint - API 엔드포인트
     * @param {Object} requestData - 요청 데이터
     */
    logApiError(error, endpoint, requestData = null) {
        const errorInfo = {
            type: 'api_error',
            message: error.message || 'API Error',
            endpoint: endpoint,
            status: error.response?.status,
            statusText: error.response?.statusText,
            responseData: error.response?.data,
            requestData: requestData,
            stack: error.stack,
            timestamp: new Date().toISOString(),
            url: window.location.href
        };

        this.logError(errorInfo);
    }

    /**
     * 사용자 액션 오류 로깅
     * @param {string} action - 사용자 액션
     * @param {Object} error - 오류 객체
     * @param {Object} context - 추가 컨텍스트
     */
    logUserActionError(action, error, context = {}) {
        const errorInfo = {
            type: 'user_action_error',
            action: action,
            message: error.message || 'User Action Error',
            stack: error.stack,
            context: context,
            timestamp: new Date().toISOString(),
            url: window.location.href
        };

        this.logError(errorInfo);
    }

    /**
     * 성능 이슈 로깅
     * @param {string} operation - 작업명
     * @param {number} duration - 소요 시간 (ms)
     * @param {Object} details - 추가 세부사항
     */
    logPerformanceIssue(operation, duration, details = {}) {
        if (duration > 5000) { // 5초 이상 걸린 작업만 로깅
            const performanceInfo = {
                type: 'performance_issue',
                operation: operation,
                duration: duration,
                details: details,
                timestamp: new Date().toISOString(),
                url: window.location.href,
                level: 'warning'
            };

            this.logError(performanceInfo);
        }
    }

    /**
     * 오류 큐 처리
     */
    async processErrorQueue() {
        if (this.isProcessing || this.errorQueue.length === 0) return;

        this.isProcessing = true;

        while (this.errorQueue.length > 0) {
            const errorData = this.errorQueue.shift();
            
            try {
                await this.sendErrorToServer(errorData);
            } catch (sendError) {
                console.error('Failed to send error to server:', sendError);
                // 실패한 오류는 다시 큐에 추가 (최대 재시도 횟수 확인)
                if (!errorData.retryCount) errorData.retryCount = 0;
                if (errorData.retryCount < this.maxRetries) {
                    errorData.retryCount++;
                    this.errorQueue.push(errorData);
                    await this.delay(this.retryDelay);
                }
            }
        }

        this.isProcessing = false;
    }

    /**
     * 서버로 오류 전송
     * @param {Object} errorData - 오류 데이터
     */
    async sendErrorToServer(errorData) {
        try {
            await api.post('/logs/frontend-error', errorData);
        } catch (error) {
            // 로깅 API가 없는 경우 무시
            if (error.response?.status === 404) {
                console.warn('Error logging endpoint not available');
                return;
            }
            throw error;
        }
    }

    /**
     * 로컬 스토리지에 오류 저장
     * @param {Object} errorData - 오류 데이터
     */
    saveToLocalStorage(errorData) {
        try {
            const errors = JSON.parse(localStorage.getItem('frontend_errors') || '[]');
            errors.push(errorData);
            
            // 최대 100개까지만 저장
            if (errors.length > 100) {
                errors.splice(0, errors.length - 100);
            }
            
            localStorage.setItem('frontend_errors', JSON.stringify(errors));
        } catch (e) {
            console.error('Failed to save error to localStorage:', e);
        }
    }

    /**
     * 로컬 스토리지에서 오류 목록 조회
     * @returns {Array} 오류 목록
     */
    getLocalErrors() {
        try {
            return JSON.parse(localStorage.getItem('frontend_errors') || '[]');
        } catch (e) {
            console.error('Failed to get errors from localStorage:', e);
            return [];
        }
    }

    /**
     * 로컬 스토리지 오류 삭제
     */
    clearLocalErrors() {
        try {
            localStorage.removeItem('frontend_errors');
        } catch (e) {
            console.error('Failed to clear errors from localStorage:', e);
        }
    }

    /**
     * 세션 ID 조회
     * @returns {string} 세션 ID
     */
    getSessionId() {
        let sessionId = sessionStorage.getItem('error_session_id');
        if (!sessionId) {
            sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
            sessionStorage.setItem('error_session_id', sessionId);
        }
        return sessionId;
    }

    /**
     * 사용자 ID 조회
     * @returns {string|null} 사용자 ID
     */
    getUserId() {
        try {
            const userData = JSON.parse(localStorage.getItem('user_data') || '{}');
            return userData.user_id || null;
        } catch (e) {
            return null;
        }
    }

    /**
     * 지연 함수
     * @param {number} ms - 지연 시간 (밀리초)
     */
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 오류 로깅 활성화/비활성화
     * @param {boolean} enabled - 활성화 여부
     */
    setEnabled(enabled) {
        this.isEnabled = enabled;
    }

    /**
     * 수동 오류 보고
     * @param {string} message - 오류 메시지
     * @param {Object} details - 추가 세부사항
     */
    reportError(message, details = {}) {
        this.logError({
            type: 'manual_report',
            message: message,
            details: details,
            timestamp: new Date().toISOString(),
            url: window.location.href,
            level: 'error'
        });
    }

    /**
     * 경고 로깅
     * @param {string} message - 경고 메시지
     * @param {Object} details - 추가 세부사항
     */
    reportWarning(message, details = {}) {
        this.logError({
            type: 'warning',
            message: message,
            details: details,
            timestamp: new Date().toISOString(),
            url: window.location.href,
            level: 'warning'
        });
    }
}

// 싱글톤 인스턴스 생성 및 내보내기
const errorLogger = new ErrorLogger();

export default errorLogger;

// 편의 함수들 내보내기
export const logError = (error, context) => errorLogger.logError({ ...error, context });
export const logApiError = (error, endpoint, requestData) => errorLogger.logApiError(error, endpoint, requestData);
export const logUserActionError = (action, error, context) => errorLogger.logUserActionError(action, error, context);
export const logPerformanceIssue = (operation, duration, details) => errorLogger.logPerformanceIssue(operation, duration, details);
export const reportError = (message, details) => errorLogger.reportError(message, details);
export const reportWarning = (message, details) => errorLogger.reportWarning(message, details);
