import { useState, useCallback, useMemo } from 'react'
import { usePoller } from '../hooks/usePoller.ts'
import { useI18n } from '../hooks/useI18n.ts'
import { batchApi } from '../api/batchApi.ts'
import type { JobExecution, StepExecution } from '../api/types.ts'
import DataTable, { type Column } from '../components/common/DataTable.tsx'
import StatusBadge from '../components/common/StatusBadge.tsx'
import { formatDuration, formatNumber, formatDateTime } from '../utils/formatters.ts'
import type { TranslationKey } from '../i18n/I18nContext.tsx'

const POLL_INTERVAL = 30_000

const JOB_FILTERS: { labelKey: TranslationKey; value: string }[] = [
  { labelKey: 'jobs.all', value: '' },
  { labelKey: 'jobs.track5min', value: 'vesselTrackAggregationJob' },
  { labelKey: 'jobs.hourly', value: 'hourlyAggregationJob' },
  { labelKey: 'jobs.daily', value: 'dailyAggregationJob' },
]

const STATUS_FILTERS = ['ALL', 'COMPLETED', 'FAILED', 'RUNNING', 'STOPPED']

export default function JobMonitor() {
  const { t } = useI18n()
  const [jobs, setJobs] = useState<JobExecution[]>([])
  const [jobFilter, setJobFilter] = useState('')
  const [statusFilter, setStatusFilter] = useState('ALL')
  const [selectedJob, setSelectedJob] = useState<JobExecution | null>(null)
  const [steps, setSteps] = useState<StepExecution[]>([])
  const [stepsLoading, setStepsLoading] = useState(false)

  usePoller(async () => {
    const data = await batchApi.getJobHistory(jobFilter || undefined, 100)
    setJobs(data)
  }, POLL_INTERVAL, [jobFilter])

  const filtered = statusFilter === 'ALL'
    ? jobs
    : jobs.filter(j => j.status === statusFilter)

  const handleRowClick = useCallback(async (job: JobExecution) => {
    setSelectedJob(job)
    setStepsLoading(true)
    try {
      const data = await batchApi.getStepDetails(job.executionId)
      setSteps(data)
    } catch {
      setSteps([])
    } finally {
      setStepsLoading(false)
    }
  }, [])

  const jobColumns: Column<JobExecution>[] = useMemo(() => [
    {
      key: 'status',
      label: t('jobs.status'),
      render: (row) => <StatusBadge status={row.status} />,
      sortable: true,
    },
    { key: 'jobName', label: t('jobs.job'), sortable: true },
    { key: 'executionId', label: t('jobs.id'), sortable: true, align: 'center' as const },
    {
      key: 'startTime',
      label: t('jobs.start'),
      render: (row) => <span className="font-mono text-xs">{formatDateTime(row.startTime)}</span>,
      sortable: true,
    },
    {
      key: 'durationSeconds',
      label: t('jobs.duration'),
      render: (row) => formatDuration(row.durationSeconds),
      sortable: true,
      align: 'right' as const,
    },
    {
      key: 'totalRead',
      label: t('jobs.read'),
      render: (row) => formatNumber(row.totalRead),
      sortable: true,
      align: 'right' as const,
    },
    {
      key: 'totalWrite',
      label: t('jobs.write'),
      render: (row) => formatNumber(row.totalWrite),
      sortable: true,
      align: 'right' as const,
    },
    {
      key: 'totalSkip',
      label: t('jobs.skip'),
      render: (row) => row.totalSkip > 0 ? <span className="text-warning">{formatNumber(row.totalSkip)}</span> : '0',
      sortable: true,
      align: 'right' as const,
    },
  ], [t])

  const stepColumns: Column<StepExecution>[] = useMemo(() => [
    {
      key: 'status',
      label: t('jobs.status'),
      render: (row) => <StatusBadge status={row.status} />,
    },
    { key: 'stepName', label: t('jobs.step') },
    {
      key: 'startTime',
      label: t('jobs.start'),
      render: (row) => <span className="font-mono text-xs">{formatDateTime(row.startTime)}</span>,
    },
    {
      key: 'durationSeconds',
      label: t('jobs.duration'),
      render: (row) => formatDuration(row.durationSeconds),
      align: 'right' as const,
    },
    {
      key: 'readCount',
      label: t('jobs.read'),
      render: (row) => formatNumber(row.readCount),
      align: 'right' as const,
    },
    {
      key: 'writeCount',
      label: t('jobs.write'),
      render: (row) => formatNumber(row.writeCount),
      align: 'right' as const,
    },
    {
      key: 'commitCount',
      label: t('jobs.commits'),
      render: (row) => formatNumber(row.commitCount),
      align: 'right' as const,
    },
    {
      key: 'errors',
      label: t('jobs.errors'),
      render: (row) => row.errors?.length > 0
        ? <span className="text-danger">{row.errors.length}</span>
        : <span className="text-muted">-</span>,
      align: 'center' as const,
    },
  ], [t])

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

      {/* Filters */}
      <div className="flex flex-wrap items-center gap-4">
        <div className="flex gap-1">
          {JOB_FILTERS.map(j => (
            <button
              key={j.value}
              onClick={() => setJobFilter(j.value)}
              className={`rounded-md px-3 py-1 text-sm font-medium transition-colors ${
                jobFilter === j.value ? 'bg-primary text-white' : 'text-muted hover:bg-surface-hover'
              }`}
            >
              {t(j.labelKey)}
            </button>
          ))}
        </div>
        <div className="h-5 w-px bg-border" />
        <div className="flex gap-1">
          {STATUS_FILTERS.map(s => (
            <button
              key={s}
              onClick={() => setStatusFilter(s)}
              className={`rounded-md px-3 py-1 text-sm font-medium transition-colors ${
                statusFilter === s ? 'bg-primary text-white' : 'text-muted hover:bg-surface-hover'
              }`}
            >
              {s}
            </button>
          ))}
        </div>
        <span className="ml-auto text-sm text-muted">{filtered.length}{t('common.items')}</span>
      </div>

      {/* Job Table */}
      <DataTable
        columns={jobColumns}
        data={filtered}
        keyExtractor={(row) => row.executionId}
        onRowClick={handleRowClick}
      />

      {/* Step Detail */}
      {selectedJob && (
        <div className="sb-card">
          <div className="mb-4 flex items-center justify-between">
            <div>
              <div className="sb-card-header">{t('jobs.stepDetails')}</div>
              <div className="text-sm">
                <span className="font-medium">{selectedJob.jobName}</span>
                <span className="text-muted"> #{selectedJob.executionId}</span>
              </div>
            </div>
            <button
              onClick={() => setSelectedJob(null)}
              className="rounded-md border border-border px-3 py-1 text-sm text-muted hover:text-foreground"
            >
              {t('common.close')}
            </button>
          </div>
          {stepsLoading ? (
            <div className="py-4 text-center text-sm text-muted">{t('common.loading')}</div>
          ) : (
            <DataTable
              columns={stepColumns}
              data={steps}
              keyExtractor={(row) => row.stepName}
              pageSize={50}
            />
          )}
          {steps.some(s => s.errors?.length > 0) && (
            <div className="mt-4 rounded-lg border border-danger bg-danger/5 p-3">
              <div className="mb-2 text-sm font-semibold text-danger">{t('jobs.errors')}</div>
              {steps
                .filter(s => s.errors?.length > 0)
                .map(s => (
                  <div key={s.stepName} className="mb-2">
                    <div className="text-xs font-medium text-muted">{s.stepName}</div>
                    {s.errors.map((err, i) => (
                      <pre key={i} className="mt-1 overflow-x-auto rounded bg-surface-hover p-2 font-mono text-xs">
                        {err}
                      </pre>
                    ))}
                  </div>
                ))}
            </div>
          )}
        </div>
      )}
    </div>
  )
}
