import { useState, useEffect, useCallback } from 'react';

// ─── 타입 ──────────────────────────────────────────────────────────────────────

type PipelineStatus = '정상' | '지연' | '중단';
type ReceiveStatus = '수신완료' | '수신대기' | '수신실패' | '시간초과';
type ProcessStatus = '처리완료' | '처리중' | '대기' | '오류';
type DataSource = 'HYCOM' | '기상청' | 'KOSPS DLL';
type AlertLevel = '경고' | '주의' | '정보';

interface PipelineNode {
  id: string;
  name: string;
  status: PipelineStatus;
  lastReceived: string;
  cycle: string;
}

interface DataLogRow {
  id: string;
  timestamp: string;
  source: DataSource;
  dataType: string;
  size: string;
  receiveStatus: ReceiveStatus;
  processStatus: ProcessStatus;
}

interface AlertItem {
  id: string;
  level: AlertLevel;
  message: string;
  timestamp: string;
}

// ─── Mock 데이터 ────────────────────────────────────────────────────────────────

const MOCK_PIPELINE: PipelineNode[] = [
  {
    id: 'hycom',
    name: 'HYCOM 해양순환모델',
    status: '정상',
    lastReceived: '2026-04-11 06:00',
    cycle: '6시간 주기',
  },
  {
    id: 'kma',
    name: '기상청 수치모델',
    status: '정상',
    lastReceived: '2026-04-11 06:00',
    cycle: '3시간 주기',
  },
  {
    id: 'kosps-server',
    name: '광주 KOSPS 서버',
    status: '정상',
    lastReceived: '2026-04-11 06:05',
    cycle: '수신 즉시',
  },
  {
    id: 'fortran-dll',
    name: 'KOSPS Fortran DLL 연산',
    status: '지연',
    lastReceived: '2026-04-11 05:45',
    cycle: '예측 시작 즉시',
  },
  {
    id: 'result-api',
    name: '결과 수신 API',
    status: '정상',
    lastReceived: '2026-04-11 06:10',
    cycle: '예측 완료 즉시',
  },
];

const MOCK_LOGS: DataLogRow[] = [
  {
    id: 'log-01',
    timestamp: '2026-04-11 06:10',
    source: 'KOSPS DLL',
    dataType: 'DLL 응답 결과',
    size: '28 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-02',
    timestamp: '2026-04-11 06:05',
    source: '기상청',
    dataType: '풍향/풍속',
    size: '38 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-03',
    timestamp: '2026-04-11 06:05',
    source: '기상청',
    dataType: '기압',
    size: '22 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-04',
    timestamp: '2026-04-11 06:00',
    source: 'HYCOM',
    dataType: '해수면온도(SST)',
    size: '98 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-05',
    timestamp: '2026-04-11 06:00',
    source: 'HYCOM',
    dataType: '해류(U/V)',
    size: '142 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-06',
    timestamp: '2026-04-11 06:00',
    source: '기상청',
    dataType: '기온',
    size: '19 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-07',
    timestamp: '2026-04-11 05:55',
    source: 'KOSPS DLL',
    dataType: 'DLL 호출 요청',
    size: '3 MB',
    receiveStatus: '수신완료',
    processStatus: '처리중',
  },
  {
    id: 'log-08',
    timestamp: '2026-04-11 05:45',
    source: 'KOSPS DLL',
    dataType: 'DLL 응답 결과',
    size: '-',
    receiveStatus: '수신대기',
    processStatus: '대기',
  },
  {
    id: 'log-09',
    timestamp: '2026-04-11 03:10',
    source: 'HYCOM',
    dataType: '해류(U/V)',
    size: '140 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-10',
    timestamp: '2026-04-11 03:05',
    source: '기상청',
    dataType: '풍향/풍속',
    size: '37 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-11',
    timestamp: '2026-04-11 03:00',
    source: 'HYCOM',
    dataType: '해수면높이(SSH)',
    size: '54 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-12',
    timestamp: '2026-04-11 03:00',
    source: 'KOSPS DLL',
    dataType: 'DLL 응답 결과',
    size: '27 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-13',
    timestamp: '2026-04-11 00:05',
    source: '기상청',
    dataType: '기압',
    size: '23 MB',
    receiveStatus: '수신완료',
    processStatus: '처리완료',
  },
  {
    id: 'log-14',
    timestamp: '2026-04-11 00:00',
    source: 'HYCOM',
    dataType: '해수면높이(SSH)',
    size: '53 MB',
    receiveStatus: '시간초과',
    processStatus: '오류',
  },
  {
    id: 'log-15',
    timestamp: '2026-04-11 00:00',
    source: 'KOSPS DLL',
    dataType: 'DLL 호출 요청',
    size: '-',
    receiveStatus: '수신실패',
    processStatus: '오류',
  },
];

