import { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ArrowLeftRight, RefreshCw } from 'lucide-react';

import { PageContainer, PageHeader, Section } from '@shared/components/layout';
import { Badge } from '@shared/components/ui/badge';
import { Button } from '@shared/components/ui/button';
import { Input } from '@shared/components/ui/input';
import { Select } from '@shared/components/ui/select';
import { Card, CardContent } from '@shared/components/ui/card';
import { DataTable, type DataColumn } from '@shared/components/common/DataTable';

import { formatDateTime } from '@shared/utils/dateFormat';
import { getAlertLevelIntent, getAlertLevelLabel } from '@shared/constants/alertLevels';
import { getTransshipSuspects, type VesselAnalysis } from '@/services/analysisApi';
import { useSettingsStore } from '@stores/settingsStore';

/**
 * 환적(Transshipment) 의심 선박 탐지 페이지.
 *
 * prediction `algorithms/transshipment.py` 의 5단계 필터 파이프라인 결과
 * (transship_suspect=true) 를 전체 목록으로 조회·집계·상세 확인.
 *
 * features.transship_tier (CRITICAL/HIGH/MEDIUM) 와 transship_score 로 심각도 판단.
 * 기존 `features/vessel/TransferDetection.tsx` 는 선박 상세 수준, 이 페이지는
 * 전체 목록·통계 수준의 운영 대시보드.
 */

const HOUR_OPTIONS = [1, 6, 12, 24, 48] as const;
const LEVEL_OPTIONS = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] as const;
const DEFAULT_HOURS = 6;
const DEFAULT_SIZE = 200;

type TransshipTier = 'CRITICAL' | 'HIGH' | 'MEDIUM' | string;

interface TransshipFeatures {
  transship_tier?: TransshipTier;
  transship_score?: number;
  dark_tier?: string;
  [key: string]: unknown;
}

function readTier(row: VesselAnalysis): string {
  const f = (row.features ?? {}) as TransshipFeatures;
  return f.transship_tier ?? '-';
}

function readScore(row: VesselAnalysis): number | null {
  const f = (row.features ?? {}) as TransshipFeatures;
  return typeof f.transship_score === 'number' ? f.transship_score : null;
}

