import { useState, useCallback } from 'react'
import { usePoller } from '../hooks/usePoller.ts'
import { useCachedState } from '../hooks/useCachedState.ts'
import { useI18n } from '../hooks/useI18n.ts'
import { batchApi } from '../api/batchApi.ts'
import { monitorApi } from '../api/monitorApi.ts'
import type {
  BatchStatistics,
  CacheStats,
  DailyStats,
  MetricsSummary,
  ProcessingDelay,
  QueryMetricsTimeSeries,
  RunningJob,
} from '../api/types.ts'
import MetricCard from '../components/charts/MetricCard.tsx'
import StatusBadge from '../components/common/StatusBadge.tsx'
import BarChart from '../components/charts/BarChart.tsx'
import LineChart from '../components/charts/LineChart.tsx'
import TimeRangeSelector from '../components/common/TimeRangeSelector.tsx'
import { formatDuration, formatNumber, formatDateTime, formatPercent } from '../utils/formatters.ts'

const POLL_INTERVAL = 30_000

export default function Dashboard() {
  const { t } = useI18n()
  const [stats, setStats] = useCachedState<BatchStatistics | null>('dash.stats', null)
  const [metrics, setMetrics] = useCachedState<MetricsSummary | null>('dash.metrics', null)
  const [cache, setCache] = useCachedState<CacheStats | null>('dash.cache', null)
  const [delay, setDelay] = useCachedState<ProcessingDelay | null>('dash.delay', null)
  const [daily, setDaily] = useCachedState<DailyStats | null>('dash.daily', null)
  const [running, setRunning] = useCachedState<RunningJob[]>('dash.running', [])
  const [queryTs, setQueryTs] = useCachedState<QueryMetricsTimeSeries | null>('dash.queryTs', null)
  const [days, setDays] = useState(7)
  const [isQueryChartsOpen, setIsQueryChartsOpen] = useState(() =>
    localStorage.getItem('dashboard-query-charts') !== 'collapsed',
  )

  const toggleQueryCharts = useCallback(() => {
    setIsQueryChartsOpen(prev => {
      const next = !prev
      localStorage.setItem('dashboard-query-charts', next ? 'expanded' : 'collapsed')
      return next
    })
  }, [])

  usePoller(() => {
    batchApi.getStatistics(days).then(setStats).catch(() => {})
    monitorApi.getMetricsSummary().then(setMetrics).catch(() => {})
    monitorApi.getCacheStats().then(setCache).catch(() => {})
    monitorApi.getDelay().then(setDelay).catch(() => {})
    batchApi.getDailyStats().then(setDaily).catch(() => {})
    batchApi.getRunningJobs().then(setRunning).catch(() => {})
    monitorApi.getQueryMetricsTimeSeries(days).then(setQueryTs).catch(() => {})
  }, POLL_INTERVAL, [days])

  const memUsage = metrics
    ? Math.round((metrics.memory.used / metrics.memory.max) * 100)
    : 0

  return (
    <div className="space-y-6 fade-in">
      {/* Header */}
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold">{t('dashboard.title')}</h1>
        <TimeRangeSelector value={days} onChange={setDays} />
      </div>

      {/* Status Cards */}
      <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
        <MetricCard
          title={t('dashboard.totalExec')}
          value={stats ? formatNumber(stats.summary.totalExecutions) : '-'}
          subtitle={stats ? `${days}${t('dashboard.periodBasis')}` : undefined}
        />
        <MetricCard
          title={t('dashboard.successRate')}
          value={stats ? formatPercent(stats.summary.successRate) : '-'}
          trend={stats && stats.summary.successRate >= 95 ? 'up' : stats && stats.summary.successRate < 80 ? 'down' : 'neutral'}
        />
        <MetricCard
          title={t('dashboard.avgDuration')}
          value={stats ? formatDuration(stats.summary.avgProcessingTimeSeconds) : '-'}
        />
        <MetricCard
          title={t('dashboard.totalProcessed')}
          value={stats ? formatNumber(stats.summary.totalRecordsProcessed) : '-'}
          subtitle={stats ? `${formatNumber(stats.summary.avgRecordsPerExecution)}${t('dashboard.avgPerJob')}` : undefined}
        />
      </div>

      {/* Running Jobs + Processing Delay */}
      <div className="grid gap-4 lg:grid-cols-2">
        <div className="sb-card">
          <div className="sb-card-header">{t('dashboard.runningJobs')}</div>
          {running.length === 0 ? (
            <div className="py-4 text-center text-sm text-muted">{t('dashboard.noRunningJobs')}</div>
          ) : (
            <div className="space-y-2">
              {running.map(job => (
                <div key={job.executionId} className="flex items-center justify-between rounded-lg bg-surface-hover p-3">
                  <div>
                    <div className="font-medium text-sm">{job.jobName}</div>
                    <div className="text-xs text-muted">#{job.executionId} &middot; {formatDateTime(job.startTime)}</div>
                  </div>
                  <StatusBadge status={job.status} />
                </div>
              ))}
            </div>
          )}
        </div>

        <div className="sb-card">
          <div className="sb-card-header">{t('dashboard.delay')}</div>
          {delay ? (
            <div className="space-y-3">
              <div className="flex items-baseline gap-2">
                <span className="text-3xl font-bold">{delay.delayMinutes ?? 0}</span>
                <span className="text-muted">{t('dashboard.delayMin')}</span>
                <StatusBadge status={delay.status ?? 'NORMAL'} />
              </div>
              <div className="grid grid-cols-2 gap-3 text-sm">
                <div>
                  <span className="text-muted">{t('dashboard.aisLatest')}</span>
                  <div className="font-mono text-xs">{formatDateTime(delay.aisLatestTime)}</div>
                </div>
                <div>
                  <span className="text-muted">{t('dashboard.processLatest')}</span>
                  <div className="font-mono text-xs">{formatDateTime(delay.queryLatestTime)}</div>
                </div>
                <div>
                  <span className="text-muted">{t('dashboard.aisReceived')}</span>
                  <div>{formatNumber(delay.recentAisCount)}{t('common.items')}</div>
                </div>
                <div>
                  <span className="text-muted">{t('dashboard.vesselsProcessed')}</span>
                  <div>{formatNumber(delay.processedVessels)}{t('common.items')}</div>
                </div>
              </div>
            </div>
          ) : (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          )}
        </div>
      </div>

      {/* System Metrics + Cache */}
      <div className="grid gap-4 lg:grid-cols-2">
        <div className="sb-card">
          <div className="sb-card-header">{t('dashboard.systemMetrics')}</div>
          {metrics ? (
            <div className="space-y-3">
              <div>
                <div className="mb-1 flex justify-between text-sm">
                  <span>{t('dashboard.memory')} ({metrics.memory.used}MB / {metrics.memory.max}MB)</span>
                  <span className={memUsage > 85 ? 'text-danger' : memUsage > 70 ? 'text-warning' : 'text-success'}>
                    {memUsage}%
                  </span>
                </div>
                <div className="h-2 rounded-full bg-surface-hover">
                  <div
                    className={`h-2 rounded-full ${memUsage > 85 ? 'bg-danger' : memUsage > 70 ? 'bg-warning' : 'bg-success'}`}
                    style={{ width: `${memUsage}%` }}
                  />
                </div>
              </div>
              <div className="grid grid-cols-3 gap-3 text-center text-sm">
                <div>
                  <div className="text-lg font-bold">{metrics.threads}</div>
                  <div className="text-xs text-muted">{t('dashboard.threads')}</div>
                </div>
                <div>
                  <div className="text-lg font-bold">{metrics.database.activeConnections}</div>
                  <div className="text-xs text-muted">{t('dashboard.dbConn')}</div>
                </div>
                <div>
                  <div className="text-lg font-bold">{(metrics.processing?.recordsPerSecond ?? 0).toFixed(0)}</div>
                  <div className="text-xs text-muted">{t('dashboard.recordsSec')}</div>
                </div>
              </div>
            </div>
          ) : (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          )}
        </div>

        <div className="sb-card">
          <div className="sb-card-header">{t('dashboard.cacheStatus')}</div>
          {cache ? (
            <div className="space-y-3">
              <div className="flex items-baseline gap-2">
                <span className="text-3xl font-bold">{cache.hitRate}</span>
                <span className="text-muted">{t('dashboard.hitRate')}</span>
                <StatusBadge status={cache.status} />
              </div>
              <div className="grid grid-cols-3 gap-3 text-center text-sm">
                <div>
                  <div className="text-lg font-bold">{formatNumber(cache.currentSize)}</div>
                  <div className="text-xs text-muted">{t('dashboard.size')}</div>
                </div>
                <div>
                  <div className="text-lg font-bold">{formatNumber(cache.hitCount)}</div>
                  <div className="text-xs text-muted">{t('dashboard.hits')}</div>
                </div>
                <div>
                  <div className="text-lg font-bold">{formatNumber(cache.missCount)}</div>
                  <div className="text-xs text-muted">{t('dashboard.misses')}</div>
                </div>
              </div>
            </div>
          ) : (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          )}
        </div>
      </div>

      {/* Daily Throughput Chart */}
      {daily && daily.dailyStats.length > 0 && (
        <div className="sb-card">
          <div className="sb-card-header">{t('dashboard.dailyVolume')}</div>
          <BarChart
            data={daily.dailyStats.map(d => ({
              date: d.date.slice(5),
              processed: d.totalWrite,
            }))}
            dataKey="processed"
            xKey="date"
            height={280}
          />
        </div>
      )}

      {/* Query Performance Charts */}
      <div className="sb-card">
        <button
          type="button"
          className="sb-card-header flex w-full items-center justify-between cursor-pointer"
          onClick={toggleQueryCharts}
        >
          <span>{t('dashboard.queryPerformance')}</span>
          <svg
            className={`h-5 w-5 text-muted transition-transform ${isQueryChartsOpen ? 'rotate-180' : ''}`}
            fill="none" viewBox="0 0 24 24" stroke="currentColor"
          >
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
          </svg>
        </button>

        {isQueryChartsOpen && (
          <div className="space-y-6 pt-2">
            {queryTs && queryTs.buckets.length > 0 ? (
              <>
                {/* Row 1: Response Time + Query Volume */}
                <div className="grid gap-4 lg:grid-cols-2">
                  <div>
                    <LineChart
                      label={t('dashboard.responseTimeTrend')}
                      data={queryTs.buckets.map(b => ({
                        time: formatBucket(b.bucket, queryTs.granularity),
                        avg: Math.round(b.avg_elapsed_ms),
                        max: Math.round(b.max_elapsed_ms),
                      }))}
                      series={[
                        { dataKey: 'avg', color: 'var(--sb-primary)', name: t('dashboard.avgElapsed') },
                        { dataKey: 'max', color: 'var(--sb-danger)', name: t('dashboard.maxElapsed') },
                      ]}
                      xKey="time"
                      height={220}
                      yFormatter={v => `${v}ms`}
                    />
                  </div>
                  <div>
                    <BarChart
                      label={t('dashboard.queryVolume')}
                      data={queryTs.buckets.map(b => ({
                        time: formatBucket(b.bucket, queryTs.granularity),
                        WS: b.ws_count,
                        REST: b.rest_count,
                      }))}
                      xKey="time"
                      height={220}
                      series={[
                        { dataKey: 'WS', color: 'var(--sb-primary)', name: 'WebSocket', stackId: 'q' },
                        { dataKey: 'REST', color: 'var(--sb-success)', name: 'REST', stackId: 'q' },
                      ]}
                    />
                  </div>
                </div>

                {/* Row 2: Cache Path + Response Size */}
                <div className="grid gap-4 lg:grid-cols-2">
                  <div>
                    <BarChart
                      label={t('dashboard.cachePathRatio')}
                      data={queryTs.buckets.map(b => ({
                        time: formatBucket(b.bucket, queryTs.granularity),
                        Cache: b.cache_count,
                        DB: b.db_count,
                        Hybrid: b.hybrid_count,
                      }))}
                      xKey="time"
                      height={220}
                      series={[
                        { dataKey: 'Cache', color: 'var(--sb-success)', stackId: 'p' },
                        { dataKey: 'DB', color: 'var(--sb-warning)', stackId: 'p' },
                        { dataKey: 'Hybrid', color: 'var(--sb-primary)', stackId: 'p' },
                      ]}
                    />
                  </div>
                  <div>
                    <LineChart
                      label={t('dashboard.responseSizeTrend')}
                      data={queryTs.buckets.map(b => ({
                        time: formatBucket(b.bucket, queryTs.granularity),
                        size: Math.round(b.avg_response_bytes / 1024),
                      }))}
                      series={[
                        { dataKey: 'size', color: 'var(--sb-primary)', name: 'KB' },
                      ]}
                      xKey="time"
                      height={220}
                      yFormatter={v => `${v}KB`}
                    />
                  </div>
                </div>

                {/* Top Clients */}
                {queryTs.topClients.length > 0 && (
                  <div>
                    <div className="mb-2 text-sm font-medium text-muted">{t('dashboard.topClients')}</div>
                    <div className="space-y-2">
                      {queryTs.topClients.map((c, i) => {
                        const maxCount = queryTs.topClients[0].query_count
                        const pct = maxCount > 0 ? (c.query_count / maxCount) * 100 : 0
                        return (
                          <div key={c.client_ip ?? i} className="flex items-center gap-3 text-sm">
                            <span className="w-32 truncate font-mono text-xs">{c.client_ip ?? '-'}</span>
                            <div className="flex-1">
                              <div className="h-4 rounded bg-surface-hover">
                                <div
                                  className="h-4 rounded bg-primary"
                                  style={{ width: `${pct}%` }}
                                />
                              </div>
                            </div>
                            <span className="w-20 text-right text-xs text-muted">
                              {c.query_count}{t('dashboard.queries')} · {Math.round(c.avg_elapsed_ms)}ms
                            </span>
                          </div>
                        )
                      })}
                    </div>
                  </div>
                )}
              </>
            ) : (
              <div className="py-8 text-center text-sm text-muted">{t('dashboard.noChartData')}</div>
            )}
          </div>
        )}
      </div>
    </div>
  )
}

function formatBucket(bucket: string, granularity: 'HOURLY' | 'DAILY'): string {
  if (granularity === 'HOURLY') {
    // "2026-03-10T14:00:00" → "14:00"
    const timePart = bucket.includes('T') ? bucket.split('T')[1] : bucket
    return timePart.slice(0, 5)
  }
  // "2026-03-10" → "03-10"
  return bucket.slice(5, 10)
}