const MOCK_ALERTS: AlertItem[] = [
  {
    id: 'alert-01',
    level: '경고',
    message: 'KOSPS Fortran DLL 응답 지연 — 평균 응답시간 초과',
    timestamp: '2026-04-11 05:45',
  },
  {
    id: 'alert-02',
    level: '주의',
    message: 'HYCOM SSH 데이터 다음 수신 예정: 09:00',
    timestamp: '2026-04-11 06:00',
  },
  {
    id: 'alert-03',
    level: '정보',
    message: '금일 KOSPS 예측 완료: 3회 / 6회',
    timestamp: '2026-04-11 06:12',
  },
];

// ─── Mock fetch ─────────────────────────────────────────────────────────────────

interface KospsData {
  pipeline: PipelineNode[];
  logs: DataLogRow[];
  alerts: AlertItem[];
}

function fetchKospsData(): Promise<KospsData> {
  return new Promise((resolve) => {
    setTimeout(
      () =>
        resolve({
          pipeline: MOCK_PIPELINE,
          logs: MOCK_LOGS,
          alerts: MOCK_ALERTS,
        }),
      300,
    );
  });
}

// ─── 유틸 ───────────────────────────────────────────────────────────────────────

function getPipelineStatusStyle(status: PipelineStatus): string {
  if (status === '정상') return 'text-emerald-400 bg-emerald-500/10';
  if (status === '지연') return 'text-yellow-400 bg-yellow-500/10';
  return 'text-red-400 bg-red-500/10';
}

function getPipelineBorderStyle(status: PipelineStatus): string {
  if (status === '정상') return 'border-l-emerald-500';
  if (status === '지연') return 'border-l-yellow-500';
  return 'border-l-red-500';
}

function getReceiveStatusStyle(status: ReceiveStatus): string {
  if (status === '수신완료') return 'text-emerald-400 bg-emerald-500/10';
  if (status === '수신대기') return 'text-yellow-400 bg-yellow-500/10';
  return 'text-red-400 bg-red-500/10';
}

function getProcessStatusStyle(status: ProcessStatus): string {
  if (status === '처리완료') return 'text-emerald-400 bg-emerald-500/10';
  if (status === '처리중') return 'text-cyan-400 bg-cyan-500/10';
  if (status === '대기') return 'text-yellow-400 bg-yellow-500/10';
  return 'text-red-400 bg-red-500/10';
}

function getAlertStyle(level: AlertLevel): string {
  if (level === '경고') return 'text-red-400 bg-red-500/10 border-red-500/30';
  if (level === '주의') return 'text-yellow-400 bg-yellow-500/10 border-yellow-500/30';
  return 'text-cyan-400 bg-cyan-500/10 border-cyan-500/30';
}

// ─── 파이프라인 카드 ─────────────────────────────────────────────────────────────

