<layout name="admin" />

<div class="section">
    <h2>📄 {{ title }}</h2>

    <div class="admin-card">
        <div class="admin-card__header">
            <h3 class="admin-card__title">Log File Browser</h3>
            <div style="display: flex; gap: 10px;">
                <select class="admin-select" id="levelFilter" style="margin-right: 10px;">
                    <option value="">All Levels</option>
                    <option value="DEBUG">Debug</option>
                    <option value="INFO">Info</option>
                    <option value="WARNING">Warning</option>
                    <option value="ERROR">Error</option>
                    <option value="CRITICAL">Critical</option>
                </select>
                <button class="admin-button admin-button--small admin-button--primary" id="refreshBtn">🔄 Refresh</button>
            </div>
        </div>
        <div class="admin-card__content" style="padding: 0;">
            <div class="log-viewer-container">
                <div class="log-sidebar">
                    <h4 style="padding: var(--space-md); margin: 0; border-bottom: 1px solid var(--border);">Available Logs</h4>
                    <ul class="log-list" id="logList">
                        <li class="loading">Loading logs...</li>
                    </ul>
                </div>

                <div class="log-main-content">
                    <div class="log-controls">
                        <input type="text" class="admin-input" id="searchInput" placeholder="Search logs..." style="flex: 1; margin-right: 10px;">
                        <input type="number" class="admin-input" id="limitInput" value="100" min="10" max="1000" placeholder="Limit" style="width: 100px; margin-right: 10px;">
                        <button class="admin-button admin-button--small" id="tailBtn">📡 Tail</button>
                        <button class="admin-button admin-button--small" id="streamBtn">📺 Stream Live</button>
                        <button class="admin-button admin-button--small" id="searchBtn">🔍 Search All</button>
                    </div>

                    <div class="log-content" id="logContent">
                        <div class="empty-state">
                            <h3>Select a log file to view</h3>
                            <p>Choose a log file from the sidebar to start viewing logs</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<style>
.log-viewer-container {
    display: flex;
    height: 70vh;
    border-radius: var(--radius-md);
    overflow: hidden;
}

.log-sidebar {
    width: 300px;
    background: var(--bg-alt);
    border-right: 1px solid var(--border);
    overflow-y: auto;
}

.log-main-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: var(--bg);
}

.log-controls {
    display: flex;
    gap: 10px;
    padding: var(--space-md);
    border-bottom: 1px solid var(--border);
    background: var(--bg-alt);
    align-items: center;
}

.log-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.log-item {
    padding: var(--space-md);
    cursor: pointer;
    border-bottom: 1px solid var(--border);
    transition: all 0.2s ease;
}

.log-item:hover {
    background: var(--hover);
}

.log-item.active {
    background: var(--primary);
    color: white;
}

.log-name {
    font-weight: 600;
    margin-bottom: var(--space-xs);
}

.log-info {
    font-size: 0.85rem;
    color: var(--muted);
}

.log-item.active .log-info {
    color: rgba(255, 255, 255, 0.8);
}

.log-content {
    flex: 1;
    background: var(--gray-900);
    color: var(--gray-100);
    padding: var(--space-md);
    overflow-y: auto;
    font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
    font-size: 0.9rem;
    line-height: 1.4;
}

.log-entry {
    margin-bottom: var(--space-sm);
    padding: var(--space-sm);
    border-radius: var(--radius-sm);
    border-left: 3px solid transparent;
}

.log-entry.level-debug {
    border-left-color: var(--gray-500);
    background: rgba(108, 117, 125, 0.1);
}

.log-entry.level-info {
    border-left-color: var(--info);
    background: rgba(23, 162, 184, 0.1);
}

.log-entry.level-warning {
    border-left-color: var(--warning);
    background: rgba(255, 193, 7, 0.1);
}

.log-entry.level-error {
    border-left-color: var(--error);
    background: rgba(220, 53, 69, 0.1);
}

.log-entry.level-critical {
    border-left-color: #800020;
    background: rgba(128, 0, 32, 0.2);
}

.log-timestamp {
    color: var(--gray-400);
    font-size: 0.85rem;
}

.log-level {
    display: inline-block;
    padding: 0.2rem 0.5rem;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: 600;
    margin: 0 0.5rem;
}

