"use client"

import { useState, useEffect, useCallback, useRef } from "react"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "./ui/dialog"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select"
import { Button } from "./ui/button"
import { Badge } from "./ui/badge"
import { Activity, TrendingDown, TrendingUp, Minus, RefreshCw, Wifi, FileText, Square } from "lucide-react"
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, LineChart, Line } from "recharts"
import { useIsMobile } from "../hooks/use-mobile"
import { fetchApi } from "@/lib/api-config"

const TIMEFRAME_OPTIONS = [
  { value: "hour", label: "1 Hour" },
  { value: "6hour", label: "6 Hours" },
  { value: "day", label: "24 Hours" },
  { value: "3day", label: "3 Days" },
  { value: "week", label: "7 Days" },
]

const TARGET_OPTIONS = [
  { value: "gateway", label: "Gateway (Router)", shortLabel: "Gateway", realtime: false },
  { value: "cloudflare", label: "Cloudflare (1.1.1.1)", shortLabel: "Cloudflare", realtime: true },
  { value: "google", label: "Google DNS (8.8.8.8)", shortLabel: "Google DNS", realtime: true },
  ]

// Realtime test configuration
const REALTIME_TEST_DURATION = 120 // 2 minutes in seconds
const REALTIME_TEST_INTERVAL = 5 // 5 seconds between tests

interface LatencyHistoryPoint {
  timestamp: number
  value: number
  min?: number
  max?: number
  packet_loss?: number
}

interface LatencyStats {
  min: number
  max: number
  avg: number
  current: number
}

interface RealtimeResult {
  target: string
  target_ip: string
  latency_avg: number | null
  latency_min: number | null
  latency_max: number | null
  packet_loss: number
  status: string
  timestamp?: number
}

interface LatencyDetailModalProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  currentLatency?: number
}

const CustomTooltip = ({ active, payload, label }: any) => {
  if (active && payload && payload.length) {
    const entry = payload[0]
    const data = entry?.payload
    const packetLoss = data?.packet_loss
    const hasMinMax = data?.min !== undefined && data?.max !== undefined && data?.min !== data?.max
    
    return (
      <div className="bg-gray-900/95 backdrop-blur-sm border border-gray-700 rounded-lg p-3 shadow-xl">
        <p className="text-sm font-semibold text-white mb-2">{label}</p>
        <div className="space-y-1.5">
          {hasMinMax ? (
            // Show min/avg/max when downsampled data is available
            <>
              <div className="flex items-center gap-2">
                <div className="w-2.5 h-2.5 rounded-full flex-shrink-0 bg-green-500" />
                <span className="text-xs text-gray-300 min-w-[60px]">Min:</span>
                <span className="text-sm font-semibold text-green-400">{data.min} ms</span>
              </div>
              <div className="flex items-center gap-2">
                <div className="w-2.5 h-2.5 rounded-full flex-shrink-0 bg-blue-500" />
                <span className="text-xs text-gray-300 min-w-[60px]">Avg:</span>
                <span className="text-sm font-semibold text-white">{data.value} ms</span>
              </div>
              <div className="flex items-center gap-2">
                <div className="w-2.5 h-2.5 rounded-full flex-shrink-0 bg-red-500" />
                <span className="text-xs text-gray-300 min-w-[60px]">Max:</span>
                <span className="text-sm font-semibold text-red-400">{data.max} ms</span>
              </div>
            </>
          ) : (
            // Simple latency display for single data points
            <div className="flex items-center gap-2">
              <div className="w-2.5 h-2.5 rounded-full flex-shrink-0 bg-blue-500" />
              <span className="text-xs text-gray-300 min-w-[60px]">Latency:</span>
              <span className="text-sm font-semibold text-white">{entry.value} ms</span>
            </div>
          )}
          {packetLoss !== undefined && packetLoss > 0 && (
            <div className="flex items-center gap-2">
              <div className="w-2.5 h-2.5 rounded-full flex-shrink-0 bg-orange-500" />
              <span className="text-xs text-gray-300 min-w-[60px]">Pkt Loss:</span>
              <span className="text-sm font-semibold text-orange-400">{packetLoss}%</span>
            </div>
          )}
        </div>
      </div>
    )
  }
  return null
}

const getStatusColor = (latency: number) => {
  if (latency >= 200) return "#ef4444"
  if (latency >= 100) return "#f59e0b"
  return "#22c55e"
}

const getStatusInfo = (latency: number | null) => {
  if (latency === null || latency === 0) return { status: "N/A", color: "bg-gray-500/10 text-gray-500 border-gray-500/20" }
  if (latency < 50) return { status: "Excellent", color: "bg-green-500/10 text-green-500 border-green-500/20" }
  if (latency < 100) return { status: "Good", color: "bg-green-500/10 text-green-500 border-green-500/20" }
  if (latency < 200) return { status: "Fair", color: "bg-yellow-500/10 text-yellow-500 border-yellow-500/20" }
  return { status: "Poor", color: "bg-red-500/10 text-red-500 border-red-500/20" }
}

const getStatusText = (latency: number | null): string => {
  if (latency === null || latency === 0) return "N/A"
  if (latency < 50) return "Excellent"
  if (latency < 100) return "Good"
  if (latency < 200) return "Fair"
  return "Poor"
}

interface ReportData {
  target: string
  targetLabel: string
  isRealtime: boolean
  stats: LatencyStats
  realtimeResults: RealtimeResult[]
  data: LatencyHistoryPoint[]
  timeframe: string
  testDuration?: number
}

