<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Report Viewer - SEO Analyzer</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        [x-cloak] { display: none !important; }
        .score-circle {
            width: 120px; height: 120px;
            border-radius: 50%;
            display: flex; align-items: center; justify-content: center;
            font-size: 2.5rem; font-weight: bold;
            border: 8px solid;
        }
    </style>
</head>
<body class="bg-gray-50 text-gray-800 font-sans"
      x-data="seoViewer('{{ report_id }}')"
      x-init="init()">

    <!-- Header -->
    <header class="bg-white shadow-sm sticky top-0 z-10">
        <div class="max-w-7xl mx-auto px-4 py-4 flex justify-between items-center">
            <div class="flex items-center gap-3">
                <a href="/" class="text-gray-500 hover:text-gray-700 transition">
                    <i class="fa-solid fa-arrow-left text-xl"></i>
                </a>
                <h1 class="text-xl font-bold text-gray-900">Analysis Report</h1>
            </div>
            <div class="text-sm text-gray-500" x-text="report ? report.meta.target_url : 'Loading...'"></div>
        </div>
    </header>

    <!-- Main Content -->
    <main class="max-w-7xl mx-auto px-4 py-8">

        <!-- Loading State & Progress -->
        <div x-show="loading || (status && status.stage !== 'completed' && status.stage !== 'failed')" class="flex flex-col items-center justify-center py-20">
            <i class="fa-solid fa-circle-notch fa-spin text-4xl text-blue-600 mb-4"></i>
            <h2 class="text-xl font-semibold text-gray-700 mb-2" x-text="status ? status.message : 'Loading...'"></h2>

            <div class="w-full max-w-md bg-gray-200 rounded-full h-2.5 dark:bg-gray-300 mt-2">
                <div class="bg-blue-600 h-2.5 rounded-full transition-all duration-500" :style="'width: ' + (status ? status.percent : 0) + '%'"></div>
            </div>
            <p class="text-sm text-gray-500 mt-2" x-text="(status ? status.percent : 0) + '%'"></p>

            <!-- Real-time Log Console -->
            <div class="mt-8 w-full max-w-2xl bg-gray-900 text-green-400 font-mono text-xs p-4 rounded-md shadow-inner h-64 overflow-y-auto">
                <template x-for="log in logs" :key="log.id">
                    <div class="mb-1">
                        <span class="text-gray-500" x-text="log.time"></span>
                        <span x-text="log.message"></span>
                    </div>
                </template>
                <div x-show="logs.length === 0" class="text-gray-600 italic">Waiting for logs...</div>
            </div>
        </div>

        <!-- Error State -->
        <div x-show="error || (status && status.stage === 'failed')" x-cloak class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert">
            <strong class="font-bold">Error!</strong>
            <span class="block sm:inline" x-text="status && status.message ? status.message : 'Failed to load report data.'"></span>
        </div>

        <!-- Dashboard -->
        <div x-show="report && status && status.stage === 'completed'" x-cloak class="space-y-8">

            <!-- Executive Summary -->
            <div class="grid grid-cols-1 md:grid-cols-4 gap-6">
                <!-- Score -->
                <div class="bg-white p-6 rounded-lg shadow-sm flex flex-col items-center justify-center col-span-1">
                    <div class="score-circle mb-2"
                         :class="{
                            'border-green-500 text-green-600': report?.summary.score >= 90,
                            'border-blue-500 text-blue-600': report?.summary.score >= 70 && report?.summary.score < 90,
                            'border-yellow-500 text-yellow-600': report?.summary.score >= 50 && report?.summary.score < 70,
                            'border-red-500 text-red-600': report?.summary.score < 50
                         }"
                         x-text="report?.summary.score.toFixed(0)">
                    </div>
                    <span class="font-semibold text-gray-600" x-text="report?.summary.rating"></span>
                </div>

                <!-- Stats -->
                <div class="col-span-1 md:col-span-3 grid grid-cols-1 sm:grid-cols-3 gap-4">
                    <div class="bg-white p-6 rounded-lg shadow-sm border-l-4 border-red-500">
                        <div class="text-gray-500 text-sm font-medium uppercase">Critical Errors</div>
                        <div class="text-3xl font-bold text-gray-900 mt-1" x-text="counts.errors"></div>
                    </div>
                    <div class="bg-white p-6 rounded-lg shadow-sm border-l-4 border-yellow-500">
                        <div class="text-gray-500 text-sm font-medium uppercase">Warnings</div>
                        <div class="text-3xl font-bold text-gray-900 mt-1" x-text="counts.warnings"></div>
                    </div>
                    <div class="bg-white p-6 rounded-lg shadow-sm border-l-4 border-blue-500">
                        <div class="text-gray-500 text-sm font-medium uppercase">Total Pages</div>
                        <div class="text-3xl font-bold text-gray-900 mt-1" x-text="report?.summary.total_pages"></div>
                    </div>
                    <!-- Size Stat -->
                    <div class="col-span-3 bg-white p-4 rounded-lg shadow-sm flex justify-between items-center text-sm text-gray-600">
                         <span><strong>Avg Page Size:</strong> <span x-text="(report?.metrics?.others?.performance?.avg_size_bytes / 1024).toFixed(1) + ' KB'"></span></span>
                         <span><strong>Avg Load Time:</strong> <span x-text="report?.metrics?.others?.performance?.avg_time.toFixed(3) + 's'"></span></span>
                    </div>
                </div>
            </div>

            <!-- Tabs -->
            <div class="border-b border-gray-200">
                <nav class="-mb-px flex gap-6">
                    <button @click="tab = 'issues'" :class="{'border-blue-500 text-blue-600': tab === 'issues', 'border-transparent text-gray-500': tab !== 'issues'}" class="py-4 px-1 border-b-2 font-medium text-sm transition">Issues List</button>
                    <button @click="tab = 'pages'" :class="{'border-blue-500 text-blue-600': tab === 'pages', 'border-transparent text-gray-500': tab !== 'pages'}" class="py-4 px-1 border-b-2 font-medium text-sm transition">Page Explorer</button>
                </nav>
            </div>

            <!-- Issues Tab -->
            <div x-show="tab === 'issues'" class="space-y-6">
                <!-- Errors -->
                <template x-if="report?.metrics?.issues?.errors?.length > 0">
                    <div class="bg-white rounded-lg shadow-sm overflow-hidden">
                        <div class="bg-red-50 px-6 py-4 border-b border-red-100 flex justify-between">
                            <h3 class="font-semibold text-red-800">Critical Issues</h3>
                            <span class="bg-red-200 text-red-800 text-xs px-2 py-1 rounded-full" x-text="report.metrics.issues.errors.length"></span>
                        </div>
                        <div class="divide-y divide-gray-100">
                            <template x-for="issue in report.metrics.issues.errors">
                                <div class="px-6 py-4 flex justify-between items-center hover:bg-gray-50">
                                    <div>
                                        <div class="font-medium text-gray-900" x-text="issue.name"></div>
                                        <div class="text-sm text-gray-500" x-text="issue.count + ' pages affected'"></div>
                                    </div>
                                    <a :href="'/report/' + reportId + '/issue/' + encodeURIComponent(issue.name)" class="text-blue-600 hover:text-blue-800 text-sm font-medium">
                                        View Details <i class="fa-solid fa-arrow-right ml-1"></i>
                                    </a>
                                </div>
                            </template>
                        </div>
                    </div>
                </template>

                <!-- Warnings -->
                <template x-if="report?.metrics?.issues?.warnings?.length > 0">
                    <div class="bg-white rounded-lg shadow-sm overflow-hidden">
                        <div class="bg-yellow-50 px-6 py-4 border-b border-yellow-100 flex justify-between">
                            <h3 class="font-semibold text-yellow-800">Warnings</h3>
                            <span class="bg-yellow-200 text-yellow-800 text-xs px-2 py-1 rounded-full" x-text="report.metrics.issues.warnings.length"></span>
                        </div>
                        <div class="divide-y divide-gray-100">
                            <template x-for="issue in report.metrics.issues.warnings">
                                <div class="px-6 py-4 flex justify-between items-center hover:bg-gray-50">
                                    <div>
                                        <div class="font-medium text-gray-900" x-text="issue.name"></div>
                                        <div class="text-sm text-gray-500" x-text="issue.count + ' pages affected'"></div>
                                    </div>
                                    <a :href="'/report/' + reportId + '/issue/' + encodeURIComponent(issue.name)" class="text-blue-600 hover:text-blue-800 text-sm font-medium">
                                        View Details <i class="fa-solid fa-arrow-right ml-1"></i>
                                    </a>
                                </div>
                            </template>
                        </div>
                    </div>
                </template>

                <!-- Notices -->
                <template x-if="report?.metrics?.issues?.notices?.length > 0">
                    <div class="bg-white rounded-lg shadow-sm overflow-hidden">
                        <div class="bg-blue-50 px-6 py-4 border-b border-blue-100 flex justify-between">
                            <h3 class="font-semibold text-blue-800">Notices</h3>
                            <span class="bg-blue-200 text-blue-800 text-xs px-2 py-1 rounded-full" x-text="report.metrics.issues.notices.length"></span>
                        </div>
                        <div class="divide-y divide-gray-100">
                            <template x-for="issue in report.metrics.issues.notices">
                                <div class="px-6 py-4 flex justify-between items-center hover:bg-gray-50">
                                    <div>
                                        <div class="font-medium text-gray-900" x-text="issue.name"></div>
                                        <div class="text-sm text-gray-500" x-text="issue.count + ' pages affected'"></div>
                                    </div>
                                    <a :href="'/report/' + reportId + '/issue/' + encodeURIComponent(issue.name)" class="text-blue-600 hover:text-blue-800 text-sm font-medium">
                                        View Details <i class="fa-solid fa-arrow-right ml-1"></i>
                                    </a>
                                </div>
                            </template>
                        </div>
                    </div>
                </template>
            </div>

            <!-- Page Explorer Tab -->
            <div x-show="tab === 'pages'" class="bg-white rounded-lg shadow-sm overflow-hidden">
                <div class="p-4 bg-gray-50 border-b border-gray-200 flex gap-4">
                    <input type="text" x-model="search" placeholder="Search URL..." class="flex-1 px-4 py-2 border rounded-md text-sm">
                    <select x-model="filterStatus" class="px-4 py-2 border rounded-md text-sm">
                        <option value="all">All</option>
                        <option value="Critical">Critical</option>
                        <option value="Warning">Warning</option>
                        <option value="Good">Good</option>
                    </select>
                </div>
                <div class="overflow-x-auto">
                    <table class="min-w-full divide-y divide-gray-200">
                        <thead class="bg-gray-50">
                            <tr>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Status</th>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">URL</th>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Size</th>
                                <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Issues</th>
                            </tr>
                        </thead>
                        <tbody class="bg-white divide-y divide-gray-200">
                            <template x-for="(data, url) in filteredPages" :key="url">
                                <tr class="hover:bg-gray-50 cursor-pointer" @click="window.location.href = '/report/' + reportId + '/page?url=' + encodeURIComponent(url)">
                                    <td class="px-6 py-4 whitespace-nowrap">
                                        <span class="px-2 text-xs font-semibold rounded-full"
                                              :class="{
                                                'bg-red-100 text-red-800': data.status.includes('Critical'),
                                                'bg-yellow-100 text-yellow-800': data.status.includes('Warning'),
                                                'bg-green-100 text-green-800': data.status.includes('Good'),
                                                'bg-blue-100 text-blue-800': data.status.includes('Notice')
                                              }"
                                              x-text="data.status.replace(/[^a-zA-Z]/g, '')">
                                        </span>
                                    </td>
                                    <td class="px-6 py-4 text-sm text-gray-500 max-w-md truncate" x-text="url"></td>
                                    <td class="px-6 py-4 text-sm text-gray-500" x-text="(data.size / 1024).toFixed(1) + ' KB'"></td>
                                    <td class="px-6 py-4 text-sm text-gray-500" x-text="data.issues.length + ' issues'"></td>
                                </tr>
                            </template>
                        </tbody>
                    </table>
                </div>
            </div>

        </div>

    </main>

    <script>
        function seoViewer(reportId) {
            return {
                reportId: reportId,
                report: null,
                status: null,
                loading: true,
                error: false,
                tab: 'issues',
                counts: { errors: 0, warnings: 0 },
                search: '',
                filterStatus: 'all',
                logs: [],
                ws: null,

                init() {
                    this.pollStatus();
                    this.connectWebSocket();
                },

                connectWebSocket() {
                    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';

                    // Logic to ensure we don't connect to 0.0.0.0 which browsers block
                    let hostname = window.location.hostname;
                    let port = window.location.port ? `:${window.location.port}` : '';

                    if (hostname === '0.0.0.0') {
                        hostname = '127.0.0.1';
                        console.log("Detected 0.0.0.0, switching WebSocket to 127.0.0.1");
                    }

                    const wsUrl = `${protocol}//${hostname}${port}/ws/${this.reportId}`;
                    console.log("Connecting to WebSocket:", wsUrl);

                    this.ws = new WebSocket(wsUrl);

                    this.ws.onopen = () => {
                        console.log("WebSocket Connected");
                    };

                    this.ws.onerror = (e) => {
                        console.error("WebSocket Error:", e);
                        this.addLog("WebSocket connection error. Try accessing via 127.0.0.1 instead of 0.0.0.0");
                    };

                    this.ws.onmessage = (event) => {
                        const data = JSON.parse(event.data);

                        if (data.type === 'log') {
                            this.addLog(data.message);
                        } else if (data.type === 'crawl_event') {
                            this.addLog(`Crawled: ${data.url} (${data.status})`);
                        } else if (data.type === 'complete') {
                            this.addLog("Analysis Finished!");
                            this.pollStatus(); // Force status update to trigger completed view
                        } else if (data.type === 'error') {
                            this.addLog(`Error: ${data.message}`);
                        }
                    };
                },

                addLog(message) {
                    this.logs.unshift({
                        id: Date.now(),
                        time: new Date().toLocaleTimeString(),
                        message: message
                    });
                    // Keep logs limited
                    if (this.logs.length > 50) this.logs.pop();
                },

                async pollStatus() {
                    try {
                        const response = await fetch(`/api/status/${this.reportId}`);
                        if (!response.ok) throw new Error('Status check failed');

                        this.status = await response.json();

                        if (this.status.stage === 'completed') {
                            await this.loadReport();
                        } else if (this.status.stage === 'failed') {
                            this.loading = false;
                        } else {
                            // Continue polling
                            this.loading = false; // Show progress UI instead of generic loading
                            setTimeout(() => this.pollStatus(), 2000);
                        }
                    } catch (e) {
                        console.error(e);
                        // Only set error if we haven't loaded report yet and it's a hard fail
                        if (!this.report) this.error = true;
                    }
                },

                async loadReport() {
                    try {
                        this.loading = true;
                        const response = await fetch(`/api/reports/${this.reportId}`);
                        if (!response.ok) throw new Error('Failed to fetch report');
                        this.report = await response.json();
                        this.calculateCounts();
                        this.loading = false;
                        if (this.ws) this.ws.close(); // Close socket when done
                    } catch (e) {
                        console.error(e);
                        this.error = true;
                        this.loading = false;
                    }
                },

                calculateCounts() {
                    if (!this.report || !this.report.metrics || !this.report.metrics.issues) return;

                    const issues = this.report.metrics.issues;
                    if (issues.errors) {
                        this.counts.errors = issues.errors.reduce((acc, i) => acc + i.count, 0);
                    }
                    if (issues.warnings) {
                        this.counts.warnings = issues.warnings.reduce((acc, i) => acc + i.count, 0);
                    }
                },

                get filteredPages() {
                    if (!this.report || !this.report.metrics || !this.report.metrics.page_details) return {};
                    const pages = this.report.metrics.page_details;
                    return Object.fromEntries(
                        Object.entries(pages).filter(([url, data]) => {
                            const matchesSearch = url.toLowerCase().includes(this.search.toLowerCase());
                            const matchesFilter = this.filterStatus === 'all' || data.status.includes(this.filterStatus);
                            return matchesSearch && matchesFilter;
                        })
                    );
                }
            }
        }
    </script>
</body>
</html>