.log-level.debug { background: var(--gray-500); color: white; }
.log-level.info { background: var(--info); color: white; }
.log-level.warning { background: var(--warning); color: var(--gray-900); }
.log-level.error { background: var(--error); color: white; }
.log-level.critical { background: #800020; color: white; }

.log-message {
    margin-top: var(--space-xs);
}

.log-context {
    margin-top: var(--space-xs);
    font-size: 0.8rem;
    color: var(--gray-400);
    font-style: italic;
}

.stream-indicator {
    display: inline-block;
    width: 8px;
    height: 8px;
    background: var(--success);
    border-radius: 50%;
    margin-right: 0.5rem;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0% { opacity: 1; }
    50% { opacity: 0.5; }
    100% { opacity: 1; }
}

.stream-status {
    background: linear-gradient(135deg, var(--gray-800), var(--gray-700));
    border: 1px solid var(--success);
    padding: var(--space-md);
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-md);
    color: var(--success);
}

.empty-state {
    text-align: center;
    padding: 4rem 2rem;
    color: var(--muted);
}

.loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    color: var(--muted);
}

@media (max-width: 768px) {
    .log-viewer-container {
        flex-direction: column;
        height: auto;
    }

    .log-sidebar {
        width: 100%;
        height: auto;
        max-height: 200px;
    }

    .log-controls {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-sm);
    }

    .log-content {
        height: 400px;
    }
}
</style>

<script>
class LogViewer {
    constructor() {
        this.currentLog = null;
        this.refreshInterval = null;
        this.streamEventSource = null;
        this.isStreaming = false;
        this.streamEntries = [];
        this.setupEventListeners();
        this.loadAvailableLogs();
    }