function PipelineCard({ node }: { node: PipelineNode }) {
  const badgeStyle = getPipelineStatusStyle(node.status);
  const borderStyle = getPipelineBorderStyle(node.status);

  return (
    <div
      className={`flex-1 min-w-0 bg-bg-card rounded border border-stroke-1 border-l-2 ${borderStyle} p-3 flex flex-col gap-1.5`}
    >
      <div className="text-xs font-medium text-t1 leading-snug">{node.name}</div>
      <span
        className={`self-start inline-block px-1.5 py-0.5 rounded text-label-2 font-medium ${badgeStyle}`}
      >
        {node.status}
      </span>
      <div className="text-label-2 text-t3 mt-0.5">최근 수신: {node.lastReceived}</div>
      <div className="text-label-2 text-t3">{node.cycle}</div>
    </div>
  );
}

function PipelineFlow({ nodes, loading }: { nodes: PipelineNode[]; loading: boolean }) {
  if (loading && nodes.length === 0) {
    return (
      <div className="flex items-center gap-1 animate-pulse">
        {Array.from({ length: 5 }).map((_, i) => (
          <div key={i} className="flex items-center gap-1">
            <div className="flex-1 h-16 bg-bg-elevated rounded w-28" />
            {i < 4 && <span className="text-t3 text-sm px-0.5">→</span>}
          </div>
        ))}
      </div>
    );
  }

  return (
    <div className="flex items-stretch gap-1">
      {nodes.map((node, idx) => (
        <div key={node.id} className="flex items-center gap-1 flex-1 min-w-0">
          <PipelineCard node={node} />
          {idx < nodes.length - 1 && (
            <span className="text-t3 text-sm shrink-0 px-0.5">→</span>
          )}
        </div>
      ))}
    </div>
  );
}

// ─── 수신 이력 테이블 ────────────────────────────────────────────────────────────

type FilterSource = 'all' | DataSource;
type FilterReceive = 'all' | ReceiveStatus;
type FilterPeriod = '6h' | '12h' | '24h';

const PERIOD_HOURS: Record<FilterPeriod, number> = { '6h': 6, '12h': 12, '24h': 24 };

function filterLogs(
  rows: DataLogRow[],
  source: FilterSource,
  receive: FilterReceive,
  period: FilterPeriod,
): DataLogRow[] {
  const cutoff = new Date('2026-04-11T06:30:00');
  const hours = PERIOD_HOURS[period];
  const from = new Date(cutoff.getTime() - hours * 60 * 60 * 1000);

  return rows.filter((r) => {
    if (source !== 'all' && r.source !== source) return false;
    if (receive !== 'all' && r.receiveStatus !== receive) return false;
    const ts = new Date(r.timestamp.replace(' ', 'T'));
    if (ts < from) return false;
    return true;
  });
}

const LOG_HEADERS = ['시간', '데이터소스', '데이터종류', '크기', '수신상태', '처리상태'];

