import { useState, useCallback } from 'react'
import { usePoller } from '../hooks/usePoller.ts'
import { useCachedState } from '../hooks/useCachedState.ts'
import { useI18n } from '../hooks/useI18n.ts'
import { monitorApi } from '../api/monitorApi.ts'
import type { MetricsSummary, CacheStats, ProcessingDelay, CacheDetails, QueryMetricsPage, QueryMetricsSummary, QueryMetricsParams, QueryMetricRow } from '../api/types.ts'
import MetricCard from '../components/charts/MetricCard.tsx'
import DataTable, { type Column } from '../components/common/DataTable.tsx'
import { formatNumber, formatBytes } from '../utils/formatters.ts'

const POLL_INTERVAL = 10_000
const QUERY_POLL_INTERVAL = 30_000

const ELAPSED_RANGES = [
  { label: '< 1s', min: undefined, max: 999 },
  { label: '1-5s', min: 1000, max: 5000 },
  { label: '5-30s', min: 5000, max: 30000 },
  { label: '> 30s', min: 30000, max: undefined },
] as const

export default function ApiMetrics() {
  const { t } = useI18n()
  const [metrics, setMetrics] = useCachedState<MetricsSummary | null>('api.metrics', null)
  const [cache, setCache] = useCachedState<CacheStats | null>('api.cache', null)
  const [cacheDetails, setCacheDetails] = useCachedState<CacheDetails | null>('api.cacheDetail', null)
  const [delay, setDelay] = useCachedState<ProcessingDelay | null>('api.delay', null)

  // Query History state
  const [filter, setFilter] = useState<QueryMetricsParams>({
    page: 0, size: 20, sortBy: 'created_at', sortDir: 'desc',
  })
  const [historyData, setHistoryData] = useState<QueryMetricsPage | null>(null)
  const [summaryData, setSummaryData] = useState<QueryMetricsSummary | null>(null)

  usePoller(() => {
    monitorApi.getMetricsSummary().then(setMetrics).catch(() => {})
    monitorApi.getCacheStats().then(setCache).catch(() => {})
    monitorApi.getCacheDetails().then(setCacheDetails).catch(() => {})
    monitorApi.getDelay().then(setDelay).catch(() => {})
  }, POLL_INTERVAL)

  const fetchQueryData = useCallback(() => {
    monitorApi.getQueryMetricsHistory(filter).then(setHistoryData).catch(() => {})
    monitorApi.getQueryMetricsSummary(24).then(setSummaryData).catch(() => {})
  }, [filter])

  usePoller(fetchQueryData, QUERY_POLL_INTERVAL, [filter])

  const updateFilter = (patch: Partial<QueryMetricsParams>) => {
    setFilter(prev => ({ ...prev, page: 0, ...patch }))
  }

  const resetFilters = () => {
    setFilter({ page: 0, size: 20, sortBy: 'created_at', sortDir: 'desc' })
  }

  const memUsed = metrics?.memory.used ?? 0
  const memMax = metrics?.memory.max ?? 1
  const memPct = Math.round((memUsed / memMax) * 100)

  // Summary computed values
  const totalQueries = summaryData?.total_queries ?? 0
  const cacheHitRate = totalQueries > 0
    ? ((summaryData?.cache_only_count ?? 0) / totalQueries * 100).toFixed(1)
    : '0.0'

  const historyColumns: Column<QueryMetricRow>[] = [
    {
      key: 'created_at', label: t('metrics.queryTime'), sortable: false,
      render: (row) => {
        if (!row.created_at) return '-'
        const d = new Date(row.created_at)
        // UTC → KST (+9h)
        const kst = new Date(d.getTime() + 9 * 60 * 60 * 1000)
        const mm = String(kst.getUTCMonth() + 1).padStart(2, '0')
        const dd = String(kst.getUTCDate()).padStart(2, '0')
        const hh = String(kst.getUTCHours()).padStart(2, '0')
        const mi = String(kst.getUTCMinutes()).padStart(2, '0')
        const ss = String(kst.getUTCSeconds()).padStart(2, '0')
        return `${mm}-${dd} ${hh}:${mi}:${ss}`
      },
    },
    {
      key: 'query_type', label: t('metrics.queryType'), sortable: false,
      render: (row) => {
        const isWs = row.query_type === 'WEBSOCKET'
        return <span className={`inline-block rounded px-1.5 py-0.5 text-xs font-medium ${isWs ? 'bg-blue-100 text-blue-700 dark:bg-blue-900 dark:text-blue-300' : 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300'}`}>{isWs ? 'WS' : 'REST'}</span>
      },
    },
    {
      key: 'data_path', label: t('metrics.dataPath'), sortable: false,
      render: (row) => {
        const path = row.data_path ?? ''
        const color = path === 'CACHE' ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300'
          : path === 'DB' ? 'bg-amber-100 text-amber-700 dark:bg-amber-900 dark:text-amber-300'
          : 'bg-violet-100 text-violet-700 dark:bg-violet-900 dark:text-violet-300'
        return <span className={`inline-block rounded px-1.5 py-0.5 text-xs font-medium ${color}`}>{path}</span>
      },
    },
    {
      key: 'status', label: t('metrics.queryStatus'), sortable: false,
      render: (row) => {
        const ok = row.status === 'COMPLETED'
        return <span className={`inline-block rounded px-1.5 py-0.5 text-xs font-medium ${ok ? 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900 dark:text-emerald-300' : 'bg-red-100 text-red-700 dark:bg-red-900 dark:text-red-300'}`}>{row.status}</span>
      },
    },
    { key: 'unique_vessels', label: t('metrics.vessels'), align: 'right' as const, sortable: false,
      render: (row) => formatNumber(row.unique_vessels) },
    { key: 'total_points', label: t('metrics.pointsBefore'), align: 'right' as const, sortable: false,
      render: (row) => formatNumber(row.total_points) },
    { key: 'points_after_simplify', label: t('metrics.pointsAfter'), align: 'right' as const, sortable: false,
      render: (row) => formatNumber(row.points_after_simplify) },
    {
      key: 'reduction', label: t('metrics.simplification'), align: 'right' as const, sortable: false,
      render: (row) => {
        const before = row.total_points || 0
        const after = row.points_after_simplify || 0
        if (before === 0) return '-'
        return `${((1 - after / before) * 100).toFixed(0)}%`
      },
    },
    { key: 'total_chunks', label: t('metrics.chunks'), align: 'right' as const, sortable: false },
    {
      key: 'elapsed_ms', label: t('metrics.elapsed'), align: 'right' as const, sortable: false,
      render: (row) => {
        const ms = row.elapsed_ms || 0
        const color = ms < 1000 ? 'text-success' : ms < 5000 ? 'text-warning' : 'text-danger'
        return <span className={`font-mono font-medium ${color}`}>{ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`}</span>
      },
    },
    {
      key: 'response_bytes', label: t('metrics.responseSize'), align: 'right' as const, sortable: false,
      render: (row) => row.response_bytes ? formatBytes(row.response_bytes) : '-',
    },
    {
      key: 'client_ip', label: t('metrics.clientIp'), sortable: false,
      render: (row) => row.client_ip ? <span className="font-mono text-xs">{row.client_ip}</span> : '-',
    },
  ]

  return (
    <div className="space-y-6 fade-in">
      <h1 className="text-2xl font-bold">{t('metrics.title')}</h1>

      {/* System Metrics */}
      <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
        <MetricCard
          title={t('metrics.heapMemory')}
          value={metrics ? `${memUsed}MB / ${memMax}MB` : '-'}
          subtitle={metrics ? `${memPct}%` : undefined}
          trend={memPct > 85 ? 'down' : memPct > 70 ? 'neutral' : 'up'}
        />
        <MetricCard
          title={t('metrics.threads')}
          value={metrics ? String(metrics.threads) : '-'}
        />
        <MetricCard
          title={t('metrics.dbActive')}
          value={metrics ? String(metrics.database.activeConnections) : '-'}
        />
        <MetricCard
          title={t('metrics.recordsPerSec')}
          value={metrics ? `${(metrics.processing?.recordsPerSecond ?? 0).toFixed(0)}/s` : '-'}
        />
      </div>

      {/* Cache Detail Grid */}
      <div className="sb-card">
        <div className="sb-card-header">{t('metrics.cacheDetail')}</div>
        {cacheDetails ? (
          <div className="overflow-x-auto">
            <table className="sb-table">
              <thead>
                <tr>
                  <th>{t('metrics.cacheLayer')}</th>
                  <th className="text-right">{t('metrics.size')}</th>
                  <th className="text-right">{t('metrics.maxSize')}</th>
                  <th className="text-right">{t('metrics.utilization')}</th>
                  <th className="text-right">{t('metrics.hitRate')}</th>
                </tr>
              </thead>
              <tbody>
                {cacheDetails.l1_fiveMin && (
                  <tr>
                    <td>L1 (5min)</td>
                    <td className="text-right">{formatNumber(cacheDetails.l1_fiveMin.size)}</td>
                    <td className="text-right">{formatNumber(cacheDetails.l1_fiveMin.maxSize)}</td>
                    <td className="text-right">
                      {((cacheDetails.l1_fiveMin.size / Math.max(cacheDetails.l1_fiveMin.maxSize, 1)) * 100).toFixed(1)}%
                    </td>
                    <td className="text-right">{cacheDetails.l1_fiveMin.hitRate?.toFixed(1) ?? '-'}%</td>
                  </tr>
                )}
                {cacheDetails.l2_hourly && (
                  <tr>
                    <td>L2 (Hourly)</td>
                    <td className="text-right">{formatNumber(cacheDetails.l2_hourly.size)}</td>
                    <td className="text-right">{formatNumber(cacheDetails.l2_hourly.maxSize)}</td>
                    <td className="text-right">
                      {((cacheDetails.l2_hourly.size / Math.max(cacheDetails.l2_hourly.maxSize, 1)) * 100).toFixed(1)}%
                    </td>
                    <td className="text-right">{cacheDetails.l2_hourly.hitRate?.toFixed(1) ?? '-'}%</td>
                  </tr>
                )}
                {cacheDetails.l3_daily && (
                  <tr>
                    <td>L3 (Daily)</td>
                    <td className="text-right">{cacheDetails.l3_daily.cachedDays ?? 0} days</td>
                    <td className="text-right">{cacheDetails.l3_daily.retentionDays ?? '-'} days</td>
                    <td className="text-right">
                      {cacheDetails.l3_daily.totalMemoryMb?.toFixed(0) ?? 0} MB
                    </td>
                    <td className="text-right">{cacheDetails.l3_daily.totalVessels ?? 0} vessels</td>
                  </tr>
                )}
                {cacheDetails.aisTarget && (
                  <tr>
                    <td>AIS Target</td>
                    <td className="text-right">{formatNumber(cacheDetails.aisTarget.estimatedSize)}</td>
                    <td className="text-right">{formatNumber(cacheDetails.aisTarget.maxSize)}</td>
                    <td className="text-right">
                      {((cacheDetails.aisTarget.estimatedSize / Math.max(cacheDetails.aisTarget.maxSize, 1)) * 100).toFixed(1)}%
                    </td>
                    <td className="text-right">{cacheDetails.aisTarget.hitRate?.toFixed(1) ?? '-'}%</td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        ) : (
          <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
        )}
      </div>

      {/* Processing & Cache Summary */}
      <div className="grid gap-4 lg:grid-cols-2">
        <div className="sb-card">
          <div className="sb-card-header">{t('metrics.processingDelay')}</div>
          {delay ? (
            <div className="space-y-3">
              <div className="grid grid-cols-2 gap-3 text-sm">
                <div>
                  <span className="text-muted">{t('metrics.delayMinutes')}</span>
                  <div className="text-2xl font-bold">{delay.delayMinutes ?? 0}<span className="text-sm text-muted"> min</span></div>
                </div>
                <div>
                  <span className="text-muted">{t('metrics.aisCount')}</span>
                  <div className="text-2xl font-bold">{formatNumber(delay.recentAisCount)}</div>
                </div>
                <div>
                  <span className="text-muted">{t('metrics.processedVessels')}</span>
                  <div className="font-bold">{formatNumber(delay.processedVessels)}</div>
                </div>
                <div>
                  <span className="text-muted">{t('metrics.status')}</span>
                  <div className={`font-bold ${
                    delay.status === 'NORMAL' ? 'text-success' :
                    delay.status === 'WARNING' ? 'text-warning' : 'text-danger'
                  }`}>{delay.status}</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('metrics.cacheHitSummary')}</div>
          {cache ? (
            <div className="space-y-3">
              <div className="grid grid-cols-3 gap-3 text-center text-sm">
                <div>
                  <div className="text-2xl font-bold">{cache.hitRate}</div>
                  <div className="text-xs text-muted">{t('metrics.hitRate')}</div>
                </div>
                <div>
                  <div className="text-2xl font-bold">{formatNumber(cache.hitCount)}</div>
                  <div className="text-xs text-muted">{t('metrics.hits')}</div>
                </div>
                <div>
                  <div className="text-2xl font-bold">{formatNumber(cache.missCount)}</div>
                  <div className="text-xs text-muted">{t('metrics.misses')}</div>
                </div>
              </div>
            </div>
          ) : (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          )}
        </div>
      </div>

      {/* Query History Section */}
      <div className="sb-card">
        <div className="sb-card-header">{t('metrics.queryHistory')}</div>

        {/* Summary Cards */}
        <div className="mb-4 grid grid-cols-2 gap-3 lg:grid-cols-4">
          <MetricCard
            title={t('metrics.totalQueries')}
            value={summaryData ? formatNumber(totalQueries) : '-'}
            subtitle={summaryData ? `WS:${summaryData.ws_count} / REST:${summaryData.rest_count}` : undefined}
          />
          <MetricCard
            title={t('metrics.avgElapsed')}
            value={summaryData ? `${((summaryData.avg_elapsed_ms ?? 0) / 1000).toFixed(1)}s` : '-'}
          />
          <MetricCard
            title={t('metrics.p95Elapsed')}
            value={summaryData ? `${((summaryData.p95_elapsed_ms ?? 0) / 1000).toFixed(1)}s` : '-'}
          />
          <MetricCard
            title={t('metrics.cacheHitRate')}
            value={summaryData ? `${cacheHitRate}%` : '-'}
            subtitle={summaryData ? `C:${summaryData.cache_only_count}/DB:${summaryData.db_only_count}/H:${summaryData.hybrid_count}` : undefined}
          />
        </div>

        {/* Filters */}
        <div className="mb-4 flex flex-wrap items-center gap-3 text-sm">
          {/* Query Type toggle */}
          <div className="flex items-center gap-1">
            <span className="text-muted mr-1">{t('metrics.queryType')}:</span>
            {[undefined, 'WEBSOCKET', 'REST_V2'].map((val) => (
              <button
                type="button"
                key={val ?? 'all'}
                onClick={() => updateFilter({ queryType: val })}
                className={`rounded px-2 py-1 text-xs font-medium transition ${
                  filter.queryType === val
                    ? 'bg-primary text-white'
                    : 'bg-surface-secondary text-muted hover:bg-surface-tertiary'
                }`}
              >
                {val == null ? t('metrics.allTypes') : val === 'WEBSOCKET' ? 'WS' : 'REST'}
              </button>
            ))}
          </div>

          {/* Data Path toggle */}
          <div className="flex items-center gap-1">
            <span className="text-muted mr-1">{t('metrics.dataPath')}:</span>
            {[undefined, 'CACHE', 'DB', 'HYBRID'].map((val) => (
              <button
                type="button"
                key={val ?? 'all'}
                onClick={() => updateFilter({ dataPath: val })}
                className={`rounded px-2 py-1 text-xs font-medium transition ${
                  filter.dataPath === val
                    ? 'bg-primary text-white'
                    : 'bg-surface-secondary text-muted hover:bg-surface-tertiary'
                }`}
              >
                {val ?? t('metrics.allPaths')}
              </button>
            ))}
          </div>

          {/* Elapsed Time select */}
          <select
            title={t('metrics.elapsed')}
            value={filter.elapsedMsMin != null ? `${filter.elapsedMsMin}-${filter.elapsedMsMax ?? ''}` : ''}
            onChange={(e) => {
              if (!e.target.value) {
                updateFilter({ elapsedMsMin: undefined, elapsedMsMax: undefined })
              } else {
                const range = ELAPSED_RANGES.find(r =>
                  `${r.min ?? ''}-${r.max ?? ''}` === e.target.value
                )
                if (range) updateFilter({ elapsedMsMin: range.min, elapsedMsMax: range.max })
              }
            }}
            className="rounded border border-border bg-surface px-2 py-1 text-xs"
          >
            <option value="">{t('metrics.elapsed')}: {t('metrics.allTypes')}</option>
            {ELAPSED_RANGES.map((r) => (
              <option key={r.label} value={`${r.min ?? ''}-${r.max ?? ''}`}>{r.label}</option>
            ))}
          </select>

          {/* Reset */}
          <button
            type="button"
            onClick={resetFilters}
            className="rounded border border-border px-2 py-1 text-xs text-muted hover:bg-surface-secondary"
          >
            {t('metrics.resetFilters')}
          </button>
        </div>

        {/* History Table */}
        <DataTable<QueryMetricRow>
          columns={historyColumns}
          data={historyData?.content ?? []}
          keyExtractor={(row) => row.query_id}
          pageSize={filter.size ?? 20}
          totalElements={historyData?.totalElements}
          currentPage={historyData?.currentPage}
          onPageChange={(p) => setFilter(prev => ({ ...prev, page: p }))}
        />
      </div>
    </div>
  )
}