    setupEventListeners() {
        document.getElementById('refreshBtn').addEventListener('click', () => {
            if (this.currentLog) {
                this.loadLogContent(this.currentLog);
            }
        });

        document.getElementById('tailBtn').addEventListener('click', () => {
            if (this.currentLog) {
                this.tailLog(this.currentLog);
            }
        });

        document.getElementById('streamBtn').addEventListener('click', () => {
            if (this.currentLog) {
                this.toggleStream();
            }
        });

        document.getElementById('searchBtn').addEventListener('click', () => {
            this.searchAllLogs();
        });

        document.getElementById('searchInput').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                if (this.currentLog) {
                    this.loadLogContent(this.currentLog);
                }
            }
        });

        document.getElementById('levelFilter').addEventListener('change', () => {
            if (this.currentLog) {
                this.loadLogContent(this.currentLog);
            }
        });
    }

    async loadAvailableLogs() {
        try {
            const response = await fetch('/admin/infrastructure/logs/api/list');
            const data = await response.json();

            if (data.status === 'success') {
                this.renderLogList(data.data.logs);
            }
        } catch (error) {
            console.error('Error loading logs:', error);
            document.getElementById('logList').innerHTML =
                '<li class="log-item">Error loading logs</li>';
        }
    }

    renderLogList(logs) {
        const logList = document.getElementById('logList');
        logList.innerHTML = '';

        Object.values(logs).forEach(log => {
            const li = document.createElement('li');
            li.className = 'log-item';

            // Extract log name - handle both string and object (VO)
            const logName = typeof log.name === 'object' ? log.name.value : log.name;

            li.innerHTML = `
                <div class="log-name">${logName}</div>
                <div class="log-info">
                    ${log.size} • ${log.modified}
                    ${!log.readable ? ' • ⚠️ Not readable' : ''}
                </div>
            `;

            if (log.readable) {
                li.addEventListener('click', () => {
                    this.selectLog(logName, li);
                });
            } else {
                li.style.opacity = '0.5';
                li.style.cursor = 'not-allowed';
            }

            logList.appendChild(li);
        });
    }

    selectLog(logName, element) {
        // Stop any active stream
        if (this.isStreaming) {
            this.stopStream();
        }

        // Update active state
        document.querySelectorAll('.log-item').forEach(item => {
            item.classList.remove('active');
        });
        element.classList.add('active');

        this.currentLog = logName;
        this.loadLogContent(logName);
    }

    async loadLogContent(logName) {
        const logContent = document.getElementById('logContent');
        logContent.innerHTML = '<div class="loading">Loading log content...</div>';

        try {
            const params = new URLSearchParams();

            const level = document.getElementById('levelFilter').value;
            const search = document.getElementById('searchInput').value;
            const limit = document.getElementById('limitInput').value;

            if (level) params.set('level', level);
            if (search) params.set('search', search);
            if (limit) params.set('limit', limit);

            const response = await fetch(`/admin/infrastructure/logs/api/read/${logName}?${params}`);
            const data = await response.json();

            if (data.status === 'success') {
                this.renderLogEntries(data.data.entries);
            } else {
                logContent.innerHTML = `<div class="empty-state">Error: ${data.message}</div>`;
            }
        } catch (error) {
            console.error('Error loading log content:', error);
            logContent.innerHTML = '<div class="empty-state">Error loading log content</div>';
        }
    }

    async tailLog(logName) {
        try {
            const lines = document.getElementById('limitInput').value || 50;
            const response = await fetch(`/admin/infrastructure/logs/api/tail/${logName}?lines=${lines}`);
            const data = await response.json();

            if (data.status === 'success') {
                this.renderLogEntries(data.data.entries);
            }
        } catch (error) {
            console.error('Error tailing log:', error);
        }
    }

    async searchAllLogs() {
        const search = document.getElementById('searchInput').value;
        if (!search) {
            alert('Please enter a search query');
            return;
        }

        const logContent = document.getElementById('logContent');
        logContent.innerHTML = '<div class="loading">Searching all logs...</div>';

        try {
            const params = new URLSearchParams();
            params.set('query', search);

            const level = document.getElementById('levelFilter').value;
            if (level) params.set('level', level);

            const response = await fetch(`/admin/infrastructure/logs/api/search?${params}`);
            const data = await response.json();

            if (data.status === 'success') {
                this.renderSearchResults(data.data);
            }
        } catch (error) {
            console.error('Error searching logs:', error);
            logContent.innerHTML = '<div class="empty-state">Error searching logs</div>';
        }
    }

    toggleStream() {
        if (this.isStreaming) {
            this.stopStream();
        } else {
            this.startStream();
        }
    }

    startStream() {
        if (!this.currentLog || this.isStreaming) return;

        const streamBtn = document.getElementById('streamBtn');
        streamBtn.textContent = '⏹️ Stop Stream';
        streamBtn.classList.add('admin-button--primary');

        this.isStreaming = true;
        this.streamEntries = [];

        const logContent = document.getElementById('logContent');
        logContent.innerHTML = `
            <div class="stream-status">
                <span class="stream-indicator"></span><strong>Live Streaming:</strong> ${this.currentLog}
                <span style="float: right;" id="streamStats">0 entries</span>
            </div>
            <div id="streamContent"></div>
        `;

        const params = new URLSearchParams();
        const level = document.getElementById('levelFilter').value;
        const search = document.getElementById('searchInput').value;
        const batchSize = 10;

        if (level) params.set('level', level);
        if (search) params.set('search', search);
        params.set('batch_size', batchSize);

        const url = `/admin/infrastructure/logs/api/stream/${this.currentLog}?${params}`;
        this.streamEventSource = new EventSource(url);

        this.streamEventSource.addEventListener('log_batch', (event) => {
            try {
                const data = JSON.parse(event.data);
                if (data.status === 'success') {
                    this.handleStreamBatch(data);
                }
            } catch (error) {
                console.error('Error parsing stream data:', error);
            }
        });

        this.streamEventSource.addEventListener('stream_complete', (event) => {
            console.log('Stream completed');
            this.updateStreamStatus('Stream completed');
        });

        this.streamEventSource.addEventListener('error', (event) => {
            console.error('Stream error:', event);
            this.stopStream();
            this.updateStreamStatus('Stream error occurred');
        });

        this.streamEventSource.onerror = (error) => {
            console.error('EventSource error:', error);
            this.stopStream();
        };
    }

    stopStream() {
        if (!this.isStreaming) return;

        const streamBtn = document.getElementById('streamBtn');
        streamBtn.textContent = '📺 Stream Live';
        streamBtn.classList.remove('admin-button--primary');

        this.isStreaming = false;

        if (this.streamEventSource) {
            this.streamEventSource.close();
            this.streamEventSource = null;
        }

        this.updateStreamStatus('Stream stopped');
    }

    handleStreamBatch(data) {
        const streamContent = document.getElementById('streamContent');
        const streamStats = document.getElementById('streamStats');

        // Füge neue Einträge hinzu
        data.batch.forEach(entry => {
            this.streamEntries.push(entry);
        });

        // Update Statistics
        if (streamStats) {
            streamStats.textContent = `${this.streamEntries.length} entries (Batch ${data.batch_number})`;
        }

        // Render neue Einträge
        const newEntriesHtml = data.batch.map(entry => {
            const levelClass = `level-${entry.level.toLowerCase()}`;
            return `
                <div class="log-entry ${levelClass}">
                    <div>
                        <span class="log-timestamp">${entry.timestamp}</span>
                        <span class="log-level ${entry.level.toLowerCase()}">${entry.level}</span>
                    </div>
                    <div class="log-message">${this.escapeHtml(entry.message)}</div>
                    ${entry.context ? `<div class="log-context">${this.escapeHtml(entry.context)}</div>` : ''}
                </div>
            `;
        }).join('');

        if (streamContent) {
            streamContent.innerHTML += newEntriesHtml;

            // Auto-scroll to bottom
            const logContent = document.getElementById('logContent');
            logContent.scrollTop = logContent.scrollHeight;
        }

        // Begrenze die Anzahl der angezeigten Einträge (Performance)
        if (this.streamEntries.length > 500) {
            this.streamEntries = this.streamEntries.slice(-400); // Keep last 400
            this.reRenderStreamEntries();
        }
    }

    reRenderStreamEntries() {
        const streamContent = document.getElementById('streamContent');
        if (streamContent) {
            streamContent.innerHTML = this.streamEntries.map(entry => {
                const levelClass = `level-${entry.level.toLowerCase()}`;
                return `
                    <div class="log-entry ${levelClass}">
                        <div>
                            <span class="log-timestamp">${entry.timestamp}</span>
                            <span class="log-level ${entry.level.toLowerCase()}">${entry.level}</span>
                        </div>
                        <div class="log-message">${this.escapeHtml(entry.message)}</div>
                        ${entry.context ? `<div class="log-context">${this.escapeHtml(entry.context)}</div>` : ''}
                    </div>
                `;
            }).join('');
        }
    }

    updateStreamStatus(message) {
        const streamStats = document.getElementById('streamStats');
        if (streamStats) {
            streamStats.textContent = message;
        }
    }

    renderLogEntries(entries) {
        const logContent = document.getElementById('logContent');

        if (entries.length === 0) {
            logContent.innerHTML = '<div class="empty-state">No log entries found</div>';
            return;
        }

        logContent.innerHTML = entries.map(entry => {
            const levelClass = `level-${entry.level.toLowerCase()}`;
            return `
                <div class="log-entry ${levelClass}">
                    <div>
                        <span class="log-timestamp">${entry.timestamp}</span>
                        <span class="log-level ${entry.level.toLowerCase()}">${entry.level}</span>
                    </div>
                    <div class="log-message">${this.escapeHtml(entry.message)}</div>
                    ${entry.context ? `<div class="log-context">${this.escapeHtml(entry.context)}</div>` : ''}
                </div>
            `;
        }).join('');

        // Scroll to bottom
        logContent.scrollTop = logContent.scrollHeight;
    }

    renderSearchResults(searchData) {
        const logContent = document.getElementById('logContent');

        if (searchData.total_matches === 0) {
            logContent.innerHTML = '<div class="empty-state">No matches found</div>';
            return;
        }

        let html = `
            <div style="padding: var(--space-md); background: var(--gray-800); border-radius: var(--radius-sm); margin-bottom: var(--space-md);">
                <strong>Search Results:</strong> ${searchData.total_matches} matches for "${searchData.query}"
            </div>
        `;

        Object.entries(searchData.results).forEach(([logName, logData]) => {
            if (logData.entries) {
                html += `
                    <div style="padding: var(--space-sm); background: var(--gray-700); margin-bottom: var(--space-md); border-radius: var(--radius-sm);">
                        <strong>${logName}</strong> (${logData.total_entries} matches)
                    </div>
                `;

                logData.entries.forEach(entry => {
                    const levelClass = `level-${entry.level.toLowerCase()}`;
                    html += `
                        <div class="log-entry ${levelClass}">
                            <div>
                                <span class="log-timestamp">${entry.timestamp}</span>
                                <span class="log-level ${entry.level.toLowerCase()}">${entry.level}</span>
                            </div>
                            <div class="log-message">${this.escapeHtml(entry.message)}</div>
                            ${entry.context ? `<div class="log-context">${this.escapeHtml(entry.context)}</div>` : ''}
                        </div>
                    `;
                });
            }
        });

        logContent.innerHTML = html;
    }

    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
}

// Initialize log viewer when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    new LogViewer();
});
</script>