// ==UserScript==
// @name         Ultra Advanced AI API Detector for Hugging Face Space o1mini
// @namespace    http://tampermonkey.net/
// @version      1.4
// @description  Hugging Face Space o1mini에서 AI API 요청을 탐지하고 UI 패널에 표시합니다.
// @author       Your Name
// @match        https://huggingface.co/spaces/yuntian-deng/o1mini*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function() {
    'use strict';

    /************** 설정 및 초기화 **************/
    const CONFIG = {
        LOG_STORAGE_KEY: 'ultra-advanced-ai-api-logs',
        MAX_LOGS: 2000,
        API_PATTERNS: [/\/api\//i, /\/ai\//i, /\/o1mini\//i], // 정규 표현식을 사용한 패턴
        THEME: 'dark', // 'dark' 또는 'light'
        NOTIFICATION: true // 알림 기능 활성화 여부
    };

    let logDataStorage = [];
    let isDarkTheme = CONFIG.THEME === 'dark';

    /************** UI 패널 생성 및 스타일링 **************/

    function createUIPanel() {
        // 호스트 컨테이너 (Shadow DOM을 위한)
        const panelHost = document.createElement('div');
        panelHost.id = 'ultra-advanced-ai-api-panel-host';
        panelHost.style.position = 'fixed';
        panelHost.style.top = '10px';
        panelHost.style.right = '10px';
        panelHost.style.width = '700px';
        panelHost.style.height = '800px';
        panelHost.style.zIndex = '10000';
        panelHost.style.transform = 'translateX(100%)'; // 숨김 상태
        panelHost.style.transition = 'transform 0.3s ease-in-out';
        document.body.appendChild(panelHost);

        // Shadow Root 생성
        const shadow = panelHost.attachShadow({ mode: 'open' });

        // 패널 생성
        const panel = document.createElement('div');
        panel.style.backgroundColor = isDarkTheme ? '#1E1E1E' : '#FFFFFF';
        panel.style.color = isDarkTheme ? '#FFFFFF' : '#000000';
        panel.style.fontFamily = 'Arial, sans-serif';
        panel.style.fontSize = '14px';
        panel.style.borderRadius = '10px';
        panel.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.5)';
        panel.style.width = '100%';
        panel.style.height = '100%';
        panel.style.display = 'flex';
        panel.style.flexDirection = 'column';
        panel.style.overflow = 'hidden';
        shadow.appendChild(panel);

        // 헤더
        const header = document.createElement('div');
        header.style.backgroundColor = isDarkTheme ? '#333' : '#f0f0f0';
        header.style.padding = '12px';
        header.style.display = 'flex';
        header.style.justifyContent = 'space-between';
        header.style.alignItems = 'center';
        header.style.cursor = 'pointer';
        header.style.borderBottom = isDarkTheme ? '1px solid #555' : '1px solid #ccc';

        const title = document.createElement('span');
        title.textContent = '🔍 AI API 요청 로그';
        title.style.fontWeight = 'bold';
        title.style.fontSize = '16px';
        header.appendChild(title);

        const toggleButton = document.createElement('button');
        toggleButton.textContent = '◀';
        toggleButton.style.background = 'none';
        toggleButton.style.border = 'none';
        toggleButton.style.color = isDarkTheme ? '#FFF' : '#000';
        toggleButton.style.fontSize = '18px';
        toggleButton.style.cursor = 'pointer';
        header.appendChild(toggleButton);

        panel.appendChild(header);

        // 필터 섹션
        const filterSection = document.createElement('div');
        filterSection.style.padding = '10px';
        filterSection.style.backgroundColor = isDarkTheme ? '#2a2a2a' : '#e0e0e0';
        filterSection.style.borderBottom = isDarkTheme ? '1px solid #555' : '1px solid #ccc';
        filterSection.style.display = 'flex';
        filterSection.style.flexWrap = 'wrap';
        filterSection.style.alignItems = 'center';

        // 메소드 필터
        const methodFilterLabel = document.createElement('label');
        methodFilterLabel.textContent = 'Method: ';
        methodFilterLabel.style.marginRight = '5px';
        filterSection.appendChild(methodFilterLabel);

        const methodFilter = document.createElement('select');
        methodFilter.id = 'method-filter';
        methodFilter.style.marginRight = '10px';
        methodFilter.style.padding = '4px';
        methodFilter.innerHTML = `
            <option value="ALL">ALL</option>
            <option value="GET">GET</option>
            <option value="POST">POST</option>
            <option value="PUT">PUT</option>
            <option value="DELETE">DELETE</option>
            <option value="PATCH">PATCH</option>
            <option value="WEBSOCKET">WEBSOCKET</option>
            <option value="SSE">SSE</option>
            <option value="BEACON">BEACON</option>
        `;
        filterSection.appendChild(methodFilter);

        // URL 필터
        const urlFilterLabel = document.createElement('label');
        urlFilterLabel.textContent = 'URL 포함: ';
        urlFilterLabel.style.marginRight = '5px';
        filterSection.appendChild(urlFilterLabel);

        const urlFilter = document.createElement('input');
        urlFilter.id = 'url-filter';
        urlFilter.type = 'text';
        urlFilter.placeholder = '예: /api/ 또는 /ai/';
        urlFilter.style.padding = '4px';
        urlFilter.style.width = '150px';
        urlFilter.style.marginRight = '10px';
        filterSection.appendChild(urlFilter);

        // 필터 적용 버튼
        const applyFilterButton = document.createElement('button');
        applyFilterButton.textContent = '필터 적용';
        applyFilterButton.style.padding = '4px 8px';
        applyFilterButton.style.cursor = 'pointer';
        filterSection.appendChild(applyFilterButton);

        // 테마 전환 버튼
        const themeToggleButton = document.createElement('button');
        themeToggleButton.textContent = isDarkTheme ? '🌞 라이트 모드' : '🌙 다크 모드';
        themeToggleButton.style.padding = '4px 8px';
        themeToggleButton.style.cursor = 'pointer';
        filterSection.appendChild(themeToggleButton);

        panel.appendChild(filterSection);

        // 로그 컨테이너
        const logContainer = document.createElement('div');
        logContainer.className = 'log-container';
        logContainer.style.flex = '1';
        logContainer.style.padding = '10px';
        logContainer.style.overflowY = 'auto';
        logContainer.style.backgroundColor = isDarkTheme ? '#1e1e1e' : '#ffffff';
        panel.appendChild(logContainer);

        // 로그 관리 섹션
        const logManagementSection = document.createElement('div');
        logManagementSection.className = 'log-management';
        logManagementSection.style.padding = '10px';
        logManagementSection.style.backgroundColor = isDarkTheme ? '#2a2a2a' : '#e0e0e0';
        logManagementSection.style.borderTop = isDarkTheme ? '1px solid #555' : '1px solid #ccc';
        logManagementSection.style.display = 'flex';
        logManagementSection.style.justifyContent = 'space-between';
        logManagementSection.style.alignItems = 'center';

        // 로그 내보내기 버튼
        const exportLogsButton = document.createElement('button');
        exportLogsButton.textContent = '📤 로그 내보내기';
        exportLogsButton.style.padding = '6px 12px';
        exportLogsButton.style.cursor = 'pointer';
        logManagementSection.appendChild(exportLogsButton);

        // 로그 삭제 버튼
        const clearLogsButton = document.createElement('button');
        clearLogsButton.textContent = '🗑️ 로그 삭제';
        clearLogsButton.style.padding = '6px 12px';
        clearLogsButton.style.cursor = 'pointer';
        logManagementSection.appendChild(clearLogsButton);

        panel.appendChild(logManagementSection);

        // 이벤트 리스너 설정

        // 헤더 클릭 시 패널 열기/닫기
        header.addEventListener('click', () => {
            if (panelHost.style.transform === 'translateX(100%)') {
                panelHost.style.transform = 'translateX(0)';
                toggleButton.textContent = '▶';
            } else {
                panelHost.style.transform = 'translateX(100%)';
                toggleButton.textContent = '◀';
            }
        });

        // 필터 적용 버튼
        applyFilterButton.addEventListener('click', () => {
            applyFilters();
        });

        // 테마 전환 버튼
        themeToggleButton.addEventListener('click', () => {
            toggleTheme();
        });

        // 로그 내보내기 버튼
        exportLogsButton.addEventListener('click', () => {
            exportLogs();
        });

        // 로그 삭제 버튼
        clearLogsButton.addEventListener('click', () => {
            clearLogs();
        });

        // 디버깅 로그
        console.log('Tampermonkey script loaded successfully.');
    }

    /************** 필터링 기능 **************/

    const filterState = {
        method: 'ALL',
        urlIncludes: ''
    };

    function shouldDisplayLog(log) {
        const { method, urlIncludes } = filterState;

        // 메소드 필터링
        if (method !== 'ALL' && log.method.toUpperCase() !== method) {
            return false;
        }

        // URL 포함 필터링
        if (urlIncludes && !log.url.includes(urlIncludes)) {
            return false;
        }

        return true;
    }

    function applyFilters() {
        const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
        if (!panelHost.shadowRoot) return;

        const methodSelect = panelHost.shadowRoot.getElementById('method-filter');
        const urlInput = panelHost.shadowRoot.getElementById('url-filter');

        filterState.method = methodSelect.value;
        filterState.urlIncludes = urlInput.value.trim();

        console.log('Applying filters:', filterState);

        // 현재 로그를 모두 숨기고 필터에 맞는 로그만 표시
        const logEntries = panelHost.shadowRoot.querySelectorAll('.log-entry');
        logEntries.forEach(entry => {
            const method = entry.querySelector('.log-method').textContent.replace('Method: ', '');
            const url = entry.querySelector('.log-url').textContent.replace('URL: ', '');

            const logData = {
                method: method,
                url: url
            };

            if (shouldDisplayLog(logData)) {
                entry.style.display = 'block';
            } else {
                entry.style.display = 'none';
            }
        });
    }

    /************** 테마 전환 기능 **************/

    function toggleTheme() {
        const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
        if (!panelHost.shadowRoot) return;

        const shadow = panelHost.shadowRoot;
        const panel = shadow.querySelector('.panel');
        const header = shadow.querySelector('.header');
        const filterSection = shadow.querySelector('.filter-section');
        const logContainer = shadow.querySelector('.log-container');
        const logManagementSection = shadow.querySelector('.log-management');
        const themeToggleButton = shadow.querySelector('.filter-section button:nth-child(6)');

        isDarkTheme = !isDarkTheme;

        // 패널 배경 및 텍스트 색상 변경
        panel.style.backgroundColor = isDarkTheme ? '#1E1E1E' : '#FFFFFF';
        panel.style.color = isDarkTheme ? '#FFFFFF' : '#000000';

        // 헤더 스타일 변경
        header.style.backgroundColor = isDarkTheme ? '#333' : '#f0f0f0';
        header.style.borderBottom = isDarkTheme ? '1px solid #555' : '1px solid #ccc';
        header.style.color = isDarkTheme ? '#FFFFFF' : '#000000';

        // 필터 섹션 스타일 변경
        filterSection.style.backgroundColor = isDarkTheme ? '#2a2a2a' : '#e0e0e0';
        filterSection.style.borderBottom = isDarkTheme ? '1px solid #555' : '1px solid #ccc';

        // 로그 컨테이너 배경색 변경
        logContainer.style.backgroundColor = isDarkTheme ? '#1e1e1e' : '#ffffff';

        // 로그 관리 섹션 스타일 변경
        logManagementSection.style.backgroundColor = isDarkTheme ? '#2a2a2a' : '#e0e0e0';
        logManagementSection.style.borderTop = isDarkTheme ? '1px solid #555' : '1px solid #ccc';

        // 테마 전환 버튼 텍스트 변경
        themeToggleButton.textContent = isDarkTheme ? '🌞 라이트 모드' : '🌙 다크 모드';

        // 로그 엔트리 스타일 변경
        const logEntries = shadow.querySelectorAll('.log-entry');
        logEntries.forEach(entry => {
            entry.style.borderBottom = isDarkTheme ? '1px solid #555' : '1px solid #ccc';
            entry.querySelector('.log-url').style.color = isDarkTheme ? '#1E90FF' : '#007BFF';
            entry.querySelector('.log-method').style.color = isDarkTheme ? '#FFD700' : '#FFA500';
            entry.querySelector('.log-status').style.color = isDarkTheme ? '#ADFF2F' : '#32CD32';
            entry.querySelector('.log-duration').style.color = isDarkTheme ? '#FF69B4' : '#FF4500';
            entry.querySelector('.log-type').style.color = isDarkTheme ? '#87CEFA' : '#4682B4';
            entry.querySelector('.log-timestamp').style.color = isDarkTheme ? '#FFA07A' : '#8B0000';
            entry.querySelector('.log-response').style.color = isDarkTheme ? '#87CEFA' : '#000000';
        });
    }

    /************** 로그 내보내기 기능 **************/

    function exportLogs() {
        const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
        const logs = JSON.parse(localStorage.getItem(CONFIG.LOG_STORAGE_KEY)) || [];
        if (logs.length === 0) {
            alert('내보낼 로그가 없습니다.');
            return;
        }

        const blob = new Blob([JSON.stringify(logs, null, 2)], { type: 'application/json' });
        const url = URL.createObjectURL(blob);

        const a = document.createElement('a');
        a.href = url;
        a.download = 'ultra_advanced_ai_api_logs.json';
        a.click();

        URL.revokeObjectURL(url);
    }

    /************** 로그 삭제 기능 **************/

    function clearLogs() {
        if (!confirm('모든 로그를 삭제하시겠습니까?')) return;

        localStorage.removeItem(CONFIG.LOG_STORAGE_KEY);
        logDataStorage = [];
        const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
        if (!panelHost.shadowRoot) return;
        const logContainer = panelHost.shadowRoot.querySelector('.log-container');
        if (logContainer) {
            logContainer.innerHTML = '';
        }
    }

    /************** 로깅 저장 및 불러오기 **************/

    function loadStoredLogs() {
        const storedLogs = localStorage.getItem(CONFIG.LOG_STORAGE_KEY);
        if (storedLogs) {
            try {
                logDataStorage = JSON.parse(storedLogs);
                logDataStorage.forEach(log => {
                    if (shouldDisplayLog(log)) {
                        displayLogEntry(log);
                    }
                });
            } catch (e) {
                console.error('로그 불러오기 실패:', e);
            }
        }
    }

    function saveLog(log) {
        logDataStorage.unshift(log); // 최신 로그가 앞에 오게 추가
        // 최대 로그 수 제한
        if (logDataStorage.length > CONFIG.MAX_LOGS) {
            logDataStorage.pop();
        }
        localStorage.setItem(CONFIG.LOG_STORAGE_KEY, JSON.stringify(logDataStorage));
    }

    /************** 로그 디스플레이 기능 **************/

    function displayLogEntry(logData) {
        const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
        if (!panelHost.shadowRoot) return;

        const logContainer = panelHost.shadowRoot.querySelector('.log-container');
        if (!logContainer) return;

        const entry = document.createElement('div');
        entry.className = 'log-entry';
        entry.style.borderBottom = isDarkTheme ? '1px solid #555' : '1px solid #ccc';
        entry.style.padding = '8px 0';

        const url = document.createElement('div');
        url.className = 'log-url';
        url.textContent = `URL: ${logData.url}`;
        url.style.color = isDarkTheme ? '#1E90FF' : '#007BFF';
        url.style.wordBreak = 'break-all';
        url.style.fontWeight = 'bold';

        const method = document.createElement('div');
        method.className = 'log-method';
        method.textContent = `Method: ${logData.method}`;
        method.style.color = isDarkTheme ? '#FFD700' : '#FFA500';

        const status = document.createElement('div');
        status.className = 'log-status';
        status.textContent = `Status: ${logData.status}`;
        status.style.color = isDarkTheme ? '#ADFF2F' : '#32CD32';

        const duration = document.createElement('div');
        duration.className = 'log-duration';
        duration.textContent = `Duration: ${logData.duration}`;
        duration.style.color = isDarkTheme ? '#FF69B4' : '#FF4500';

        const type = document.createElement('div');
        type.className = 'log-type';
        type.textContent = `Type: ${logData.type}`;
        type.style.color = isDarkTheme ? '#87CEFA' : '#4682B4';

        const timestamp = document.createElement('div');
        timestamp.className = 'log-timestamp';
        timestamp.textContent = `Time: ${logData.timestamp}`;
        timestamp.style.color = isDarkTheme ? '#FFA07A' : '#8B0000';

        const response = document.createElement('div');
        response.className = 'log-response';
        response.textContent = `Response: ${logData.response}`;
        response.style.color = isDarkTheme ? '#87CEFA' : '#000000';
        response.style.fontSize = '12px';
        response.style.marginTop = '4px';
        response.style.wordBreak = 'break-all';

        entry.appendChild(url);
        entry.appendChild(method);
        entry.appendChild(status);
        entry.appendChild(duration);
        entry.appendChild(type);
        entry.appendChild(timestamp);
        entry.appendChild(response);

        // 상단에 추가
        logContainer.prepend(entry);
    }

    /************** 알림 기능 **************/

    function showNotification(logData) {
        if (!("Notification" in window)) {
            console.log("이 브라우저는 알림을 지원하지 않습니다.");
            return;
        }

        if (Notification.permission === "granted") {
            notify(logData);
        } else if (Notification.permission !== "denied") {
            Notification.requestPermission().then(permission => {
                if (permission === "granted") {
                    notify(logData);
                }
            });
        }

        function notify(log) {
            const notification = new Notification("새 AI API 요청 감지됨", {
                body: `URL: ${log.url}\nMethod: ${log.method}\nStatus: ${log.status}`,
                icon: "https://huggingface.co/favicon.ico" // Hugging Face 아이콘 사용
            });

            notification.onclick = () => {
                window.focus();
                const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
                if (panelHost) {
                    panelHost.style.transform = 'translateX(0)';
                }
            };
        }
    }

    /************** API 요청 모니터링 **************/

    /**
     * XMLHttpRequest, Fetch, WebSocket, Server-Sent Events (SSE), Beacon API를 오버라이드하여 API 요청 탐지
     */

    // XMLHttpRequest 오버라이드
    (function() {
        const originalXHROpen = XMLHttpRequest.prototype.open;
        const originalXHRSend = XMLHttpRequest.prototype.send;

        XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
            this._url = url; // URL 저장
            this._method = method.toUpperCase(); // 메소드 저장
            return originalXHROpen.apply(this, arguments);
        };

        XMLHttpRequest.prototype.send = function(body) {
            const startTime = Date.now();

            this.addEventListener('readystatechange', function() {
                if (this.readyState === 4) { // 요청 완료
                    if (isMatchingURL(this._url)) {
                        const duration = Date.now() - startTime;
                        let responseText = this.responseText;
                        try {
                            responseText = JSON.stringify(JSON.parse(responseText), null, 2);
                        } catch (e) {
                            // JSON 파싱 실패 시 원본 텍스트 유지
                        }
                        const logEntry = {
                            method: this._method,
                            url: this._url,
                            status: this.status,
                            response: responseText,
                            duration: `${duration}ms`,
                            type: 'XHR',
                            timestamp: new Date().toISOString()
                        };
                        handleNewLog(logEntry);
                    }
                }
            }, false);
            return originalXHRSend.apply(this, arguments);
        };
    })();

    // Fetch 오버라이드
    (function() {
        const originalFetch = window.fetch;
        window.fetch = function(input, init = {}) {
            const method = (init.method || 'GET').toUpperCase();
            const url = (typeof input === 'string' || input instanceof URL) ? input.toString() : input.url;

            const startTime = Date.now();

            return originalFetch.apply(this, arguments).then(response => {
                if (isMatchingURL(url)) {
                    const duration = Date.now() - startTime;
                    return response.clone().text().then(text => {
                        let responseText = text;
                        try {
                            responseText = JSON.stringify(JSON.parse(text), null, 2);
                        } catch (e) {
                            // JSON 파싱 실패 시 원본 텍스트 유지
                        }
                        const logEntry = {
                            method: method,
                            url: url,
                            status: response.status,
                            response: responseText,
                            duration: `${duration}ms`,
                            type: 'Fetch',
                            timestamp: new Date().toISOString()
                        };
                        handleNewLog(logEntry);
                    }).catch(() => {
                        const logEntry = {
                            method: method,
                            url: url,
                            status: response.status,
                            response: 'Unable to parse response',
                            duration: `${duration}ms`,
                            type: 'Fetch',
                            timestamp: new Date().toISOString()
                        };
                        handleNewLog(logEntry);
                    });
                }
                return response;
            });
        };
    })();

    // WebSocket 탐지
    (function() {
        const originalWebSocket = window.WebSocket;
        window.WebSocket = function(url, protocols) {
            const ws = new originalWebSocket(url, protocols);

            ws.addEventListener('message', function(event) {
                if (isMatchingURL(url)) {
                    let message = event.data;
                    try {
                        message = JSON.stringify(JSON.parse(message), null, 2);
                    } catch (e) {
                        // JSON 파싱 실패 시 원본 텍스트 유지
                    }
                    const logEntry = {
                        method: 'WEBSOCKET',
                        url: url,
                        status: 'N/A',
                        response: message,
                        duration: 'N/A',
                        type: 'WebSocket Message',
                        timestamp: new Date().toISOString()
                    };
                    handleNewLog(logEntry);
                }
            });

            ws.addEventListener('open', function() {
                if (isMatchingURL(url)) {
                    const logEntry = {
                        method: 'WEBSOCKET',
                        url: url,
                        status: 'OPEN',
                        response: 'WebSocket connection opened',
                        duration: 'N/A',
                        type: 'WebSocket Open',
                        timestamp: new Date().toISOString()
                    };
                    handleNewLog(logEntry);
                }
            });

            ws.addEventListener('close', function() {
                if (isMatchingURL(url)) {
                    const logEntry = {
                        method: 'WEBSOCKET',
                        url: url,
                        status: 'CLOSED',
                        response: 'WebSocket connection closed',
                        duration: 'N/A',
                        type: 'WebSocket Close',
                        timestamp: new Date().toISOString()
                    };
                    handleNewLog(logEntry);
                }
            });

            ws.addEventListener('error', function() {
                if (isMatchingURL(url)) {
                    const logEntry = {
                        method: 'WEBSOCKET',
                        url: url,
                        status: 'ERROR',
                        response: 'WebSocket error occurred',
                        duration: 'N/A',
                        type: 'WebSocket Error',
                        timestamp: new Date().toISOString()
                    };
                    handleNewLog(logEntry);
                }
            });

            return ws;
        };
    })();

    // Server-Sent Events (SSE) 탐지
    (function() {
        const originalEventSource = window.EventSource;
        window.EventSource = function(url, eventSourceInitDict) {
            const es = new originalEventSource(url, eventSourceInitDict);

            es.addEventListener('message', function(event) {
                if (isMatchingURL(url)) {
                    let message = event.data;
                    try {
                        message = JSON.stringify(JSON.parse(message), null, 2);
                    } catch (e) {
                        // JSON 파싱 실패 시 원본 텍스트 유지
                    }
                    const logEntry = {
                        method: 'SSE',
                        url: url,
                        status: 'N/A',
                        response: message,
                        duration: 'N/A',
                        type: 'SSE Message',
                        timestamp: new Date().toISOString()
                    };
                    handleNewLog(logEntry);
                }
            });

            es.addEventListener('open', function() {
                if (isMatchingURL(url)) {
                    const logEntry = {
                        method: 'SSE',
                        url: url,
                        status: 'OPEN',
                        response: 'SSE connection opened',
                        duration: 'N/A',
                        type: 'SSE Open',
                        timestamp: new Date().toISOString()
                    };
                    handleNewLog(logEntry);
                }
            });

            es.addEventListener('error', function() {
                if (isMatchingURL(url)) {
                    const logEntry = {
                        method: 'SSE',
                        url: url,
                        status: 'ERROR',
                        response: 'SSE error occurred',
                        duration: 'N/A',
                        type: 'SSE Error',
                        timestamp: new Date().toISOString()
                    };
                    handleNewLog(logEntry);
                }
            });

            return es;
        };
    })();

    // Beacon API 탐지
    (function() {
        const originalBeacon = navigator.sendBeacon;
        navigator.sendBeacon = function(url, data) {
            if (isMatchingURL(url)) {
                const logEntry = {
                    method: 'BEACON',
                    url: url,
                    status: 'DISPATCHED',
                    response: data ? data.toString() : 'No Data',
                    duration: 'N/A',
                    type: 'Beacon',
                    timestamp: new Date().toISOString()
                };
                handleNewLog(logEntry);
            }
            return originalBeacon.apply(this, arguments);
        };
    })();

    /************** URL 매칭 함수 **************/

    function isMatchingURL(url) {
        return CONFIG.API_PATTERNS.some(pattern => pattern.test(url));
    }

    /************** 로깅 처리 **************/

    function handleNewLog(logData) {
        saveLog(logData);
        if (shouldDisplayLog(logData)) {
            displayLogEntry(logData);
            // 알림 기능 추가
            if (CONFIG.NOTIFICATION) {
                showNotification(logData);
            }
        }
    }

    /************** 알림 기능 **************/

    function showNotification(logData) {
        if (!("Notification" in window)) {
            console.log("이 브라우저는 알림을 지원하지 않습니다.");
            return;
        }

        if (Notification.permission === "granted") {
            notify(logData);
        } else if (Notification.permission !== "denied") {
            Notification.requestPermission().then(permission => {
                if (permission === "granted") {
                    notify(logData);
                }
            });
        }

        function notify(log) {
            const notification = new Notification("새 AI API 요청 감지됨", {
                body: `URL: ${log.url}\nMethod: ${log.method}\nStatus: ${log.status}`,
                icon: "https://huggingface.co/favicon.ico" // Hugging Face 아이콘 사용
            });

            notification.onclick = () => {
                window.focus();
                const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
                if (panelHost) {
                    panelHost.style.transform = 'translateX(0)';
                }
            };
        }
    }

    /************** 로그 저장 및 불러오기 **************/

    function loadStoredLogs() {
        const storedLogs = localStorage.getItem(CONFIG.LOG_STORAGE_KEY);
        if (storedLogs) {
            try {
                logDataStorage = JSON.parse(storedLogs);
                logDataStorage.forEach(log => {
                    if (shouldDisplayLog(log)) {
                        displayLogEntry(log);
                    }
                });
            } catch (e) {
                console.error('로그 불러오기 실패:', e);
            }
        }
    }

    function saveLog(log) {
        logDataStorage.unshift(log); // 최신 로그가 앞에 오게 추가
        // 최대 로그 수 제한
        if (logDataStorage.length > CONFIG.MAX_LOGS) {
            logDataStorage.pop();
        }
        localStorage.setItem(CONFIG.LOG_STORAGE_KEY, JSON.stringify(logDataStorage));
    }

    /************** 로그 디스플레이 기능 **************/

    function displayLogEntry(logData) {
        const panelHost = document.getElementById('ultra-advanced-ai-api-panel-host');
        if (!panelHost.shadowRoot) return;

        const logContainer = panelHost.shadowRoot.querySelector('.log-container');
        if (!logContainer) return;

        const entry = document.createElement('div');
        entry.className = 'log-entry';

        const url = document.createElement('div');
        url.className = 'log-url';
        url.textContent = `URL: ${logData.url}`;
        url.style.color = isDarkTheme ? '#1E90FF' : '#007BFF';
        url.style.wordBreak = 'break-all';
        url.style.fontWeight = 'bold';

        const method = document.createElement('div');
        method.className = 'log-method';
        method.textContent = `Method: ${logData.method}`;
        method.style.color = isDarkTheme ? '#FFD700' : '#FFA500';

        const status = document.createElement('div');
        status.className = 'log-status';
        status.textContent = `Status: ${logData.status}`;
        status.style.color = isDarkTheme ? '#ADFF2F' : '#32CD32';

        const duration = document.createElement('div');
        duration.className = 'log-duration';
        duration.textContent = `Duration: ${logData.duration}`;
        duration.style.color = isDarkTheme ? '#FF69B4' : '#FF4500';

        const type = document.createElement('div');
        type.className = 'log-type';
        type.textContent = `Type: ${logData.type}`;
        type.style.color = isDarkTheme ? '#87CEFA' : '#4682B4';

        const timestamp = document.createElement('div');
        timestamp.className = 'log-timestamp';
        timestamp.textContent = `Time: ${logData.timestamp}`;
        timestamp.style.color = isDarkTheme ? '#FFA07A' : '#8B0000';

        const response = document.createElement('div');
        response.className = 'log-response';
        response.textContent = `Response: ${logData.response}`;
        response.style.color = isDarkTheme ? '#87CEFA' : '#000000';
        response.style.fontSize = '12px';
        response.style.marginTop = '4px';
        response.style.wordBreak = 'break-all';

        entry.appendChild(url);
        entry.appendChild(method);
        entry.appendChild(status);
        entry.appendChild(duration);
        entry.appendChild(type);
        entry.appendChild(timestamp);
        entry.appendChild(response);

        // 상단에 추가
        logContainer.prepend(entry);
    }

})();