<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import DashboardLayout from '../layouts/DashboardLayout.vue'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Separator } from '@/components/ui/separator'
import { ScrollArea } from '@/components/ui/scroll-area'

const windowMinutes = ref('20')
const intervalSeconds = ref('4')
const paused = ref(false)
const status = ref('connecting')
const statusText = ref('Connecting')
const lastUpdate = ref('—')
const snapshot = ref(null)
let eventSource = null

const metrics = ref({ traces: 0, sessions: 0, cost: 0, latency: 0, errorRate: 0 })
const series = ref({ labels: [], traces: [], costs: [], latencies: [] })
const modelMix = ref([])
const feedEvents = ref([])
const previousIds = new Set()

function fmt(v) { return Number(v || 0).toLocaleString('vi-VN') }
function fmtUsd(v) { return `$${Number(v || 0).toFixed(v >= 1 ? 2 : 4)}` }
function fmtSec(v) { return `${Number(v || 0).toFixed(2)}s` }
function fmtPct(v) { return `${Number(v || 0).toFixed(2)}%` }
function fmtTime(v) {
  if (!v) return '—'
  return new Date(v).toLocaleTimeString('vi-VN', { hour: '2-digit', minute: '2-digit', second: '2-digit' })
}

function applySnapshot(data) {
  if (!data) return
  snapshot.value = data
  status.value = data.status === 'degraded' ? 'degraded' : 'live'
  statusText.value = data.status === 'degraded' ? 'Degraded' : 'Live'
  lastUpdate.value = fmtTime(data.generated_at)

  const m = data.metrics || {}
  metrics.value = {
    traces: m.traces || 0, sessions: m.active_sessions || 0,
    cost: m.total_cost_usd || 0, latency: m.avg_latency_s || 0,
    errorRate: m.error_rate_pct || 0,
    peakTraces: m.peak_traces_per_min || 0, peakCost: m.peak_cost_per_min || 0,
    peakLatency: m.peak_latency_s || 0, lastEvent: m.last_event_at || '',
    statusReason: data.status_reason || ''
  }
  series.value = data.series || { labels: [], traces: [], costs: [], latencies: [] }
  modelMix.value = data.model_mix || []

  const events = data.latest_events || []
  feedEvents.value = events.map(e => ({ ...e, fresh: !previousIds.has(e.trace_id) }))
  events.forEach(e => previousIds.add(e.trace_id))
}

async function loadBootstrap() {
  status.value = 'connecting'
  statusText.value = 'Connecting'
  const r = await fetch(`/api/live-monitor/bootstrap?window_minutes=${windowMinutes.value}`)
  const d = await r.json()
  applySnapshot(d)
}

function connectStream() {
  if (eventSource) { eventSource.close(); eventSource = null }
  if (paused.value) { status.value = 'offline'; statusText.value = 'Paused'; return }
  status.value = 'connecting'; statusText.value = 'Connecting'
  eventSource = new EventSource(`/api/live-monitor/stream?window_minutes=${windowMinutes.value}&interval_seconds=${intervalSeconds.value}`)
  eventSource.onmessage = (event) => {
    try {
      const p = JSON.parse(event.data)
      if (p.type === 'snapshot' || p.type === 'dashboard_update') applySnapshot(p.payload)
      else if (p.type === 'heartbeat') {
        if (statusText.value !== 'Paused') {
          status.value = p.status === 'degraded' ? 'degraded' : 'live'
          statusText.value = status.value === 'degraded' ? 'Degraded' : 'Live'
        }
        lastUpdate.value = fmtTime(p.generated_at)
      } else if (p.type === 'error') { status.value = 'offline'; statusText.value = 'Stream Error' }
    } catch (e) {}
  }
  eventSource.onerror = () => { if (!paused.value) { status.value = 'offline'; statusText.value = 'Reconnecting' } }
}

async function refresh() {
  await loadBootstrap()
  connectStream()
}

function togglePause() {
  paused.value = !paused.value
  connectStream()
}