const generateLatencyReport = (report: ReportData) => {
  const now = new Date().toLocaleString()
  const logoUrl = `${window.location.origin}/images/proxmenux-logo.png`
  
  // Calculate stats for realtime results - all values are individual ping measurements in latency_avg
  const validRealtimeValues = report.realtimeResults.filter(r => r.latency_avg !== null).map(r => r.latency_avg!)
  const realtimeStats = validRealtimeValues.length > 0 ? {
    min: Math.min(...validRealtimeValues),
    max: Math.max(...validRealtimeValues),
    avg: validRealtimeValues.reduce((acc, v) => acc + v, 0) / validRealtimeValues.length,
    current: validRealtimeValues[validRealtimeValues.length - 1] ?? null,
    avgPacketLoss: report.realtimeResults.reduce((acc, r) => acc + (r.packet_loss || 0), 0) / report.realtimeResults.length,
  } : null

  const statusText = report.isRealtime 
    ? getStatusText(realtimeStats?.current ?? null)
    : getStatusText(report.stats.current)
  
  // Colors matching Lynis report
  const statusColorMap: Record<string, string> = {
    "Excellent": "#16a34a",
    "Good": "#16a34a", 
    "Fair": "#ca8a04",
    "Poor": "#dc2626",
    "N/A": "#64748b"
  }
  const statusColor = statusColorMap[statusText] || "#64748b"

  const timeframeLabel = TIMEFRAME_OPTIONS.find(t => t.value === report.timeframe)?.label || report.timeframe

  // Build test results table for realtime mode - each row is now an individual ping measurement
  const realtimeTableRows = report.realtimeResults.map((r, i) => `
    <tr${r.packet_loss > 0 ? ' class="warn"' : ''}>
      <td>${i + 1}</td>
      <td>${new Date(r.timestamp || Date.now()).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })}</td>
      <td style="font-weight:600;color:${statusColorMap[getStatusText(r.latency_avg)] || '#64748b'}">${r.latency_avg !== null ? r.latency_avg.toFixed(1) + ' ms' : 'Failed'}</td>
      <td${r.packet_loss > 0 ? ' style="color:#dc2626;font-weight:600;"' : ''}>${r.packet_loss}%</td>
      <td><span class="f-tag" style="background:${statusColorMap[getStatusText(r.latency_avg)] || '#64748b'}15;color:${statusColorMap[getStatusText(r.latency_avg)] || '#64748b'}">${getStatusText(r.latency_avg)}</span></td>
    </tr>
  `).join('')

  // Build history summary for gateway mode
  const historyStats = report.data.length > 0 ? {
    samples: report.data.length,
    avgPacketLoss: (report.data.reduce((acc, d) => acc + (d.packet_loss || 0), 0) / report.data.length).toFixed(2),
    startTime: new Date(report.data[0].timestamp * 1000).toLocaleString(),
    endTime: new Date(report.data[report.data.length - 1].timestamp * 1000).toLocaleString(),
  } : null

  // Build history table rows for gateway mode (last 20 records)
  const historyTableRows = report.data.slice(-20).map((d, i) => `
    <tr${d.packet_loss && d.packet_loss > 0 ? ' class="warn"' : ''}>
      <td>${i + 1}</td>
      <td>${new Date(d.timestamp * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</td>
      <td style="font-weight:600;color:${statusColorMap[getStatusText(d.value)] || '#64748b'}">${d.value !== null ? d.value.toFixed(1) + ' ms' : 'Failed'}</td>
      <td${d.packet_loss && d.packet_loss > 0 ? ' style="color:#dc2626;font-weight:600;"' : ''}>${d.packet_loss?.toFixed(1) ?? 0}%</td>
      <td><span class="f-tag" style="background:${statusColorMap[getStatusText(d.value)] || '#64748b'}15;color:${statusColorMap[getStatusText(d.value)] || '#64748b'}">${getStatusText(d.value)}</span></td>
    </tr>
  `).join('')

  // Generate chart SVG - data already expanded for realtime
  const chartData = report.isRealtime
    ? report.realtimeResults.filter(r => r.latency_avg !== null).map(r => r.latency_avg!)
    : report.data.map(d => d.value || 0)
  
  let chartSvg = '<p style="text-align:center;color:#64748b;padding:20px;">Not enough data points for chart</p>'
  if (chartData.length >= 2) {
    const rawMin = Math.min(...chartData)
    const rawMax = Math.max(...chartData)
    // Ensure a minimum range of 10ms or 20% of the average to avoid flat lines
    const avgVal = chartData.reduce((a, b) => a + b, 0) / chartData.length
    const minRange = Math.max(10, avgVal * 0.2)
    const range = Math.max(rawMax - rawMin, minRange)
    // Center the data if range was expanded
    const midPoint = (rawMin + rawMax) / 2
    const minVal = midPoint - range / 2
    const maxVal = midPoint + range / 2
    
    const width = 700
    const height = 120
    const padding = 40
    const chartHeight = height - padding * 2
    const chartWidth = width - padding * 2
    
    const points = chartData.map((val, i) => {
      const x = padding + (i / (chartData.length - 1)) * chartWidth
      const y = padding + chartHeight - ((val - minVal) / range) * chartHeight
      return `${x},${y}`
    }).join(' ')
    
    const areaPoints = `${padding},${height - padding} ${points} ${width - padding},${height - padding}`
    
    chartSvg = `
      <svg width="100%" viewBox="0 0 ${width} ${height}" style="display:block;">
        <defs>
          <linearGradient id="areaGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stop-color="#3b82f6" stop-opacity="0.3"/>
            <stop offset="100%" stop-color="#3b82f6" stop-opacity="0.05"/>
          </linearGradient>
        </defs>
        <line x1="${padding}" y1="${padding}" x2="${padding}" y2="${height - padding}" stroke="#e2e8f0" stroke-width="1"/>
        <line x1="${padding}" y1="${height - padding}" x2="${width - padding}" y2="${height - padding}" stroke="#e2e8f0" stroke-width="1"/>
        <line x1="${padding}" y1="${height / 2}" x2="${width - padding}" y2="${height / 2}" stroke="#e2e8f0" stroke-width="1" stroke-dasharray="4"/>
        <text x="${padding - 5}" y="${padding + 4}" font-size="9" fill="#64748b" text-anchor="end">${Math.round(maxVal)}ms</text>
        <text x="${padding - 5}" y="${height / 2 + 3}" font-size="9" fill="#64748b" text-anchor="end">${Math.round((minVal + maxVal) / 2)}ms</text>
        <text x="${padding - 5}" y="${height - padding + 4}" font-size="9" fill="#64748b" text-anchor="end">${Math.round(minVal)}ms</text>
        <polygon points="${areaPoints}" fill="url(#areaGrad)"/>
        <polyline points="${points}" fill="none" stroke="#3b82f6" stroke-width="2"/>
        <text x="${width / 2}" y="${height - 5}" font-size="9" fill="#64748b" text-anchor="middle">${chartData.length} samples</text>
      </svg>
    `
  }

  const html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Network Latency Report - ${report.targetLabel}</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: #1a1a2e; background: #fff; font-size: 13px; line-height: 1.5; }
  @page { margin: 10mm; size: A4; }
  @media print {
    html, body { margin: 0 !important; padding: 0 !important; }
    .no-print { display: none !important; }
    .page-break { page-break-before: always; }
    * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
    body { font-size: 11px; padding-top: 0; }
    .section { margin-bottom: 16px; }
    .rpt-header-left p, .rpt-header-right { color: #374151; }
    .rpt-header-right .rid { color: #4b5563; }
    .exec-text p { color: #374151; }
    .score-bar-labels { color: #4b5563; }
    .card-label { color: #4b5563; }
    .card-sub { color: #374151; }
    .chk-tbl th { color: #374151; }
    .rpt-footer { color: #4b5563; }
  }
  @media screen {
    body { max-width: 1000px; margin: 0 auto; padding: 24px 32px; padding-top: 64px; }
  }
  
  /* Top bar for screen only */
  .top-bar {
    position: fixed; top: 0; left: 0; right: 0; background: #0f172a; color: #e2e8f0;
    padding: 12px 16px; display: flex; align-items: center; justify-content: space-between; z-index: 100;
    font-size: 13px;
  }
  .top-bar-left { display: flex; align-items: center; gap: 12px; }
  .top-bar-title { font-weight: 600; }
  .top-bar-subtitle { font-size: 11px; color: #94a3b8; display: none; }
  .top-bar button {
    background: #06b6d4; color: #fff; border: none; padding: 10px 20px; border-radius: 6px;
    font-size: 14px; font-weight: 600; cursor: pointer;
  }
  .top-bar button:hover { background: #0891b2; }
  @media (min-width: 640px) {
    .top-bar { padding: 12px 24px; }
    .top-bar-subtitle { display: block; }
  }
  @media print { .top-bar { display: none; } body { padding-top: 0; } }

  /* Header */
  .rpt-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: 18px 0; border-bottom: 3px solid #0f172a; margin-bottom: 22px;
  }
  .rpt-header-left { display: flex; align-items: center; gap: 14px; }
  .rpt-header-left img { height: 44px; width: auto; }
  .rpt-header-left h1 { font-size: 22px; font-weight: 700; color: #0f172a; }
  .rpt-header-left p { font-size: 11px; color: #64748b; }
  .rpt-header-right { text-align: right; font-size: 11px; color: #64748b; line-height: 1.6; }
  .rpt-header-right .rid { font-family: monospace; font-size: 10px; color: #94a3b8; }

  /* Sections */
  .section { margin-bottom: 22px; }
  .section-title {
    font-size: 14px; font-weight: 700; color: #0f172a; text-transform: uppercase;
    letter-spacing: 0.05em; padding-bottom: 5px; border-bottom: 2px solid #e2e8f0; margin-bottom: 12px;
  }

  /* Executive summary */
  .exec-box {
    display: flex; align-items: flex-start; gap: 20px; padding: 20px;
    background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; margin-bottom: 16px;
    flex-wrap: wrap;
  }
  .score-ring {
    width: 96px; height: 96px; border-radius: 50%; display: flex; flex-direction: column;
    align-items: center; justify-content: center; border: 4px solid; flex-shrink: 0;
  }
  .score-num { font-size: 32px; font-weight: 800; line-height: 1; }
  .score-unit { font-size: 14px; font-weight: 600; opacity: 0.8; }
  .score-lbl { font-size: 9px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; margin-top: 2px; }
  .exec-text { flex: 1; min-width: 200px; }
  .exec-text h3 { font-size: 16px; margin-bottom: 4px; }
  .exec-text p { font-size: 12px; color: #64748b; line-height: 1.5; }

  /* Latency gauge */
  .latency-gauge {
    display: flex; flex-direction: column; align-items: center; flex-shrink: 0; width: 160px;
  }
  .gauge-value { display: flex; align-items: baseline; gap: 2px; margin-top: -10px; }
  .gauge-num { font-size: 32px; font-weight: 800; line-height: 1; }
  .gauge-unit { font-size: 14px; font-weight: 600; opacity: 0.8; }
  .gauge-status { font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; margin-top: 2px; }
  
  /* Latency range display */
  .latency-range {
    display: flex; gap: 16px; margin-top: 12px; padding-top: 12px; border-top: 1px solid #e2e8f0;
    flex-wrap: wrap;
  }
  .range-item { display: flex; flex-direction: column; gap: 2px; min-width: 60px; }
  .range-label { font-size: 9px; font-weight: 600; color: #94a3b8; text-transform: uppercase; }
  .range-value { font-size: 14px; font-weight: 700; }
  


  /* Grids */
  .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
  .grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 8px; }
  .grid-4 { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 8px; margin-bottom: 8px; }
  .card { padding: 10px 12px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 6px; }
  .card-label { font-size: 10px; font-weight: 600; color: #94a3b8; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 2px; }
  .card-value { font-size: 13px; font-weight: 600; color: #0f172a; }
  .card-c { text-align: center; }
  .card-c .card-value { font-size: 20px; font-weight: 800; }
  .card-c .card-label { margin-top: 3px; margin-bottom: 0; }
  .card-sub { font-size: 9px; color: #64748b; margin-top: 2px; }

  /* Tags */
  .f-tag { font-size: 9px; padding: 2px 6px; border-radius: 4px; font-weight: 600; }

  /* Tables */
  .chk-tbl { width: 100%; border-collapse: collapse; font-size: 11px; margin-bottom: 14px; }
  .chk-tbl th { text-align: left; padding: 6px 8px; font-size: 10px; color: #64748b; font-weight: 600; border-bottom: 1px solid #e2e8f0; background: #f1f5f9; }
  .chk-tbl td { padding: 5px 8px; border-bottom: 1px solid #f1f5f9; color: #1e293b; }
  .chk-tbl tr.warn { background: #fef2f2; }

  /* Thresholds */
  .threshold-item { 
    display: flex; align-items: center; gap: 10px; padding: 8px 12px;
    background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 4px; margin-bottom: 6px;
  }
  .threshold-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
  .threshold-item p { font-size: 11px; color: #374151; }
  .threshold-item strong { color: #0f172a; }

  /* Info box */
  .info-box {
    background: #ecfeff; border: 1px solid #a5f3fc; border-left: 4px solid #06b6d4;
    border-radius: 4px; padding: 12px 14px; margin-top: 12px;
  }
  .info-box h4 { font-size: 11px; font-weight: 700; color: #0891b2; margin-bottom: 4px; }
  .info-box p { font-size: 11px; color: #0e7490; }

  /* Footer */
  .rpt-footer {
    margin-top: 32px; padding-top: 12px; border-top: 1px solid #e2e8f0;
    display: flex; justify-content: space-between; font-size: 10px; color: #94a3b8;
  }

  /* Print styles */
  @media print {
    * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
    body { padding: 10mm; font-size: 10pt; }
    .no-print { display: none !important; }
    .container { max-width: 100%; padding: 0; }
    
    /* Prevent page breaks inside elements */
    .section { page-break-inside: avoid; break-inside: avoid; }
    .exec-box { page-break-inside: avoid; break-inside: avoid; }
    .card { page-break-inside: avoid; break-inside: avoid; }
    .threshold-item { page-break-inside: avoid; break-inside: avoid; }
    .info-box { page-break-inside: avoid; break-inside: avoid; }
    .chk-tbl { page-break-inside: avoid; break-inside: avoid; }
    .latency-gauge { page-break-inside: avoid; break-inside: avoid; }
    .latency-range { page-break-inside: avoid; break-inside: avoid; }
    
    /* Force page breaks before major sections if needed */
    .section { page-break-before: auto; }
    
    /* Keep headers with their content */
    .section-title { page-break-after: avoid; break-after: avoid; }
    
    /* Ensure grids don't break awkwardly */
    .grid-2, .grid-3, .grid-4 { page-break-inside: avoid; break-inside: avoid; }
    
    /* Table rows - try to keep together */
    .chk-tbl tr { page-break-inside: avoid; break-inside: avoid; }
    .chk-tbl thead { display: table-header-group; }
    
    /* Footer always at bottom */
    .rpt-footer { 
      page-break-inside: avoid; break-inside: avoid;
      margin-top: 20px;
    }
    
    /* Reduce spacing for print */
    .section { margin-bottom: 15px; }
    .exec-box { padding: 12px; }
    
    /* Ensure SVG charts print correctly */
    svg { max-width: 100%; height: auto; }
  }

  /* NOTE: No mobile-specific print overrides — print layout is always A4/desktop
     regardless of the device generating the PDF. The @media print block above
     handles all necessary print adjustments. */
</style>
</head>
<body>

<!-- Top bar for screen -->
<div class="top-bar no-print">
  <div class="top-bar-left">
    <div>
      <div class="top-bar-title">ProxMenux Network Latency Report</div>
      <div class="top-bar-subtitle">Review the report, then print or save as PDF</div>
    </div>
  </div>
  <button onclick="window.print()">Print / Save as PDF</button>
</div>

<!-- Header -->
<div class="rpt-header">
  <div class="rpt-header-left">
    <img src="${logoUrl}" alt="ProxMenux" onerror="this.style.display='none'" />
    <div>
      <h1>Network Latency Report</h1>
      <p>ProxMenux Monitor - Network Performance Analysis</p>
    </div>
  </div>
  <div class="rpt-header-right">
    <div><strong>Date:</strong> ${now}</div>
    <div><strong>Target:</strong> ${report.targetLabel}</div>
    <div><strong>Mode:</strong> ${report.isRealtime ? 'Real-time Test' : 'Historical Analysis'}</div>
    <div class="rid">ID: PMXL-${Date.now().toString(36).toUpperCase()}</div>
  </div>
</div>

<!-- 1. Executive Summary -->
<div class="section">
  <div class="section-title">1. Executive Summary</div>
  <div class="exec-box">
    <div class="latency-gauge">
      <svg viewBox="0 0 120 90" width="160" height="120">
        <!-- Gauge background arc -->
        <path d="M 10 70 A 50 50 0 0 1 110 70" fill="none" stroke="#e2e8f0" stroke-width="8" stroke-linecap="round"/>
        <!-- Colored segments: Excellent (green), Good (green), Fair (yellow), Poor (red) -->
        <path d="M 10 70 A 50 50 0 0 1 35 28" fill="none" stroke="#16a34a" stroke-width="8" stroke-linecap="round"/>
        <path d="M 35 28 A 50 50 0 0 1 60 20" fill="none" stroke="#22c55e" stroke-width="8"/>
        <path d="M 60 20 A 50 50 0 0 1 85 28" fill="none" stroke="#ca8a04" stroke-width="8"/>
        <path d="M 85 28 A 50 50 0 0 1 110 70" fill="none" stroke="#dc2626" stroke-width="8" stroke-linecap="round"/>
        <!-- Needle -->
        <line x1="60" y1="70" x2="${60 + 40 * Math.cos(Math.PI - (Math.min(300, report.isRealtime ? (realtimeStats?.avg ?? 0) : parseFloat(String(report.stats.avg))) / 300) * Math.PI)}" y2="${70 - 40 * Math.sin(Math.PI - (Math.min(300, report.isRealtime ? (realtimeStats?.avg ?? 0) : parseFloat(String(report.stats.avg))) / 300) * Math.PI)}" stroke="${statusColor}" stroke-width="3" stroke-linecap="round"/>
        <circle cx="60" cy="70" r="6" fill="${statusColor}"/>
        <!-- Labels -->
        <text x="8" y="87" font-size="7" fill="#64748b">0</text>
        <text x="98" y="87" font-size="7" fill="#64748b">300+</text>
      </svg>
      <div class="gauge-value" style="color:${statusColor};">
        <span class="gauge-num">${report.isRealtime ? (realtimeStats?.avg?.toFixed(0) ?? 'N/A') : report.stats.avg}</span>
        <span class="gauge-unit">ms</span>
      </div>
      <div class="gauge-status" style="color:${statusColor};">${statusText}</div>
    </div>
    <div class="exec-text">
      <h3>Network Latency Assessment${report.isRealtime ? ' (Real-time)' : ''}</h3>
      <p>
        ${report.isRealtime 
          ? `Real-time latency test to <strong>${report.targetLabel}</strong> with <strong>${report.realtimeResults.length} samples</strong> collected over ${report.testDuration ? Math.round(report.testDuration / 60) + ' minute(s)' : 'the test period'}. 
             Average latency: <strong style="color:${statusColor}">${realtimeStats?.avg?.toFixed(1) ?? 'N/A'} ms</strong>.
             ${realtimeStats && realtimeStats.avgPacketLoss > 0 ? `<span style="color:#dc2626">Average packet loss: ${realtimeStats.avgPacketLoss.toFixed(1)}%.</span>` : '<span style="color:#16a34a">No packet loss detected.</span>'}`
          : `Historical latency analysis to <strong>Gateway</strong> over <strong>${timeframeLabel.toLowerCase()}</strong>.
             <strong>${report.data.length} samples</strong> analyzed.
             Average latency: <strong style="color:${statusColor}">${report.stats.avg} ms</strong>.`
        }
      </p>
      <div class="latency-range">
        <div class="range-item">
          <span class="range-label">Minimum</span>
          <span class="range-value" style="color:#16a34a;">${report.isRealtime ? (realtimeStats?.min?.toFixed(1) ?? 'N/A') : report.stats.min} ms</span>
        </div>
        <div class="range-item">
          <span class="range-label">Average</span>
          <span class="range-value" style="color:${statusColor};">${report.isRealtime ? (realtimeStats?.avg?.toFixed(1) ?? 'N/A') : report.stats.avg} ms</span>
        </div>
        <div class="range-item">
          <span class="range-label">Maximum</span>
          <span class="range-value" style="color:#dc2626;">${report.isRealtime ? (realtimeStats?.max?.toFixed(1) ?? 'N/A') : report.stats.max} ms</span>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- 2. Statistics -->
<div class="section">
  <div class="section-title">2. Latency Statistics</div>
  <div class="grid-4">
    <div class="card card-c">
      <div class="card-value" style="color:${statusColor};">${report.isRealtime ? (realtimeStats?.current?.toFixed(1) ?? 'N/A') : report.stats.current}<span style="font-size:10px;color:#64748b;"> ms</span></div>
      <div class="card-label">Current</div>
    </div>
    <div class="card card-c">
      <div class="card-value" style="color:#16a34a;">${report.isRealtime ? (realtimeStats?.min?.toFixed(1) ?? 'N/A') : report.stats.min}<span style="font-size:10px;color:#64748b;"> ms</span></div>
      <div class="card-label">Minimum</div>
    </div>
    <div class="card card-c">
      <div class="card-value">${report.isRealtime ? (realtimeStats?.avg?.toFixed(1) ?? 'N/A') : report.stats.avg}<span style="font-size:10px;color:#64748b;"> ms</span></div>
      <div class="card-label">Average</div>
    </div>
    <div class="card card-c">
      <div class="card-value" style="color:#dc2626;">${report.isRealtime ? (realtimeStats?.max?.toFixed(1) ?? 'N/A') : report.stats.max}<span style="font-size:10px;color:#64748b;"> ms</span></div>
      <div class="card-label">Maximum</div>
    </div>
  </div>
  <div class="grid-3">
    <div class="card">
      <div class="card-label">Sample Count</div>
      <div class="card-value">${report.isRealtime ? report.realtimeResults.length : report.data.length}</div>
    </div>
    <div class="card">
      <div class="card-label">Packet Loss (Avg)</div>
      <div class="card-value" style="color:${(report.isRealtime ? (realtimeStats?.avgPacketLoss ?? 0) : parseFloat(historyStats?.avgPacketLoss ?? '0')) > 0 ? '#dc2626' : '#16a34a'};">
        ${report.isRealtime ? (realtimeStats?.avgPacketLoss?.toFixed(1) ?? '0') : (historyStats?.avgPacketLoss ?? '0')}%
      </div>
    </div>
    <div class="card">
      <div class="card-label">Test Period</div>
      <div class="card-value" style="font-size:11px;">
        ${report.isRealtime 
          ? (report.testDuration ? Math.round(report.testDuration / 60) + ' min' : 'Real-time')
          : timeframeLabel}
      </div>
    </div>
  </div>
</div>

<!-- 3. Latency Graph (always section 3) -->
<div class="section">
  <div class="section-title">3. Latency Graph</div>
  <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:16px;">
    ${chartSvg}
  </div>
</div>

<!-- 4. Performance Thresholds (always section 4) -->
<div class="section">
  <div class="section-title">4. Performance Thresholds</div>
  <div class="threshold-item">
    <div class="threshold-dot" style="background:#16a34a;"></div>
    <p><strong>Excellent (&lt; 50ms):</strong> Optimal for real-time applications, gaming, and video calls.</p>
  </div>
  <div class="threshold-item">
    <div class="threshold-dot" style="background:#16a34a;"></div>
    <p><strong>Good (50-100ms):</strong> Acceptable for most applications with minimal impact.</p>
  </div>
  <div class="threshold-item">
    <div class="threshold-dot" style="background:#ca8a04;"></div>
    <p><strong>Fair (100-200ms):</strong> Noticeable delay. May affect VoIP and interactive applications.</p>
  </div>
  <div class="threshold-item">
    <div class="threshold-dot" style="background:#dc2626;"></div>
    <p><strong>Poor (&gt; 200ms):</strong> Significant latency. Investigation recommended.</p>
  </div>
</div>

  ${report.isRealtime && report.realtimeResults.length > 0 ? `
  <!-- 5. Detailed Test Results (for Cloudflare / Google DNS) -->
  <div class="section">
  <div class="section-title">5. Detailed Test Results</div>
  <table class="chk-tbl">
  <thead>
  <tr>
  <th>#</th>
  <th>Time</th>
  <th>Latency</th>
  <th>Packet Loss</th>
  <th>Status</th>
  </tr>
  </thead>
  <tbody>
  ${realtimeTableRows}
  </tbody>
  </table>
</div>
` : ''}

${!report.isRealtime && report.data.length > 0 ? `
<!-- 5. Detailed History (for Gateway) -->
<div class="section">
  <div class="section-title">5. Latency History (Last ${Math.min(20, report.data.length)} Records)</div>
  <table class="chk-tbl">
  <thead>
  <tr>
  <th>#</th>
  <th>Time</th>
  <th>Latency</th>
  <th>Packet Loss</th>
  <th>Status</th>
  </tr>
  </thead>
  <tbody>
  ${historyTableRows}
  </tbody>
  </table>
</div>
` : ''}

<!-- Methodology -->
<div class="section">
  <div class="section-title">${(report.isRealtime && report.realtimeResults.length > 0) || (!report.isRealtime && report.data.length > 0) ? '6' : '5'}. Methodology</div>
  <div class="grid-2">
    <div class="card">
      <div class="card-label">Test Method</div>
      <div class="card-value" style="font-size:12px;">ICMP Echo Request (Ping)</div>
    </div>
    <div class="card">
      <div class="card-label">Samples per Test</div>
      <div class="card-value" style="font-size:12px;">3 consecutive pings</div>
    </div>
    <div class="card">
      <div class="card-label">Target</div>
      <div class="card-value" style="font-size:12px;">${report.targetLabel}</div>
    </div>
    <div class="card">
      <div class="card-label">Target IP</div>
      <div class="card-value" style="font-size:12px;">${report.target === 'gateway' ? 'Default Gateway' : report.target === 'cloudflare' ? '1.1.1.1' : '8.8.8.8'}</div>
    </div>
  </div>
  <div class="info-box">
    <h4>Performance Assessment</h4>
    <p>${
      statusText === 'Excellent' ? 'Network latency is excellent. No action required.' :
      statusText === 'Good' ? 'Network latency is within acceptable parameters.' :
      statusText === 'Fair' ? 'Network latency is elevated. Consider investigating network congestion or routing issues.' :
      statusText === 'Poor' ? 'Network latency is critically high. Immediate investigation recommended.' :
      'Unable to determine network status.'
    }</p>
  </div>
</div>

<!-- Footer -->
<div class="rpt-footer">
  <div>ProxMenux Monitor - Network Performance Report</div>
  <div>Generated: ${now} | Report ID: PMXL-${Date.now().toString(36).toUpperCase()}</div>
</div>

</body>
</html>`

  // Use Blob URL for Safari-safe preview
  const blob = new Blob([html], { type: "text/html" })
  const url = URL.createObjectURL(blob)
  window.open(url, "_blank")
}

export function LatencyDetailModal({ open, onOpenChange, currentLatency }: LatencyDetailModalProps) {
  const [timeframe, setTimeframe] = useState("hour")
  const [target, setTarget] = useState("gateway")
  const [data, setData] = useState<LatencyHistoryPoint[]>([])
  const [stats, setStats] = useState<LatencyStats>({ min: 0, max: 0, avg: 0, current: 0 })
  const [loading, setLoading] = useState(true)
  const [realtimeResults, setRealtimeResults] = useState<RealtimeResult[]>([])
  const [realtimeTesting, setRealtimeTesting] = useState(false)
  const [testProgress, setTestProgress] = useState(0) // 0-100 percentage
  const [testStartTime, setTestStartTime] = useState<number | null>(null)
  const testIntervalRef = useRef<NodeJS.Timeout | null>(null)
  const isMobile = useIsMobile()

  const isRealtime = TARGET_OPTIONS.find(t => t.value === target)?.realtime ?? false

  // Cleanup on unmount or close
  useEffect(() => {
    if (!open) {
      stopRealtimeTest()
    }
    return () => {
      stopRealtimeTest()
    }
  }, [open])

  // Fetch history for gateway
  useEffect(() => {
    if (open && target === "gateway") {
      fetchHistory()
    }
  }, [open, timeframe, target])

  // Auto-start test when switching to realtime target
  useEffect(() => {
    if (open && isRealtime) {
      // Clear previous results and start new test
      setRealtimeResults([])
      startRealtimeTest()
    } else {
      stopRealtimeTest()
    }
  }, [open, target])

  const fetchHistory = async () => {
    setLoading(true)
    try {
      const result = await fetchApi<{ data: LatencyHistoryPoint[]; stats: LatencyStats; target: string }>(
        `/api/network/latency/history?target=${target}&timeframe=${timeframe}`
      )
      if (result && result.data) {
        setData(result.data)
        setStats(result.stats)
      }
    } catch (err) {
      // Silently fail
    } finally {
      setLoading(false)
    }
  }

  const runSingleTest = useCallback(async () => {
    try {
      const result = await fetchApi<RealtimeResult>(`/api/network/latency/current?target=${target}`)
      if (result) {
        const baseTime = Date.now()
        // Expand each ping result into 3 individual samples (min, avg, max) with slightly different timestamps
        // This ensures the graph shows all actual measured values, not just averages
        const samples: RealtimeResult[] = []
        
        if (result.latency_min !== null) {
          samples.push({
            ...result,
            latency_avg: result.latency_min,
            timestamp: baseTime - 200,  // Slightly earlier
          })
        }
        if (result.latency_avg !== null && result.latency_avg !== result.latency_min && result.latency_avg !== result.latency_max) {
          samples.push({
            ...result,
            latency_avg: result.latency_avg,
            timestamp: baseTime,
          })
        }
        if (result.latency_max !== null) {
          samples.push({
            ...result,
            latency_avg: result.latency_max,
            timestamp: baseTime + 200,  // Slightly later
          })
        }
        
        // Fallback if no valid samples
        if (samples.length === 0 && result.latency_avg !== null) {
          samples.push({ ...result, timestamp: baseTime })
        }
        
        setRealtimeResults(prev => [...prev, ...samples])
      }
    } catch (err) {
      // Silently fail
    }
  }, [target])

  const startRealtimeTest = useCallback(() => {
    if (realtimeTesting) return
    
    setRealtimeTesting(true)
    setTestProgress(0)
    setTestStartTime(Date.now())
    
    // Run first test immediately
    runSingleTest()
    
    // Set up interval for subsequent tests
    const totalTests = REALTIME_TEST_DURATION / REALTIME_TEST_INTERVAL
    let testCount = 1
    
    testIntervalRef.current = setInterval(() => {
      testCount++
      const progress = Math.min(100, (testCount / totalTests) * 100)
      setTestProgress(progress)
      
      runSingleTest()
      
      // Stop after duration
      if (testCount >= totalTests) {
        stopRealtimeTest()
      }
    }, REALTIME_TEST_INTERVAL * 1000)
  }, [realtimeTesting, runSingleTest])

  const stopRealtimeTest = useCallback(() => {
    if (testIntervalRef.current) {
      clearInterval(testIntervalRef.current)
      testIntervalRef.current = null
    }
    setRealtimeTesting(false)
    setTestProgress(100)
  }, [])

  const restartRealtimeTest = useCallback(() => {
    // Don't clear results - add to existing data
    startRealtimeTest()
  }, [startRealtimeTest])

  // Format chart data
  const chartData = data.map(point => ({
    ...point,
    time: new Date(point.timestamp * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
  }))

  // Data already expanded to individual ping values - just format for chart
  const realtimeChartData = realtimeResults
    .filter(r => r.latency_avg !== null)
    .map(r => ({
      time: new Date(r.timestamp || Date.now()).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }),
      value: r.latency_avg,
      packet_loss: r.packet_loss
    }))

  // Calculate realtime stats - all values are now individual ping measurements stored in latency_avg
  const validValues = realtimeResults.filter(r => r.latency_avg !== null).map(r => r.latency_avg!)
  const realtimeStats = validValues.length > 0 ? {
    current: validValues[validValues.length - 1],
    min: Math.min(...validValues),
    max: Math.max(...validValues),
    avg: validValues.reduce((acc, v) => acc + v, 0) / validValues.length,
    packetLoss: realtimeResults[realtimeResults.length - 1]?.packet_loss ?? 0,
  } : null

  const displayStats = isRealtime ? {
    current: realtimeStats?.current ?? 0,
    min: realtimeStats?.min ?? 0,
    max: realtimeStats?.max ?? 0,
    avg: Math.round((realtimeStats?.avg ?? 0) * 10) / 10,
  } : stats

  const statusInfo = getStatusInfo(displayStats.current)

  // Calculate test duration for report based on first and last result timestamps
  const testDuration = realtimeResults.length >= 2 
    ? Math.round(((realtimeResults[realtimeResults.length - 1].timestamp || Date.now()) - (realtimeResults[0].timestamp || Date.now())) / 1000)
    : realtimeResults.length === 1 
    ? 5 // Single sample = 5 seconds (one test)
    : 0

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto bg-background border-border">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2 text-foreground">
            <Wifi className="h-5 w-5 text-blue-500" />
            Network Latency
          </DialogTitle>
        </DialogHeader>
        <div className="flex items-center gap-2 mt-1 flex-nowrap">
          <Select value={target} onValueChange={setTarget}>
            <SelectTrigger className="w-[140px] sm:w-[180px] h-8 text-xs shrink-0">
              <span className="truncate">
                {TARGET_OPTIONS.find(t => t.value === target)?.shortLabel || target}
              </span>
            </SelectTrigger>
            <SelectContent>
              {TARGET_OPTIONS.map(opt => (
                <SelectItem key={opt.value} value={opt.value} className="text-xs">
                  {opt.label}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          {!isRealtime && (
            <Select value={timeframe} onValueChange={setTimeframe}>
              <SelectTrigger className="w-[100px] h-8 text-xs shrink-0">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {TIMEFRAME_OPTIONS.map(opt => (
                  <SelectItem key={opt.value} value={opt.value} className="text-xs">
                    {opt.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
          {isRealtime && (
            realtimeTesting ? (
              <Button
                variant="outline"
                size="sm"
                onClick={stopRealtimeTest}
                className="gap-1.5 text-red-500 border-red-500/30 hover:bg-red-500/10 shrink-0 h-8 px-3"
              >
                <Square className="h-3 w-3 fill-current" />
                Stop
              </Button>
            ) : (
              <Button
                variant="outline"
                size="sm"
                onClick={restartRealtimeTest}
                className="gap-1.5 shrink-0 h-8 px-3"
              >
                <RefreshCw className="h-3 w-3" />
                Test Again
              </Button>
            )
          )}
          <Button
            variant="outline"
            size="sm"
            onClick={() => generateLatencyReport({
              target,
              targetLabel: TARGET_OPTIONS.find(t => t.value === target)?.label || target,
              isRealtime,
              stats,
              realtimeResults,
              data,
              timeframe,
              testDuration: isRealtime ? testDuration : undefined,
            })}
            disabled={isRealtime ? realtimeResults.length === 0 : data.length === 0}
            className="gap-1.5 shrink-0 h-8 px-3"
          >
            <FileText className="h-3.5 w-3.5" />
            Report
          </Button>
        </div>

        {/* Progress bar for realtime test */}
        {isRealtime && realtimeTesting && (
          <div className="mb-4">
            <div className="flex items-center justify-between text-xs text-muted-foreground mb-1">
              <span>Testing... {Math.round(testProgress)}%</span>
              <span>{Math.round((REALTIME_TEST_DURATION * (1 - testProgress / 100)))}s remaining</span>
            </div>
            <div className="h-1.5 bg-muted rounded-full overflow-hidden">
              <div 
                className="h-full bg-blue-500 transition-all duration-500 ease-out"
                style={{ width: `${testProgress}%` }}
              />
            </div>
          </div>
        )}

        {/* Stats Cards - Compact single row */}
        <div className="flex items-center justify-between gap-1 mb-2 py-2 px-1 bg-muted/20 rounded-lg">
          <div className="flex items-center gap-1 min-w-0">
            <span className="text-[10px] text-muted-foreground">Current</span>
            <span className="text-base font-bold" style={{ color: getStatusColor(displayStats.current || 0) }}>
              {displayStats.current || '-'}
            </span>
            <span className="text-[10px] text-muted-foreground">ms</span>
          </div>
          <div className="flex items-center gap-1 min-w-0">
            <TrendingDown className="h-3 w-3 text-green-500 shrink-0" />
            <span className="text-[10px] text-muted-foreground">Min</span>
            <span className="text-base font-bold text-green-500">{displayStats.min || '-'}</span>
            <span className="text-[10px] text-muted-foreground">ms</span>
          </div>
          <div className="flex items-center gap-1 min-w-0">
            <Minus className="h-3 w-3 shrink-0" />
            <span className="text-[10px] text-muted-foreground">Avg</span>
            <span className="text-base font-bold">{displayStats.avg || '-'}</span>
            <span className="text-[10px] text-muted-foreground">ms</span>
          </div>
          <div className="flex items-center gap-1 min-w-0">
            <TrendingUp className="h-3 w-3 text-red-500 shrink-0" />
            <span className="text-[10px] text-muted-foreground">Max</span>
            <span className="text-base font-bold text-red-500">{displayStats.max || '-'}</span>
            <span className="text-[10px] text-muted-foreground">ms</span>
          </div>
        </div>

        {/* Status Badge */}
        <div className="flex items-center justify-between mb-4">
          <Badge variant="outline" className={statusInfo.color}>
            {statusInfo.status}
          </Badge>
          {isRealtime && (
            <span className="text-xs text-muted-foreground">
              {realtimeResults.length} sample{realtimeResults.length !== 1 ? 's' : ''} collected
              {realtimeStats?.packetLoss ? ` | ${realtimeStats.packetLoss}% packet loss` : ''}
            </span>
          )}
        </div>

        {/* Chart */}
        <div className="h-[250px] sm:h-[300px] w-full">
          {isRealtime ? (
            realtimeChartData.length > 0 ? (
              <ResponsiveContainer width="100%" height="100%">
                <AreaChart data={realtimeChartData}>
                  <defs>
                    <linearGradient id="latencyRealtimeGradient" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="0%" stopColor="#3b82f6" stopOpacity={0.4} />
                      <stop offset="100%" stopColor="#3b82f6" stopOpacity={0.05} />
                    </linearGradient>
                  </defs>
                  <CartesianGrid strokeDasharray="3 3" stroke="#374151" opacity={0.3} />
                  <XAxis 
                    dataKey="time" 
                    stroke="#6b7280" 
                    fontSize={10}
                    tickLine={false}
                    interval="preserveStartEnd"
                  />
                  <YAxis 
                    stroke="#6b7280" 
                    fontSize={10}
                    tickLine={false}
                    domain={['dataMin - 1', 'dataMax + 2']}
                    tickFormatter={(v) => `${Number(v).toFixed(1)}ms`}
                  />
                  <Tooltip content={<CustomTooltip />} />
                  <Area
                    type="monotone"
                    dataKey="value"
                    stroke="#3b82f6"
                    strokeWidth={2}
                    fill="url(#latencyRealtimeGradient)"
                    dot={{ fill: '#3b82f6', strokeWidth: 0, r: 3 }}
                    activeDot={{ r: 5, fill: '#3b82f6' }}
                    baseValue="dataMin"
                  />
                </AreaChart>
              </ResponsiveContainer>
            ) : (
              <div className="h-full flex flex-col items-center justify-center text-muted-foreground">
                <Activity className="h-12 w-12 mb-3 opacity-30" />
                <p className="text-sm">
                  {realtimeTesting ? 'Collecting data...' : 'No data yet. Click "Test Again" to start.'}
                </p>
              </div>
            )
          ) : loading ? (
            <div className="h-full flex items-center justify-center">
              <RefreshCw className="h-8 w-8 animate-spin text-muted-foreground" />
            </div>
          ) : chartData.length > 0 ? (
            <ResponsiveContainer width="100%" height="100%">
              <AreaChart data={chartData}>
                <defs>
                  <linearGradient id="latencyGradient" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#3b82f6" stopOpacity={0.4} />
                    <stop offset="100%" stopColor="#3b82f6" stopOpacity={0.05} />
                  </linearGradient>
                </defs>
                <CartesianGrid strokeDasharray="3 3" stroke="#374151" opacity={0.3} />
                <XAxis 
                  dataKey="time" 
                  stroke="#6b7280" 
                  fontSize={10}
                  tickLine={false}
                  interval="preserveStartEnd"
                />
                <YAxis 
                  stroke="#6b7280" 
                  fontSize={10}
                  tickLine={false}
                  domain={['dataMin - 1', 'dataMax + 2']}
                  tickFormatter={(v) => `${Number(v).toFixed(1)}ms`}
                />
                <Tooltip content={<CustomTooltip />} />
                {/* For longer timeframes (6h+), show max values to preserve spikes.
                    For 1 hour view, show avg values since there's no downsampling */}
                <Area
                  type="monotone"
                  dataKey={timeframe === "hour" ? "value" : "max"}
                  stroke="#3b82f6"
                  strokeWidth={2}
                  fill="url(#latencyGradient)"
                  baseValue="dataMin"
                />
              </AreaChart>
            </ResponsiveContainer>
          ) : (
            <div className="h-full flex flex-col items-center justify-center text-muted-foreground">
              <Activity className="h-12 w-12 mb-3 opacity-30" />
              <p className="text-sm">No latency data available for this period</p>
              <p className="text-xs mt-1">Data is collected every 60 seconds</p>
            </div>
          )}
        </div>

        {/* Info for realtime mode */}
        {isRealtime && (
          <div className="mt-4 p-3 bg-blue-500/10 border border-blue-500/20 rounded-lg">
            <p className="text-xs text-blue-400">
              <strong>Real-time Mode:</strong> Tests run for 2 minutes with readings every 5 seconds. 
              Click "Test Again" to add more samples. All data is included in the report.
            </p>
          </div>
        )}
      </DialogContent>
    </Dialog>
  )
}
