<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FastAPI Monitor Dashboard</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/htmx.org@1.9.6"></script>
    <script src="https://unpkg.com/alpinejs@3.13.1/dist/cdn.min.js" defer></script>
    <script>
        tailwind.config = {
            darkMode: 'class',
            theme: {
                extend: {
                    colors: {
                        primary: {
                            50: '#eff6ff',
                            100: '#dbeafe', 
                            500: '#3b82f6',
                            600: '#2563eb',
                            700: '#1d4ed8'
                        }
                    }
                }
            }
        }
    </script>
</head>
<body x-data="dashboardApp()" 
      class="bg-gray-50 dark:bg-gray-900 transition-colors duration-200">
    
    <div class="max-w-7xl mx-auto px-4 py-8">
        <!-- Header -->
        <header class="flex justify-between items-center mb-8 pb-6 border-b border-gray-200 dark:border-gray-700">
            <div class="flex items-center gap-4">
                <h1 class="text-3xl font-bold text-gray-900 dark:text-white">FastAPI Monitor Dashboard</h1>
                <a href="analytics" class="text-blue-500 hover:text-blue-600 text-sm">Analytics →</a>
            </div>
            
            <div class="flex items-center gap-4">
                <!-- Theme Toggle -->
                <button @click="toggleTheme()" 
                        class="p-2 rounded-lg bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
                    <svg x-show="theme === 'light'" class="w-5 h-5 text-gray-600 dark:text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0020.354 15.354z"></path>
                    </svg>
                    <svg x-show="theme === 'dark'" class="w-5 h-5 text-gray-600 dark:text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path>
                    </svg>
                </button>
                
                <!-- Refresh Button -->
                <button @click="refreshData()" 
                        class="p-2 rounded-lg bg-primary-500 hover:bg-primary-600 text-white transition-all duration-200 hover:scale-105 shadow-lg hover:shadow-xl">
                    <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
                    </svg>
                </button>
                
                <!-- Modern Toggle Switch -->
                <div class="flex items-center gap-3">
                    <span class="text-sm text-gray-600 dark:text-gray-400">Auto Refresh</span>
                    <button @click="toggleAutoRefresh()" 
                            :class="autoRefresh ? 'bg-primary-500' : 'bg-gray-200 dark:bg-gray-700'"
                            class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2">
                        <span :class="autoRefresh ? 'translate-x-6' : 'translate-x-1'"
                              class="inline-block h-4 w-4 transform rounded-full bg-white transition-transform"></span>
                    </button>
                    <span class="text-xs text-gray-500 dark:text-gray-400">(5s)</span>
                </div>
            </div>
        </header>

        <main>
            <!-- Stats Section -->
            <div id="stats-container" class="mb-8">
                {% include "partials/stats.html" %}
            </div>

            <!-- Recent Requests Section -->
            <div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg border border-gray-200 dark:border-gray-700 overflow-hidden">
                <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
                    <h2 class="text-xl font-semibold text-gray-900 dark:text-white">Recent Requests</h2>
                </div>
                <div class="overflow-x-auto">
                    <div id="requests-table-container">
                        <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
                            <thead class="bg-gray-50 dark:bg-gray-800">
                                <tr>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Time</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Method</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Path</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Status</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Response Time</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Size</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">IP</th>
                                </tr>
                            </thead>
                            <tbody id="requests-tbody" class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
                                <!-- Table rows will be loaded here via JavaScript -->
                            </tbody>
                        </table>
                    </div>
                </div>
                <div id="pagination-container" class="px-6 py-4 border-t border-gray-200 dark:border-gray-700">
                    <!-- Pagination will be loaded here via JavaScript -->
                </div>
            </div>
        </main>
        
        <!-- Request Detail Drawer -->
        <div id="request-drawer" 
             x-show="$store.drawer.open"
             x-transition:enter="transition ease-out duration-300"
             x-transition:enter-start="transform translate-x-full"
             x-transition:enter-end="transform translate-x-0"
             x-transition:leave="transition ease-in duration-300"
             x-transition:leave-start="transform translate-x-0"
             x-transition:leave-end="transform translate-x-full"
             class="fixed inset-y-0 right-0 w-1/2 bg-white dark:bg-gray-800 shadow-xl z-50 overflow-y-auto"
             style="display: none;">
            
            <div class="p-6">
                <div class="flex justify-between items-center mb-6">
                    <h3 class="text-lg font-semibold text-gray-900 dark:text-white">Request Details</h3>
                    <button @click="$store.drawer.close()" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
                        <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
                        </svg>
                    </button>
                </div>
                
                <div x-show="$store.drawer.request" class="space-y-6">
                    <!-- Request Info -->
                    <div class="bg-gray-50 dark:bg-gray-700 p-4 rounded-lg">
                        <h4 class="font-medium text-gray-900 dark:text-white mb-2">Request Info</h4>
                        <div class="grid grid-cols-2 gap-4 text-sm">
                            <div><span class="text-gray-500 dark:text-gray-400">Method:</span> <span x-text="$store.drawer.request?.method" class="font-mono text-gray-900 dark:text-gray-100"></span></div>
                            <div><span class="text-gray-500 dark:text-gray-400">Status:</span> <span x-text="$store.drawer.request?.status_code" class="font-mono text-gray-900 dark:text-gray-100"></span></div>
                            <div><span class="text-gray-500 dark:text-gray-400">Path:</span> <span x-text="$store.drawer.request?.path" class="font-mono text-gray-900 dark:text-gray-100"></span></div>
                            <div><span class="text-gray-500 dark:text-gray-400">Time:</span> <span x-text="$store.drawer.request?.formatted_time" class="text-gray-900 dark:text-gray-100"></span></div>
                            <div><span class="text-gray-500 dark:text-gray-400">Response Time:</span> <span x-text="$store.drawer.request?.response_time?.toFixed(1) + 'ms'" class="text-gray-900 dark:text-gray-100"></span></div>
                            <div><span class="text-gray-500 dark:text-gray-400">IP:</span> <span x-text="$store.drawer.request?.client_ip" class="font-mono text-gray-900 dark:text-gray-100"></span></div>
                        </div>
                    </div>
                    
                    <!-- Tabs -->
                    <div x-data="{ activeTab: 'headers' }">
                        <div class="border-b border-gray-200 dark:border-gray-600">
                            <nav class="-mb-px flex space-x-8">
                                <button @click="activeTab = 'headers'" 
                                        :class="activeTab === 'headers' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 dark:text-gray-400'"
                                        class="py-2 px-1 border-b-2 font-medium text-sm">Request Headers</button>
                                <button @click="activeTab = 'query'" 
                                        :class="activeTab === 'query' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 dark:text-gray-400'"
                                        class="py-2 px-1 border-b-2 font-medium text-sm">Query Params</button>
                                <button @click="activeTab = 'reqbody'" 
                                        :class="activeTab === 'reqbody' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 dark:text-gray-400'"
                                        class="py-2 px-1 border-b-2 font-medium text-sm">Request Body</button>
                                <button @click="activeTab = 'respheaders'" 
                                        :class="activeTab === 'respheaders' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 dark:text-gray-400'"
                                        class="py-2 px-1 border-b-2 font-medium text-sm">Response Headers</button>
                                <button @click="activeTab = 'respbody'" 
                                        :class="activeTab === 'respbody' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 dark:text-gray-400'"
                                        class="py-2 px-1 border-b-2 font-medium text-sm">Response Body</button>
                                <button @click="activeTab = 'error'" 
                                        :class="activeTab === 'error' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 dark:text-gray-400'"
                                        class="py-2 px-1 border-b-2 font-medium text-sm" x-show="$store.drawer.request?.error_info">Error</button>
                            </nav>
                        </div>
                        
                        <div class="mt-4">
                            <!-- Request Headers Tab -->
                            <div x-show="activeTab === 'headers'">
                                <pre class="bg-gray-100 dark:bg-gray-900 p-4 rounded text-sm overflow-x-auto text-gray-900 dark:text-gray-100" x-text="JSON.stringify($store.drawer.request?.headers, null, 2)"></pre>
                            </div>
                            
                            <!-- Query Params Tab -->
                            <div x-show="activeTab === 'query'">
                                <pre class="bg-gray-100 dark:bg-gray-900 p-4 rounded text-sm overflow-x-auto text-gray-900 dark:text-gray-100" x-text="$store.drawer.request?.query_params || 'No query parameters'"></pre>
                            </div>
                            
                            <!-- Request Body Tab -->
                            <div x-show="activeTab === 'reqbody'">
                                <pre class="bg-gray-100 dark:bg-gray-900 p-4 rounded text-sm overflow-x-auto text-gray-900 dark:text-gray-100" x-text="$store.drawer.request?.request_body || 'No request body'"></pre>
                            </div>
                            
                            <!-- Response Headers Tab -->
                            <div x-show="activeTab === 'respheaders'">
                                <pre class="bg-gray-100 dark:bg-gray-900 p-4 rounded text-sm overflow-x-auto text-gray-900 dark:text-gray-100" x-text="JSON.stringify($store.drawer.request?.response_headers, null, 2)"></pre>
                            </div>
                            
                            <!-- Response Body Tab -->
                            <div x-show="activeTab === 'respbody'">
                                <pre class="bg-gray-100 dark:bg-gray-900 p-4 rounded text-sm overflow-x-auto text-gray-900 dark:text-gray-100" x-text="$store.drawer.request?.response_body || 'No response body'"></pre>
                            </div>
                            
                            <!-- Error Tab -->
                            <div x-show="activeTab === 'error' && $store.drawer.request?.error_info">
                                <pre class="bg-red-50 dark:bg-red-900 p-4 rounded text-sm overflow-x-auto text-red-800 dark:text-red-200" x-text="JSON.stringify($store.drawer.request?.error_info, null, 2)"></pre>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // Global current page tracker
        let currentPage = 1;
        let currentPageSize = 20;
        
        // Alpine stores
        document.addEventListener('alpine:init', () => {
            Alpine.store('drawer', {
                open: false,
                request: null,
                
                show(requestData) {
                    this.request = requestData;
                    this.open = true;
                },
                
                close() {
                    this.open = false;
                    this.request = null;
                }
            });
        });
        
        function dashboardApp() {
            return {
                theme: localStorage.getItem('theme') || 'light',
                autoRefresh: true,
                refreshInterval: null,
                
                init() {
                    // Apply theme immediately
                    this.applyTheme();
                    // Start auto-refresh on load
                    this.startAutoRefresh();
                    // Load first page of requests
                    this.loadPage(1);
                },
                
                applyTheme() {
                    if (this.theme === 'dark') {
                        document.documentElement.classList.add('dark');
                    } else {
                        document.documentElement.classList.remove('dark');
                    }
                },
                
                toggleTheme() {
                    this.theme = this.theme === 'light' ? 'dark' : 'light';
                    localStorage.setItem('theme', this.theme);
                    this.applyTheme();
                },
                
                toggleAutoRefresh() {
                    this.autoRefresh = !this.autoRefresh;
                    if (this.autoRefresh) {
                        this.startAutoRefresh();
                    } else {
                        this.stopAutoRefresh();
                    }
                },
                
                startAutoRefresh() {
                    if (this.refreshInterval) {
                        clearInterval(this.refreshInterval);
                    }
                    this.refreshInterval = setInterval(() => this.refreshData(), 5000);
                },
                
                stopAutoRefresh() {
                    if (this.refreshInterval) {
                        clearInterval(this.refreshInterval);
                        this.refreshInterval = null;
                    }
                },
                
                refreshData() {
                    fetch('stats-partial')
                        .then(response => response.text())
                        .then(html => document.getElementById('stats-container').innerHTML = html);
                    
                    // Use global current page and page size
                    fetch(`requests-partial?page=${currentPage}&limit=${currentPageSize}`)
                        .then(response => response.json())
                        .then(data => {
                            document.getElementById('requests-tbody').innerHTML = data.rows;
                            document.getElementById('pagination-container').innerHTML = data.pagination;
                        });
                },
                
                loadPage(page) {
                    loadPage(page);
                }
            }
        }
        
        // Global functions for onclick handlers
        function showRequestDetail(requestId) {
            fetch(`api/requests/${requestId}`)
                .then(response => response.json())
                .then(data => {
                    Alpine.store('drawer').show(data);
                })
                .catch(error => console.error('Error fetching request details:', error));
        }
        
        function loadPage(page) {
            currentPage = page;
            fetch(`requests-partial?page=${page}&limit=${currentPageSize}`)
                .then(response => response.json())
                .then(data => {
                    document.getElementById('requests-tbody').innerHTML = data.rows;
                    document.getElementById('pagination-container').innerHTML = data.pagination;
                });
        }
        
        function changePageSize(newSize) {
            currentPageSize = parseInt(newSize);
            currentPage = 1; // Reset to first page when changing size
            loadPage(1);
        }
    </script>
</body>
</html>