const statusConfig = {
  live:        { dotClass: 'bg-emerald-500 animate-pulse', badgeClass: 'border-emerald-200 bg-emerald-50 text-emerald-700 dark:bg-emerald-900/20 dark:text-emerald-400', label: 'Live' },
  degraded:    { dotClass: 'bg-amber-500',                 badgeClass: 'border-amber-200 bg-amber-50 text-amber-700 dark:bg-amber-900/20 dark:text-amber-400',     label: 'Degraded' },
  connecting:  { dotClass: 'bg-primary animate-pulse',     badgeClass: 'border-primary/20 bg-primary/5 text-primary',                                               label: 'Connecting' },
  offline:     { dotClass: 'bg-muted-foreground',          badgeClass: 'border-border bg-muted text-muted-foreground',                                              label: 'Offline' },
}
const currentStatus = () => statusConfig[status.value] || statusConfig.offline

onMounted(() => refresh())
onUnmounted(() => { if (eventSource) eventSource.close() })
</script>

<template>
  <DashboardLayout>
    <div class="p-6 md:p-8 max-w-[1400px] mx-auto min-h-screen space-y-6">

      <!-- Header -->
      <div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
        <div class="flex items-center gap-4">
          <div>
            <h1 class="text-3xl font-bold tracking-tight text-foreground">Live Monitor</h1>
            <div class="flex items-center gap-2 mt-1">
              <span class="text-sm text-muted-foreground">Cập nhật:</span>
              <span class="text-sm font-mono text-foreground">{{ lastUpdate }}</span>
            </div>
          </div>
          <div :class="['flex items-center gap-2 px-3 py-1.5 rounded-full text-xs font-semibold border', currentStatus().badgeClass]">
            <span :class="['w-2 h-2 rounded-full shrink-0', currentStatus().dotClass]"></span>
            {{ statusText }}
          </div>
        </div>

        <div class="flex flex-wrap items-center gap-2">
          <Select v-model="windowMinutes" @update:modelValue="refresh">
            <SelectTrigger class="h-9 w-32 text-xs"><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="5">5 phút</SelectItem>
              <SelectItem value="10">10 phút</SelectItem>
              <SelectItem value="20">20 phút</SelectItem>
              <SelectItem value="60">60 phút</SelectItem>
            </SelectContent>
          </Select>
          <Select v-model="intervalSeconds" @update:modelValue="connectStream">
            <SelectTrigger class="h-9 w-[100px] text-xs"><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="4">mỗi 4s</SelectItem>
              <SelectItem value="10">mỗi 10s</SelectItem>
              <SelectItem value="30">mỗi 30s</SelectItem>
            </SelectContent>
          </Select>
          <Button size="sm" variant="outline" class="h-9 gap-2" @click="togglePause">
            <svg v-if="paused" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>
            <svg v-else xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>
            {{ paused ? 'Resume' : 'Pause' }}
          </Button>
          <Button size="sm" variant="outline" class="h-9 w-9 p-0" @click="refresh">
            <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/></svg>
          </Button>
        </div>
      </div>

      <!-- KPI Metric Cards -->
      <div class="grid grid-cols-2 md:grid-cols-5 gap-4">
        <Card v-for="(item, i) in [
          { label: 'Traces',       value: fmt(metrics.traces),       sub: `Peak ${fmt(metrics.peakTraces)}/min`,    accent: 'text-primary' },
          { label: 'Sessions',     value: fmt(metrics.sessions),     sub: `Last: ${fmtTime(metrics.lastEvent)}`,    accent: 'text-primary' },
          { label: 'Cost',         value: fmtUsd(metrics.cost),      sub: `Peak ${fmtUsd(metrics.peakCost)}/min`,   accent: 'text-amber-500' },
          { label: 'Avg Latency',  value: fmtSec(metrics.latency),   sub: `Peak ${fmtSec(metrics.peakLatency)}`,    accent: Number(metrics.latency) > 3 ? 'text-destructive' : 'text-emerald-500' },
          { label: 'Error Rate',   value: fmtPct(metrics.errorRate), sub: metrics.statusReason || 'vs window',      accent: Number(metrics.errorRate) > 2 ? 'text-destructive' : 'text-foreground' },
        ]" :key="i" class="border-border hover:shadow-sm transition-shadow">
          <CardContent class="p-5">
            <p :class="['text-2xl font-black leading-none tabular-nums', item.accent]">{{ item.value }}</p>
            <p class="text-xs font-semibold text-muted-foreground uppercase tracking-wider mt-2">{{ item.label }}</p>
            <p class="text-[10px] text-muted-foreground/60 mt-1 truncate font-mono">{{ item.sub }}</p>
          </CardContent>
        </Card>
      </div>

      <div class="grid grid-cols-1 lg:grid-cols-2 gap-5">

        <!-- Model Mix -->
        <Card class="border-border">
          <CardHeader class="pb-3 pt-4 px-5 border-b border-border">
            <CardTitle class="text-sm flex items-center gap-2">
              <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 14-8-4 8-4 8 4-8 4Z"/><path d="m12 14 8-4"/><path d="m12 22-8-4 8-4 8 4-8 4Z"/></svg>
              Model Mix
            </CardTitle>
          </CardHeader>
          <CardContent class="px-5 py-4">
            <div v-if="!modelMix.length" class="flex flex-col items-center justify-center py-8 text-muted-foreground">
              <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="opacity-20 mb-2"><path d="M5 7 3 5l2-2"/><path d="m9 3 2.5 2.5L9 8"/><path d="M3 14h7.5a5.5 5.5 0 0 0 0-11H3v11Z"/><path d="M3 21h18"/><path d="M10 21v-7"/></svg>
              <p class="text-xs">Chưa có model data</p>
            </div>
            <ScrollArea class="max-h-64">
              <div class="space-y-4">
                <div v-for="m in modelMix" :key="m.model_name">
                  <div class="flex items-center justify-between text-sm mb-1.5">
                    <span class="font-medium text-foreground truncate pr-3">{{ m.model_name }}</span>
                    <span class="text-muted-foreground font-mono shrink-0">{{ m.share_pct?.toFixed(1) }}%</span>
                  </div>
                  <div class="h-2 bg-muted rounded-full overflow-hidden shadow-inner">
                    <div class="h-full bg-primary/70 rounded-full transition-all duration-700"
                         :style="{ width: Math.max(m.share_pct, 2) + '%' }"></div>
                  </div>
                  <div class="flex gap-4 text-[11px] text-muted-foreground mt-1.5">
                    <span>{{ fmt(m.traces) }} traces</span>
                    <span>{{ fmtUsd(m.total_cost_usd) }}</span>
                    <span class="font-mono">{{ fmtSec(m.avg_latency_s) }}</span>
                  </div>
                </div>
              </div>
            </ScrollArea>
          </CardContent>
        </Card>

        <!-- Latest Events Feed -->
        <Card class="border-border">
          <CardHeader class="pb-3 pt-4 px-5 border-b border-border">
            <CardTitle class="text-sm flex items-center gap-2">
              <span class="relative flex h-2 w-2">
                <span v-if="status === 'live'" class="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
                <span :class="['relative inline-flex rounded-full h-2 w-2', status === 'live' ? 'bg-emerald-500' : 'bg-muted-foreground']"></span>
              </span>
              Latest Events
            </CardTitle>
          </CardHeader>
          <CardContent class="p-0">
            <div v-if="!feedEvents.length" class="flex flex-col items-center justify-center py-10 text-muted-foreground">
              <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="opacity-20 mb-2"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
              <p class="text-xs">Chưa có trace nào</p>
            </div>
            <ScrollArea class="max-h-72" v-else>
              <div class="divide-y divide-border">
                <div v-for="e in feedEvents" :key="e.trace_id"
                     :class="['p-4 transition-colors', e.fresh ? 'bg-primary/5 border-l-2 border-l-primary' : 'hover:bg-accent/20']">
                  <div class="flex items-center justify-between mb-2">
                    <span class="font-mono font-semibold text-sm text-foreground truncate pr-2">{{ e.model_name }}</span>
                    <Badge :variant="e.severity === 'error' ? 'destructive' : 'secondary'" class="text-[9px] uppercase tracking-wider shrink-0">
                      {{ e.severity }}
                    </Badge>
                  </div>
                  <div class="grid grid-cols-2 gap-x-4 gap-y-1 text-[11px] text-muted-foreground font-mono">
                    <span>Session: <span class="text-foreground">{{ (e.session_id || '—').slice(0, 10) }}</span></span>
                    <span>Latency: <span class="text-foreground">{{ fmtSec(e.trace_latency_s) }}</span></span>
                    <span>Cost: <span class="text-foreground">{{ fmtUsd(e.total_cost_usd) }}</span></span>
                    <span>Age: <span class="text-foreground">{{ e.age_seconds != null ? e.age_seconds + 's' : '—' }}</span></span>
                  </div>
                </div>
              </div>
            </ScrollArea>
          </CardContent>
        </Card>
      </div>

    </div>
  </DashboardLayout>
</template>