export function TransshipmentDetection() {
  const { t } = useTranslation('detection');
  const { t: tc } = useTranslation('common');
  const lang = useSettingsStore((s) => s.language) as 'ko' | 'en';

  const [rows, setRows] = useState<VesselAnalysis[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [hours, setHours] = useState<number>(DEFAULT_HOURS);
  const [levelFilter, setLevelFilter] = useState('');
  const [mmsiFilter, setMmsiFilter] = useState('');
  const [selected, setSelected] = useState<VesselAnalysis | null>(null);

  const loadData = useCallback(async () => {
    setLoading(true);
    setError('');
    try {
      const resp = await getTransshipSuspects({ hours, page: 0, size: DEFAULT_SIZE });
      setRows(resp.content);
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : t('transshipment.error.loadFailed'));
    } finally {
      setLoading(false);
    }
  }, [hours, t]);

  useEffect(() => {
    loadData();
  }, [loadData]);

  const filteredRows = useMemo(() => {
    return rows.filter((r) => {
      if (levelFilter && r.riskLevel !== levelFilter) return false;
      if (mmsiFilter && !r.mmsi.includes(mmsiFilter)) return false;
      return true;
    });
  }, [rows, levelFilter, mmsiFilter]);

  const stats = useMemo(() => {
    const byLevel: Record<string, number> = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 };
    const byTier: Record<string, number> = { CRITICAL: 0, HIGH: 0, MEDIUM: 0 };
    for (const r of rows) {
      if (r.riskLevel && byLevel[r.riskLevel] !== undefined) {
        byLevel[r.riskLevel]++;
      }
      const tier = readTier(r);
      if (byTier[tier] !== undefined) {
        byTier[tier]++;
      }
    }
    return { byLevel, byTier };
  }, [rows]);

  const cols: DataColumn<VesselAnalysis & Record<string, unknown>>[] = useMemo(
    () => [
      {
        key: 'analyzedAt',
        label: t('transshipment.columns.analyzedAt'),
        width: '140px',
        sortable: true,
        render: (v) => (
          <span className="text-muted-foreground text-[10px]">{formatDateTime(v as string)}</span>
        ),
      },
      {
        key: 'mmsi',
        label: t('transshipment.columns.mmsi'),
        width: '120px',
        sortable: true,
        render: (v) => (
          <span className="font-mono text-[10px] text-cyan-600 dark:text-cyan-400">
            {v as string}
          </span>
        ),
      },
      {
        key: 'transshipPairMmsi',
        label: t('transshipment.columns.pairMmsi'),
        width: '120px',
        render: (v) => (
          <span className="font-mono text-[10px] text-label">{(v as string) || '-'}</span>
        ),
      },
      {
        key: 'transshipDurationMin',
        label: t('transshipment.columns.durationMin'),
        width: '90px',
        align: 'right',
        sortable: true,
        render: (v) => {
          const n = typeof v === 'number' ? v : Number(v ?? 0);
          return <span className="font-mono text-label">{n.toFixed(0)}</span>;
        },
      },
      {
        key: 'features',
        label: t('transshipment.columns.tier'),
        width: '90px',
        align: 'center',
        render: (_, row) => {
          const tier = readTier(row);
          const isKnown = ['CRITICAL', 'HIGH', 'MEDIUM'].includes(tier);
          return (
            <Badge
              intent={isKnown ? getAlertLevelIntent(tier) : 'muted'}
              size="sm"
            >
              {isKnown ? getAlertLevelLabel(tier, tc, lang) : tier}
            </Badge>
          );
        },
      },
      {
        key: 'riskScore',
        label: t('transshipment.columns.riskScore'),
        width: '80px',
        align: 'right',
        sortable: true,
        render: (v) => <span className="font-mono text-label">{(v as number) ?? 0}</span>,
      },
      {
        key: 'riskLevel',
        label: t('transshipment.columns.riskLevel'),
        width: '90px',
        align: 'center',
        sortable: true,
        render: (v) => (
          <Badge intent={getAlertLevelIntent(v as string)} size="sm">
            {getAlertLevelLabel(v as string, tc, lang)}
          </Badge>
        ),
      },
      {
        key: 'zoneCode',
        label: t('transshipment.columns.zone'),
        width: '130px',
        render: (v) => <span className="text-hint text-[10px]">{(v as string) || '-'}</span>,
      },
    ],
    [t, tc, lang],
  );

  return (
    <PageContainer>
      <PageHeader
        icon={ArrowLeftRight}
        iconColor="text-purple-600 dark:text-purple-400"
        title={t('transshipment.title')}
        description={t('transshipment.desc')}
        actions={
          <Button
            variant="outline"
            size="sm"
            onClick={loadData}
            disabled={loading}
            icon={<RefreshCw className="w-3.5 h-3.5" />}
          >
            {t('transshipment.refresh')}
          </Button>
        }
      />

      {error && (
        <Card variant="default">
          <CardContent className="text-destructive text-xs py-2">{error}</CardContent>
        </Card>
      )}

      <Section title={t('transshipment.stats.title')}>
        <div className="grid grid-cols-2 md:grid-cols-5 gap-2">
          <StatCard label={t('transshipment.stats.total')} value={rows.length} />
          <StatCard label={t('transshipment.stats.tierCritical')} value={stats.byTier.CRITICAL} intent="critical" />
          <StatCard label={t('transshipment.stats.tierHigh')} value={stats.byTier.HIGH} intent="warning" />
          <StatCard label={t('transshipment.stats.tierMedium')} value={stats.byTier.MEDIUM} intent="info" />
          <StatCard label={t('transshipment.stats.riskCritical')} value={stats.byLevel.CRITICAL} intent="critical" />
        </div>
      </Section>

      <Section title={t('transshipment.list.title')}>
        <div className="grid grid-cols-1 md:grid-cols-4 gap-2 mb-3">
          <Select
            aria-label={t('transshipment.filters.hours')}
            value={String(hours)}
            onChange={(e) => setHours(Number(e.target.value))}
          >
            {HOUR_OPTIONS.map((h) => (
              <option key={h} value={h}>
                {t('transshipment.filters.hoursValue', { h })}
              </option>
            ))}
          </Select>
          <Select
            aria-label={t('transshipment.filters.level')}
            value={levelFilter}
            onChange={(e) => setLevelFilter(e.target.value)}
          >
            <option value="">{t('transshipment.filters.allLevel')}</option>
            {LEVEL_OPTIONS.map((l) => (
              <option key={l} value={l}>
                {getAlertLevelLabel(l, tc, lang)}
              </option>
            ))}
          </Select>
          <Input
            aria-label={t('transshipment.filters.mmsi')}
            placeholder={t('transshipment.filters.mmsi')}
            value={mmsiFilter}
            onChange={(e) => setMmsiFilter(e.target.value)}
          />
          <div className="flex items-center justify-end gap-1.5">
            <Badge intent="info" size="sm">
              {filteredRows.length} / {rows.length}
            </Badge>
          </div>
        </div>

        {filteredRows.length === 0 && !loading ? (
          <p className="text-hint text-xs py-4 text-center">
            {t('transshipment.list.empty', { hours })}
          </p>
        ) : (
          <DataTable
            data={filteredRows as (VesselAnalysis & Record<string, unknown>)[]}
            columns={cols}
            pageSize={20}
            showSearch={false}
            showExport={false}
            showPrint={false}
            onRowClick={(row) => setSelected(row as VesselAnalysis)}
          />
        )}
      </Section>

      {selected && (
        <Section title={t('transshipment.detail.title')}>
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-xs">
            <div className="space-y-1.5">
              <DetailRow
                label={t('transshipment.columns.analyzedAt')}
                value={formatDateTime(selected.analyzedAt)}
              />
              <DetailRow label={t('transshipment.columns.mmsi')} value={selected.mmsi} mono />
              <DetailRow
                label={t('transshipment.columns.pairMmsi')}
                value={selected.transshipPairMmsi ?? '-'}
                mono
              />
              <DetailRow
                label={t('transshipment.columns.durationMin')}
                value={`${selected.transshipDurationMin ?? 0}분`}
              />
              <DetailRow
                label={t('transshipment.columns.riskScore')}
                value={String(selected.riskScore ?? 0)}
              />
              <DetailRow
                label={t('transshipment.columns.zone')}
                value={selected.zoneCode ?? '-'}
              />
              <DetailRow
                label={t('transshipment.detail.location')}
                value={
                  selected.lat != null && selected.lon != null
                    ? `${selected.lat.toFixed(4)}, ${selected.lon.toFixed(4)}`
                    : '-'
                }
              />
            </div>
            <div className="space-y-2">
              <div className="flex items-center gap-2">
                <span className="text-xs text-label">
                  {t('transshipment.columns.tier')}:
                </span>
                {(() => {
                  const tier = readTier(selected);
                  const isKnown = ['CRITICAL', 'HIGH', 'MEDIUM'].includes(tier);
                  return (
                    <Badge intent={isKnown ? getAlertLevelIntent(tier) : 'muted'} size="sm">
                      {isKnown ? getAlertLevelLabel(tier, tc, lang) : tier}
                    </Badge>
                  );
                })()}
                <span className="text-xs text-label ml-3">
                  {t('transshipment.detail.transshipScore')}:
                </span>
                <span className="text-xs font-mono text-heading">
                  {readScore(selected)?.toFixed(1) ?? '-'}
                </span>
              </div>
              {selected.features && Object.keys(selected.features).length > 0 && (
                <div>
                  <div className="text-[10px] text-hint mb-1">
                    {t('transshipment.detail.features')}
                  </div>
                  <pre className="bg-surface-raised text-[10px] text-label p-2 overflow-auto max-h-48">
                    {JSON.stringify(selected.features, null, 2)}
                  </pre>
                </div>
              )}
              <div className="flex justify-end pt-2">
                <Button variant="ghost" size="sm" onClick={() => setSelected(null)}>
                  {t('transshipment.detail.close')}
                </Button>
              </div>
            </div>
          </div>
        </Section>
      )}
    </PageContainer>
  );
}

// ─── 내부 컴포넌트 ─────────────

interface StatCardProps {
  label: string;
  value: number;
  intent?: 'warning' | 'info' | 'critical' | 'muted';
}

function StatCard({ label, value, intent }: StatCardProps) {
  return (
    <Card variant="default">
      <CardContent className="py-3 flex flex-col items-center gap-1">
        <span className="text-[10px] text-hint text-center">{label}</span>
        {intent ? (
          <Badge intent={intent} size="md">
            {value}
          </Badge>
        ) : (
          <span className="text-lg font-bold text-heading">{value}</span>
        )}
      </CardContent>
    </Card>
  );
}

interface DetailRowProps {
  label: string;
  value: string;
  mono?: boolean;
}

function DetailRow({ label, value, mono }: DetailRowProps) {
  return (
    <div className="flex items-start gap-2">
      <span className="text-hint w-24 shrink-0">{label}</span>
      <span className={mono ? 'font-mono text-label' : 'text-label'}>{value}</span>
    </div>
  );
}

export default TransshipmentDetection;