function DataLogTable({ rows, loading }: { rows: DataLogRow[]; loading: boolean }) {
  return (
    <div className="overflow-auto">
      <table className="w-full text-xs border-collapse">
        <thead>
          <tr className="bg-bg-elevated text-t3 uppercase tracking-wide">
            {LOG_HEADERS.map((h) => (
              <th
                key={h}
                className="px-3 py-2 text-left font-medium border-b border-stroke-1 whitespace-nowrap"
              >
                {h}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {loading && rows.length === 0
            ? Array.from({ length: 8 }).map((_, i) => (
                <tr key={i} className="border-b border-stroke-1 animate-pulse">
                  {LOG_HEADERS.map((_, j) => (
                    <td key={j} className="px-3 py-2">
                      <div className="h-3 bg-bg-elevated rounded w-16" />
                    </td>
                  ))}
                </tr>
              ))
            : rows.map((row) => (
                <tr key={row.id} className="border-b border-stroke-1 hover:bg-bg-surface/50">
                  <td className="px-3 py-2 text-t2 whitespace-nowrap font-mono">
                    {row.timestamp}
                  </td>
                  <td className="px-3 py-2 font-medium text-t1 whitespace-nowrap">{row.source}</td>
                  <td className="px-3 py-2 text-t2 whitespace-nowrap">{row.dataType}</td>
                  <td className="px-3 py-2 text-t2 whitespace-nowrap font-mono">{row.size}</td>
                  <td className="px-3 py-2">
                    <span
                      className={`inline-block px-1.5 py-0.5 rounded text-label-2 font-medium ${getReceiveStatusStyle(row.receiveStatus)}`}
                    >
                      {row.receiveStatus}
                    </span>
                  </td>
                  <td className="px-3 py-2">
                    <span
                      className={`inline-block px-1.5 py-0.5 rounded text-label-2 font-medium ${getProcessStatusStyle(row.processStatus)}`}
                    >
                      {row.processStatus}
                    </span>
                  </td>
                </tr>
              ))}
          {!loading && rows.length === 0 && (
            <tr>
              <td colSpan={6} className="px-3 py-8 text-center text-t3">
                조회된 데이터가 없습니다.
              </td>
            </tr>
          )}
        </tbody>
      </table>
    </div>
  );
}

// ─── 알림 목록 ───────────────────────────────────────────────────────────────────

function AlertList({ alerts, loading }: { alerts: AlertItem[]; loading: boolean }) {
  if (loading && alerts.length === 0) {
    return (
      <div className="flex flex-col gap-2 animate-pulse">
        {Array.from({ length: 3 }).map((_, i) => (
          <div key={i} className="h-8 bg-bg-elevated rounded" />
        ))}
      </div>
    );
  }

  if (alerts.length === 0) {
    return <p className="text-xs text-t3 py-2">활성 알림이 없습니다.</p>;
  }

  return (
    <div className="flex flex-col gap-1.5">
      {alerts.map((alert) => (
        <div
          key={alert.id}
          className={`flex items-start gap-2 px-3 py-2 rounded border text-xs ${getAlertStyle(alert.level)}`}
        >
          <span className="font-semibold shrink-0">[{alert.level}]</span>
          <span className="flex-1">{alert.message}</span>
          <span className="shrink-0 opacity-70 font-mono">{alert.timestamp}</span>
        </div>
      ))}
    </div>
  );
}

// ─── 메인 패널 ───────────────────────────────────────────────────────────────────

export default function RndKospsPanel() {
  const [pipeline, setPipeline] = useState<PipelineNode[]>([]);
  const [logs, setLogs] = useState<DataLogRow[]>([]);
  const [alerts, setAlerts] = useState<AlertItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [lastUpdate, setLastUpdate] = useState<Date | null>(null);

  // 필터
  const [filterSource, setFilterSource] = useState<FilterSource>('all');
  const [filterReceive, setFilterReceive] = useState<FilterReceive>('all');
  const [filterPeriod, setFilterPeriod] = useState<FilterPeriod>('24h');

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const data = await fetchKospsData();
      setPipeline(data.pipeline);
      setLogs(data.logs);
      setAlerts(data.alerts);
      setLastUpdate(new Date());
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    let isMounted = true;
    void Promise.resolve().then(() => {
      if (isMounted) void fetchData();
    });
    return () => {
      isMounted = false;
    };
  }, [fetchData]);

  const filteredLogs = filterLogs(logs, filterSource, filterReceive, filterPeriod);

  const totalReceived = logs.filter((r) => r.receiveStatus === '수신완료').length;
  const totalDelayed = logs.filter((r) => r.receiveStatus === '수신대기').length;
  const totalFailed = logs.filter(
    (r) => r.receiveStatus === '수신실패' || r.receiveStatus === '시간초과',
  ).length;

  return (
    <div className="flex flex-col h-full overflow-hidden">
      {/* ── 헤더 ── */}
      <div className="shrink-0 border-b border-stroke-1">
        <div className="flex items-center justify-between px-5 py-3">
          <h2 className="text-sm font-semibold text-t1">유출유확산예측 (KOSPS) 연계 모니터링</h2>
          <div className="flex items-center gap-3">
            {lastUpdate && (
              <span className="text-xs text-t3">
                갱신:{' '}
                {lastUpdate.toLocaleTimeString('ko-KR', {
                  hour: '2-digit',
                  minute: '2-digit',
                  second: '2-digit',
                })}
              </span>
            )}
            <button
              onClick={() => void fetchData()}
              disabled={loading}
              className="flex items-center gap-1.5 px-3 py-1.5 text-xs rounded bg-bg-elevated hover:bg-bg-card text-t2 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              <svg
                className={`w-3.5 h-3.5 ${loading ? 'animate-spin' : ''}`}
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
                />
              </svg>
              새로고침
            </button>
          </div>
        </div>
        {/* 요약 통계 바 */}
        <div className="flex items-center gap-4 px-5 py-2 bg-bg-base text-xs text-t3 border-t border-stroke-1">
          <span>
            정상 수신:{' '}
            <span className="text-emerald-400 font-medium">{totalReceived}건</span>
          </span>
          <span className="text-stroke-1">|</span>
          <span>
            지연: <span className="text-yellow-400 font-medium">{totalDelayed}건</span>
          </span>
          <span className="text-stroke-1">|</span>
          <span>
            실패: <span className="text-red-400 font-medium">{totalFailed}건</span>
          </span>
          <span className="text-stroke-1">|</span>
          <span>
            금일 예측 완료:{' '}
            <span className="text-cyan-400 font-medium">3 / 6회</span>
          </span>
        </div>
      </div>

      {/* ── 스크롤 영역 ── */}
      <div className="flex-1 overflow-auto">
        {/* 파이프라인 현황 */}
        <section className="px-5 pt-4 pb-3 border-b border-stroke-1">
          <h3 className="text-xs font-semibold text-t2 mb-3 uppercase tracking-wide">
            데이터 파이프라인 현황
          </h3>
          <PipelineFlow nodes={pipeline} loading={loading} />
        </section>

        {/* 필터 바 + 수신 이력 테이블 */}
        <section className="px-5 pt-4 pb-3 border-b border-stroke-1">
          <div className="flex items-center justify-between mb-3 gap-3 flex-wrap">
            <h3 className="text-xs font-semibold text-t2 uppercase tracking-wide shrink-0">
              데이터 수신 이력
            </h3>
            <div className="flex items-center gap-2 flex-wrap">
              {/* 데이터소스 필터 */}
              <select
                value={filterSource}
                onChange={(e) => setFilterSource(e.target.value as FilterSource)}
                className="px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t2 focus:outline-none focus:border-cyan-500 transition-colors"
              >
                <option value="all">모두 (소스)</option>
                <option value="HYCOM">HYCOM</option>
                <option value="기상청">기상청</option>
                <option value="KOSPS DLL">KOSPS DLL</option>
              </select>
              {/* 수신상태 필터 */}
              <select
                value={filterReceive}
                onChange={(e) => setFilterReceive(e.target.value as FilterReceive)}
                className="px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t2 focus:outline-none focus:border-cyan-500 transition-colors"
              >
                <option value="all">모두 (상태)</option>
                <option value="수신완료">수신완료</option>
                <option value="수신대기">수신대기</option>
                <option value="수신실패">수신실패</option>
                <option value="시간초과">시간초과</option>
              </select>
              {/* 기간 필터 */}
              <select
                value={filterPeriod}
                onChange={(e) => setFilterPeriod(e.target.value as FilterPeriod)}
                className="px-2 py-1 text-xs rounded bg-bg-elevated border border-stroke-1 text-t2 focus:outline-none focus:border-cyan-500 transition-colors"
              >
                <option value="6h">최근 6시간</option>
                <option value="12h">최근 12시간</option>
                <option value="24h">최근 24시간</option>
              </select>
              <span className="text-xs text-t3">{filteredLogs.length}건</span>
            </div>
          </div>
          <DataLogTable rows={filteredLogs} loading={loading} />
        </section>

        {/* 알림 현황 */}
        <section className="px-5 pt-4 pb-5">
          <h3 className="text-xs font-semibold text-t2 uppercase tracking-wide mb-3">
            알림 현황
          </h3>
          <AlertList alerts={alerts} loading={loading} />
        </section>
      </div>
    </div>
  );
}
