import { useEffect, useMemo, useRef, useState } from 'react'
import {
  CartesianGrid,
  Legend,
  Line,
  LineChart,
  Bar,
  BarChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts'
import { Activity, Cpu, HardDrive, MemoryStick, RefreshCw } from 'lucide-react'
import type { MonitorStats } from '@/api'
import { useMonitorStats } from '@/api/hooks'
import { Button, Card, PageHeader, SectionLabel, Tabs } from '@/components/ui'
import { useTheme } from '@/context/ThemeContext'
import { formatDuration } from '@/lib/format'

const HISTORY_SIZE = 60

type HistoryPoint = {
  time: string
  goroutines: number
  alloc: number
  sys: number
  gcPause: number
  scheduled: number
  running: number
  queue: number
}

function formatBytes(bytes = 0) {
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`
  return `${(bytes / 1024 / 1024 / 1024).toFixed(2)} GB`
}

function formatUptime(seconds = 0) {
  const d = Math.floor(seconds / 86400)
  const h = Math.floor((seconds % 86400) / 3600)
  const m = Math.floor((seconds % 3600) / 60)
  if (d > 0) return `${d}天 ${h}小时`
  if (h > 0) return `${h}小时 ${m}分钟`
  return `${m}分钟`
}

function Progress({ value }: { value: number }) {
  const v = Math.max(0, Math.min(100, value || 0))
  const color = v > 85 ? 'bg-red-500' : v > 65 ? 'bg-amber-500' : 'bg-[var(--bg-accent)]'
  return (
    <div className="mt-2 h-1.5 overflow-hidden rounded-full bg-[var(--bg-tertiary)]">
      <div className={`h-full rounded-full ${color}`} style={{ width: `${v}%` }} />
    </div>
  )
}

function pushHistory(prev: HistoryPoint[], next: HistoryPoint) {
  const list = [...prev, next]
  if (list.length > HISTORY_SIZE) list.splice(0, list.length - HISTORY_SIZE)
  return list
}

export default function Monitor() {
  const { theme } = useTheme()
  const isDark = theme !== 'light'
  const [tab, setTab] = useState(() => localStorage.getItem('monitor_active_tab') || 'overview')
  const [live, setLive] = useState<MonitorStats | null>(null)
  const [history, setHistory] = useState<HistoryPoint[]>([])
  const [sseConnected, setSseConnected] = useState(false)
  const lastPauseNs = useRef(0)
  const { data, isLoading, refetch, isFetching } = useMonitorStats()

  const stats = live || data || null
  const axisColor = isDark ? '#94a3b8' : '#64748b'
  const gridColor = isDark ? '#334155' : '#e2e8f0'

  useEffect(() => {
    localStorage.setItem('monitor_active_tab', tab)
  }, [tab])

  useEffect(() => {
    if (!data) return
    setLive((prev) => prev || data)
    // 无 SSE 时用轮询快照补充首点，避免图表长期空白
    setHistory((prev) => {
      if (prev.length > 0) return prev
      return pushHistory(prev, {
        time: new Date().toLocaleTimeString('en-US', { hour12: false }),
        goroutines: data.env?.goroutines || 0,
        alloc: Number(((data.mem?.alloc || 0) / 1024 / 1024).toFixed(2)),
        sys: Number(((data.mem?.sys || 0) / 1024 / 1024).toFixed(2)),
        gcPause: 0,
        scheduled: data.scheduler?.scheduled || 0,
        running: data.scheduler?.running || 0,
        queue: data.scheduler?.queue_size || 0,
        cpu: Number((data.host?.cpu_percent || 0).toFixed(1)),
        mem: Number((data.host?.mem_percent || 0).toFixed(1)),
        disk: Number((data.host?.disk_percent || 0).toFixed(1)),
      })
    })
  }, [data])

  useEffect(() => {
    const baseUrl = (window as any).__BASE_URL__ || ''
    const apiVersion = (window as any).__API_VERSION__ || '/api/v1'
    const url = `${baseUrl}${apiVersion}/monitor/sse`
    const es = new EventSource(url, { withCredentials: true } as EventSourceInit)

    es.onopen = () => setSseConnected(true)
    es.onerror = () => setSseConnected(false)
    es.onmessage = (event) => {
      try {
        const payload = JSON.parse(event.data)
        const res: MonitorStats | undefined = payload?.data || payload
        if (!res?.host || !res?.env) return
        setLive(res)
        setSseConnected(true)

        let pauseDelta = 0
        const pauseTotal = res.gc?.pause_total_ns || 0
        if (lastPauseNs.current > 0 && pauseTotal >= lastPauseNs.current) {
          pauseDelta = Number(((pauseTotal - lastPauseNs.current) / 1_000_000).toFixed(2))
        }
        lastPauseNs.current = pauseTotal

        const point: HistoryPoint = {
          time: new Date().toLocaleTimeString('en-US', { hour12: false }),
          goroutines: res.env.goroutines || 0,
          alloc: Number(((res.mem?.alloc || 0) / 1024 / 1024).toFixed(2)),
          sys: Number(((res.mem?.sys || 0) / 1024 / 1024).toFixed(2)),
          gcPause: pauseDelta,
          scheduled: res.scheduler?.scheduled || 0,
          running: res.scheduler?.running || 0,
          queue: res.scheduler?.queue_size || 0,
          cpu: Number((res.host?.cpu_percent || 0).toFixed(1)),
          mem: Number((res.host?.mem_percent || 0).toFixed(1)),
          disk: Number((res.host?.disk_percent || 0).toFixed(1)),
        }
        setHistory((prev) => pushHistory(prev, point))
      } catch {
        // ignore malformed frames
      }
    }

    return () => {
      es.close()
    }
  }, [])

  const chartData = useMemo(() => history, [history])

  return (
    <div>
      <PageHeader
        title="系统监控"
        description="主机资源、运行时与调度器状态"
        actions={
          <div className="flex items-center gap-2">
            <span className={`text-xs ${sseConnected ? 'text-emerald-500' : 'text-[var(--text-muted)]'}`}>
              {sseConnected ? 'SSE 已连接' : 'SSE 重连中'}
            </span>
            <Button variant="secondary" onClick={() => refetch()} disabled={isFetching}>
              <RefreshCw size={14} className={isFetching ? 'animate-spin' : ''} />
              刷新
            </Button>
          </div>
        }
      />

      <div className="mb-4">
        <Tabs
          value={tab}
          onValueChange={setTab}
          items={[
            { value: 'overview', label: '概览' },
            { value: 'charts', label: '时序图' },
            { value: 'runtime', label: '运行时' },
          ]}
        />
      </div>

      {isLoading && !stats ? (
        <div className="text-[var(--text-muted)]">加载中...</div>
      ) : !stats ? (
        <div className="text-[var(--text-muted)]">暂无监控数据</div>
      ) : (
        <div className="space-y-6">
          {(tab === 'overview' || tab === 'runtime') && (
            <section>
              <SectionLabel>主机资源</SectionLabel>
              <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
                <Card className="p-4">
                  <div className="mb-2 flex items-center gap-2 text-sm text-[var(--text-muted)]">
                    <Cpu size={14} /> CPU
                  </div>
                  <div className="text-2xl font-semibold">{stats.host.cpu_percent?.toFixed(1) || 0}%</div>
                  <Progress value={stats.host.cpu_percent || 0} />
                </Card>
                <Card className="p-4">
                  <div className="mb-2 flex items-center gap-2 text-sm text-[var(--text-muted)]">
                    <MemoryStick size={14} /> 内存
                  </div>
                  <div className="text-2xl font-semibold">{stats.host.mem_percent?.toFixed(1) || 0}%</div>
                  <div className="mt-1 text-xs text-[var(--text-muted)]">
                    {formatBytes(stats.host.mem_used)} / {formatBytes(stats.host.mem_total)}
                  </div>
                  <Progress value={stats.host.mem_percent || 0} />
                </Card>
                <Card className="p-4">
                  <div className="mb-2 flex items-center gap-2 text-sm text-[var(--text-muted)]">
                    <HardDrive size={14} /> 磁盘
                  </div>
                  <div className="text-2xl font-semibold">{stats.host.disk_percent?.toFixed(1) || 0}%</div>
                  <div className="mt-1 text-xs text-[var(--text-muted)]">
                    {formatBytes(stats.host.disk_used)} / {formatBytes(stats.host.disk_total)}
                  </div>
                  <Progress value={stats.host.disk_percent || 0} />
                </Card>
                <Card className="p-4">
                  <div className="mb-2 flex items-center gap-2 text-sm text-[var(--text-muted)]">
                    <Activity size={14} /> 运行时间
                  </div>
                  <div className="text-2xl font-semibold">{formatUptime(stats.host.uptime)}</div>
                  <div className="mt-1 text-xs text-[var(--text-muted)]">
                    {stats.env.os} / {stats.env.arch}
                  </div>
                </Card>
              </div>
            </section>
          )}

          {tab === 'charts' ? (
            <section className="grid gap-3 xl:grid-cols-2">
              <ChartCard title="Goroutines">
                <LineSeries data={chartData} dataKey="goroutines" color="#2563eb" name="协程数" axisColor={axisColor} gridColor={gridColor} isDark={isDark} />
              </ChartCard>
              <ChartCard title="内存 (MB)">
                <MultiLine
                  data={chartData}
                  series={[
                    { dataKey: 'alloc', color: '#059669', name: 'Alloc' },
                    { dataKey: 'sys', color: '#d97706', name: 'Sys' },
                  ]}
                  axisColor={axisColor}
                  gridColor={gridColor}
                  isDark={isDark}
                />
              </ChartCard>
              <ChartCard title="GC Pause (ms)">
                <BarSeries data={chartData} dataKey="gcPause" color="#ea580c" name="GC Pause" axisColor={axisColor} gridColor={gridColor} isDark={isDark} />
              </ChartCard>
              <ChartCard title="调度器">
                <MultiLine
                  data={chartData}
                  series={[
                    { dataKey: 'scheduled', color: '#3b82f6', name: '已调度' },
                    { dataKey: 'running', color: '#10b981', name: '运行中' },
                    { dataKey: 'queue', color: '#f59e0b', name: '队列' },
                  ]}
                  axisColor={axisColor}
                  gridColor={gridColor}
                  isDark={isDark}
                />
              </ChartCard>
            </section>
          ) : null}

          {(tab === 'overview' || tab === 'runtime') && (
            <section className="grid gap-3 xl:grid-cols-2">
              <Card className="p-4">
                <SectionLabel>运行时</SectionLabel>
                <div className="space-y-2 text-sm">
                  <Row label="Go" value={stats.env.go_version} />
                  <Row label="CPU 核心" value={String(stats.env.num_cpu)} />
                  <Row label="Goroutines" value={String(stats.env.goroutines)} />
                  <Row label="Alloc" value={formatBytes(stats.mem?.alloc || 0)} />
                  <Row label="Sys" value={formatBytes(stats.mem?.sys || 0)} />
                  <Row label="Heap Inuse" value={formatBytes(stats.heap?.heap_inuse || 0)} />
                  <Row label="GC 次数" value={String(stats.gc?.num_gc || 0)} />
                  <Row label="GC 总停顿" value={`${((stats.gc?.pause_total_ns || 0) / 1_000_000).toFixed(2)} ms`} />
                </div>
              </Card>
              <Card className="p-4">
                <SectionLabel>调度器</SectionLabel>
                <div className="mb-4 grid grid-cols-2 gap-3 md:grid-cols-4">
                  <Metric label="Worker" value={stats.scheduler.worker_count} />
                  <Metric label="队列" value={stats.scheduler.queue_size} />
                  <Metric label="运行中" value={stats.scheduler.running} />
                  <Metric label="已调度" value={stats.scheduler.scheduled} />
                </div>
                <div className="border-t border-[var(--border)] pt-3">
                  <div className="mb-2 text-xs font-medium uppercase tracking-wide text-[var(--text-muted)]">Worker 列表</div>
                  {(Array.isArray(stats.scheduler.workers) ? stats.scheduler.workers : []).length === 0 ? (
                    <div className="text-sm text-[var(--text-muted)]">暂无 Worker 数据</div>
                  ) : (
                    <div className="max-h-64 space-y-2 overflow-auto">
                      {(Array.isArray(stats.scheduler.workers) ? stats.scheduler.workers : []).map((w) => (
                        <div key={w.id} className="flex items-center justify-between rounded-md bg-[var(--bg-tertiary)]/50 px-3 py-2 text-sm">
                          <div>
                            #{w.id} · {w.status}
                            {w.duration ? <span className="ml-2 text-xs text-[var(--text-muted)]">{formatDuration(w.duration)}</span> : null}
                          </div>
                          <div className="truncate pl-3 text-[var(--text-muted)]">{w.task_name || w.task_id || '-'}</div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              </Card>
            </section>
          )}
        </div>
      )}
    </div>
  )
}

function ChartCard({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <Card className="p-4">
      <SectionLabel>{title}</SectionLabel>
      <div className="h-[240px] w-full">
        {children}
      </div>
    </Card>
  )
}

function LineSeries({
  data,
  dataKey,
  color,
  name,
  axisColor,
  gridColor,
  isDark,
}: {
  data: HistoryPoint[]
  dataKey: keyof HistoryPoint
  color: string
  name: string
  axisColor: string
  gridColor: string
  isDark: boolean
}) {
  if (!data.length) return <EmptyChart />
  return (
    <ResponsiveContainer width="100%" height="100%">
      <LineChart data={data}>
        <CartesianGrid stroke={gridColor} strokeDasharray="3 3" vertical={false} />
        <XAxis dataKey="time" tick={{ fill: axisColor, fontSize: 10 }} minTickGap={24} axisLine={false} tickLine={false} />
        <YAxis tick={{ fill: axisColor, fontSize: 10 }} width={36} axisLine={false} tickLine={false} />
        <Tooltip contentStyle={tooltipStyle(isDark, gridColor)} />
        <Line type="monotone" dataKey={dataKey as string} name={name} stroke={color} strokeWidth={2} dot={false} isAnimationActive={false} />
      </LineChart>
    </ResponsiveContainer>
  )
}

function MultiLine({
  data,
  series,
  axisColor,
  gridColor,
  isDark,
}: {
  data: HistoryPoint[]
  series: { dataKey: keyof HistoryPoint; color: string; name: string }[]
  axisColor: string
  gridColor: string
  isDark: boolean
}) {
  if (!data.length) return <EmptyChart />
  return (
    <ResponsiveContainer width="100%" height="100%">
      <LineChart data={data}>
        <CartesianGrid stroke={gridColor} strokeDasharray="3 3" vertical={false} />
        <XAxis dataKey="time" tick={{ fill: axisColor, fontSize: 10 }} minTickGap={24} axisLine={false} tickLine={false} />
        <YAxis tick={{ fill: axisColor, fontSize: 10 }} width={36} axisLine={false} tickLine={false} />
        <Tooltip contentStyle={tooltipStyle(isDark, gridColor)} />
        <Legend wrapperStyle={{ fontSize: 11 }} />
        {series.map((s) => (
          <Line
            key={String(s.dataKey)}
            type="monotone"
            dataKey={s.dataKey as string}
            name={s.name}
            stroke={s.color}
            strokeWidth={2}
            dot={false}
            isAnimationActive={false}
          />
        ))}
      </LineChart>
    </ResponsiveContainer>
  )
}

function BarSeries({
  data,
  dataKey,
  color,
  name,
  axisColor,
  gridColor,
  isDark,
}: {
  data: HistoryPoint[]
  dataKey: keyof HistoryPoint
  color: string
  name: string
  axisColor: string
  gridColor: string
  isDark: boolean
}) {
  if (!data.length) return <EmptyChart />
  return (
    <ResponsiveContainer width="100%" height="100%">
      <BarChart data={data}>
        <CartesianGrid stroke={gridColor} strokeDasharray="3 3" vertical={false} />
        <XAxis dataKey="time" tick={{ fill: axisColor, fontSize: 10 }} minTickGap={24} axisLine={false} tickLine={false} />
        <YAxis tick={{ fill: axisColor, fontSize: 10 }} width={36} axisLine={false} tickLine={false} />
        <Tooltip contentStyle={tooltipStyle(isDark, gridColor)} />
        <Bar dataKey={dataKey as string} name={name} fill={color} isAnimationActive={false} />
      </BarChart>
    </ResponsiveContainer>
  )
}

function EmptyChart() {
  return <div className="flex h-full items-center justify-center text-sm text-[var(--text-muted)]">等待实时数据...</div>
}

function tooltipStyle(isDark: boolean, gridColor: string) {
  return {
    background: isDark ? '#0f172a' : '#fff',
    border: `1px solid ${gridColor}`,
    borderRadius: 8,
    fontSize: 12,
  }
}

function Row({ label, value }: { label: string; value?: string }) {
  return (
    <div className="flex justify-between gap-3 border-b border-[var(--border)] py-1.5 last:border-0">
      <span className="text-[var(--text-muted)]">{label}</span>
      <span className="font-mono text-xs">{value || '-'}</span>
    </div>
  )
}

function Metric({ label, value }: { label: string; value?: number }) {
  return (
    <div>
      <div className="text-xs text-[var(--text-muted)]">{label}</div>
      <div className="text-lg font-semibold">{value ?? 0}</div>
    </div>
  )
}
