import { useState } from 'react'
import { usePoller } from '../hooks/usePoller.ts'
import { useI18n } from '../hooks/useI18n.ts'
import { batchApi } from '../api/batchApi.ts'
import { monitorApi } from '../api/monitorApi.ts'
import type {
  BatchStatistics,
  CacheStats,
  DailyStats,
  JobExecution,
  ProcessingDelay,
} from '../api/types.ts'
import type { CacheDetails } from '../api/types.ts'
import PipelineChart from '../components/charts/PipelineChart.tsx'
import LineChart from '../components/charts/LineChart.tsx'
import MetricCard from '../components/charts/MetricCard.tsx'
import StatusBadge from '../components/common/StatusBadge.tsx'
import { formatNumber, formatDuration, formatDateTime, formatPercent } from '../utils/formatters.ts'

const POLL_INTERVAL = 30_000

const JOB_DISPLAY: Record<string, string> = {
  aisTargetImportJob: 'AIS 수집 (1분)',
  vesselTrackAggregationJob: 'Track (5분)',
  hourlyAggregationJob: 'Hourly (1시간)',
  dailyAggregationJob: 'Daily (1일)',
}

export default function DataPipeline() {
  const { t } = useI18n()
  const [stats, setStats] = useState<BatchStatistics | null>(null)
  const [daily, setDaily] = useState<DailyStats | null>(null)
  const [delay, setDelay] = useState<ProcessingDelay | null>(null)
  const [cache, setCache] = useState<CacheStats | null>(null)
  const [cacheDetails, setCacheDetails] = useState<CacheDetails | null>(null)
  const [recentJobs, setRecentJobs] = useState<JobExecution[]>([])

  usePoller(async () => {
    const [s, d, dl, c, cd, rj] = await Promise.allSettled([
      batchApi.getStatistics(7),
      batchApi.getDailyStats(),
      monitorApi.getDelay(),
      monitorApi.getCacheStats(),
      monitorApi.getCacheDetails(),
      batchApi.getJobHistory(undefined, 20),
    ])
    if (s.status === 'fulfilled') setStats(s.value)
    if (d.status === 'fulfilled') setDaily(d.value)
    if (dl.status === 'fulfilled') setDelay(dl.value)
    if (c.status === 'fulfilled') setCache(c.value)
    if (cd.status === 'fulfilled') setCacheDetails(cd.value)
    if (rj.status === 'fulfilled') setRecentJobs(rj.value)
  }, POLL_INTERVAL)

  const jobCounts = stats?.byJob.executionCounts ?? {}
  const jobTimes = stats?.byJob.processingTimes ?? {}

  const getStageStatus = (jobName: string) => {
    const recent = recentJobs.find(j => j.jobName === jobName)
    if (!recent) return 'idle' as const
    if (recent.status === 'STARTED' || recent.status === 'STARTING') return 'active' as const
    if (recent.status === 'FAILED') return 'error' as const
    return 'active' as const
  }

  const stages = [
    {
      label: 'AIS API',
      sublabel: t('pipeline.collect1min'),
      count: formatNumber(jobCounts['aisTargetImportJob'] ?? 0),
      status: getStageStatus('aisTargetImportJob'),
    },
    {
      label: 'Track 5min',
      sublabel: t('pipeline.aggregate5min'),
      count: formatNumber(jobCounts['vesselTrackAggregationJob'] ?? 0),
      status: getStageStatus('vesselTrackAggregationJob'),
    },
    {
      label: 'Hourly',
      sublabel: t('pipeline.mergeHourly'),
      count: formatNumber(jobCounts['hourlyAggregationJob'] ?? 0),
      status: getStageStatus('hourlyAggregationJob'),
    },
    {
      label: 'Daily',
      sublabel: t('pipeline.mergeDaily'),
      count: formatNumber(jobCounts['dailyAggregationJob'] ?? 0),
      status: getStageStatus('dailyAggregationJob'),
    },
  ]

  /* 일별 처리량 라인 차트 데이터 */
  const dailyChartData = daily?.dailyStats.map(d => ({
    date: d.date.slice(5),
    processed: d.totalProcessed,
    vessel: d.vesselJobs,
    track: d.trackJobs,
  })) ?? []

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

      {/* Pipeline Flow */}
      <div className="sb-card">
        <div className="sb-card-header">{t('pipeline.flowTitle')}</div>
        <PipelineChart stages={stages} />
      </div>

      {/* Stage Metric Cards */}
      <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
        {Object.entries(JOB_DISPLAY).map(([jobName, label]) => (
          <MetricCard
            key={jobName}
            title={label}
            value={`${jobCounts[jobName] ?? 0}${t('pipeline.executions')}`}
            subtitle={`${formatDuration(jobTimes[jobName] ?? 0)} ${t('pipeline.totalTime')}`}
          />
        ))}
      </div>

      {/* Processing Delay + Cache Status */}
      <div className="grid gap-4 lg:grid-cols-2">
        <div className="sb-card">
          <div className="sb-card-header">{t('pipeline.processingDelay')}</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('pipeline.delayMin')}</span>
                <StatusBadge status={delay.status ?? 'NORMAL'} />
              </div>
              <div className="grid grid-cols-2 gap-3 text-sm">
                <div>
                  <span className="text-muted">{t('pipeline.aisLatest')}</span>
                  <div className="font-mono text-xs">{formatDateTime(delay.aisLatestTime)}</div>
                </div>
                <div>
                  <span className="text-muted">{t('pipeline.processLatest')}</span>
                  <div className="font-mono text-xs">{formatDateTime(delay.queryLatestTime)}</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('pipeline.cacheOverview')}</div>
          {cacheDetails ? (
            <div className="space-y-3">
              <div className="grid grid-cols-3 gap-3 text-center text-sm">
                <div>
                  <div className="text-xs text-muted">L1 (5min)</div>
                  <div className="text-lg font-bold">{formatNumber(cacheDetails.l1_fiveMin?.size)}</div>
                  <div className="text-xs text-muted">/ {formatNumber(cacheDetails.l1_fiveMin?.maxSize)}</div>
                </div>
                <div>
                  <div className="text-xs text-muted">L2 (Hourly)</div>
                  <div className="text-lg font-bold">{formatNumber(cacheDetails.l2_hourly?.size)}</div>
                  <div className="text-xs text-muted">/ {formatNumber(cacheDetails.l2_hourly?.maxSize)}</div>
                </div>
                <div>
                  <div className="text-xs text-muted">L3 (Daily)</div>
                  <div className="text-lg font-bold">{cacheDetails.l3_daily?.cachedDays ?? 0}</div>
                  <div className="text-xs text-muted">{t('pipeline.cachedDays')}</div>
                </div>
              </div>
              {cache && (
                <div className="flex items-center justify-between rounded-lg bg-surface-hover px-3 py-2 text-sm">
                  <span className="text-muted">{t('pipeline.totalHitRate')}</span>
                  <div className="flex items-center gap-2">
                    <span className="font-bold">{cache.hitRate}</span>
                    <StatusBadge status={cache.status} />
                  </div>
                </div>
              )}
            </div>
          ) : (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          )}
        </div>
      </div>

      {/* Daily Throughput Timeline */}
      {dailyChartData.length > 0 && (
        <div className="sb-card">
          <div className="sb-card-header">{t('pipeline.dailyThroughput')}</div>
          <LineChart
            data={dailyChartData}
            series={[
              { dataKey: 'processed', color: 'var(--sb-primary)', name: t('pipeline.totalProcessed') },
              { dataKey: 'vessel', color: 'var(--sb-success)', name: t('pipeline.vesselJobs') },
              { dataKey: 'track', color: 'var(--sb-info)', name: t('pipeline.trackJobs') },
            ]}
            xKey="date"
            height={280}
          />
        </div>
      )}

      {/* Recent Job Executions */}
      <div className="sb-card">
        <div className="sb-card-header">{t('pipeline.recentJobs')}</div>
        <div className="space-y-1">
          {recentJobs.length === 0 ? (
            <div className="py-4 text-center text-sm text-muted">{t('common.noData')}</div>
          ) : (
            recentJobs.slice(0, 10).map(job => (
              <div key={job.executionId} className="flex items-center justify-between rounded-lg bg-surface-hover px-3 py-2">
                <div className="flex items-center gap-3">
                  <StatusBadge status={job.status} />
                  <div>
                    <div className="text-sm font-medium">{JOB_DISPLAY[job.jobName] ?? job.jobName}</div>
                    <div className="text-xs text-muted">#{job.executionId} &middot; {formatDateTime(job.startTime)}</div>
                  </div>
                </div>
                <div className="text-right text-sm">
                  <div>{formatDuration(job.durationSeconds)}</div>
                  <div className="text-xs text-muted">
                    R:{formatNumber(job.totalRead)} W:{formatNumber(job.totalWrite)}
                  </div>
                </div>
              </div>
            ))
          )}
        </div>
      </div>

      {/* Summary Stats */}
      {stats && (
        <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
          <MetricCard
            title={t('pipeline.totalExec')}
            value={formatNumber(stats.summary.totalExecutions)}
            subtitle={`${formatPercent(stats.summary.successRate)} ${t('pipeline.successRate')}`}
          />
          <MetricCard
            title={t('pipeline.totalRecords')}
            value={formatNumber(stats.summary.totalRecordsProcessed)}
          />
          <MetricCard
            title={t('pipeline.avgDuration')}
            value={formatDuration(stats.summary.avgProcessingTimeSeconds)}
          />
          <MetricCard
            title={t('pipeline.totalTime')}
            value={formatDuration(stats.summary.totalProcessingTimeSeconds)}
          />
        </div>
      )}
    </div>
  )
}
