import { useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { Card, CardContent, CardHeader, CardTitle } from '@shared/components/ui/card';
import { Badge } from '@shared/components/ui/badge';
import { Button } from '@shared/components/ui/button';
import { TabBar, TabButton } from '@shared/components/ui/tabs';
import { PageContainer, PageHeader } from '@shared/components/layout';
import { DataTable, type DataColumn } from '@shared/components/common/DataTable';
import { SaveButton } from '@shared/components/common/SaveButton';
import { getConnectionStatusHex } from '@shared/constants/connectionStatuses';
import type { BadgeIntent } from '@lib/theme/variants';

/** 수집/적재 작업 상태 → BadgeIntent 매핑 (DataHub 로컬 전용) */
function jobStatusIntent(s: string): BadgeIntent {
  if (s === '수행중') return 'success';
  if (s === '대기중') return 'warning';
  if (s === '장애발생') return 'critical';
  return 'muted';
}
import {
  Database, RefreshCw, Calendar, Wifi, WifiOff, Radio,
  Activity, Server, ArrowDownToLine, Clock, AlertTriangle,
  CheckCircle, XCircle, BarChart3, Layers, Plus, Play, Square,
  Trash2, Edit2, Eye, FileText, HardDrive, Upload, FolderOpen,
  Network, X, ChevronRight, Info,
} from 'lucide-react';

/*
 * SFR-03: 통합데이터 허브 수집·연계 관리
 * ① 선박신호 수신 현황 — 24시간 타임라인 히트맵
 * ② 선박위치정보 모니터링 — 연계 채널 테이블
 */

// ─── ① 선박신호 수신 현황 데이터 ──────────────

type SignalStatus = 'ok' | 'warn' | 'error';

interface SignalSource {
  name: string;
  rate: number; // 수신율 %
  timeline: SignalStatus[]; // 24시간 × 6 (10분 단위 = 144 슬롯)
}

function generateTimeline(): SignalStatus[] {
  return Array.from({ length: 144 }, () => {
    const r = Math.random();
    return r < 0.75 ? 'ok' : r < 0.90 ? 'warn' : 'error';
  });
}

const SIGNAL_SOURCES: SignalSource[] = [
  { name: 'VTS', rate: 88.9, timeline: generateTimeline() },
  { name: 'VTS-AIS', rate: 85.4, timeline: generateTimeline() },
  { name: 'V-PASS', rate: 84.0, timeline: generateTimeline() },
  { name: 'E-NAVI', rate: 88.9, timeline: generateTimeline() },
  { name: 'S&P AIS', rate: 85.4, timeline: generateTimeline() },
];

// SIGNAL_COLORS는 connectionStatuses 카탈로그에서 가져옴 (getConnectionStatusHex)

const HOURS = Array.from({ length: 25 }, (_, i) => `${String(i).padStart(2, '0')}시`);

// ─── ② 선박위치정보 모니터링 데이터 ──────────────

interface ChannelRecord {
  no: number;
  source: string;       // 원천기관
  code: string;         // 기관코드
  system: string;       // 정보시스템명
  linkInfo: string;     // 연계정보
  storage: string;      // 저장장소
  linkMethod: string;   // 연계방식
  cycle: string;        // 수집주기
  vesselCount: string;  // 선박건수/신호건수
  status: 'ON' | 'OFF'; // 연결상태
  lastUpdate: string;   // 최종갱신
  [key: string]: unknown;
}

const CHANNELS: ChannelRecord[] = [
  { no: 1, source: '부산항', code: 'BS', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '439 / 499', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 2, source: '부산항', code: 'BS', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '133 / 463', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 3, source: '부산신항', code: 'BSN', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '255 / 278', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 4, source: '부산신항', code: 'BSN', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '133 / 426', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 5, source: '동해안', code: 'DH', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '수신대기중', vesselCount: '0', status: 'OFF', lastUpdate: '' },
  { no: 6, source: '동해안', code: 'DH', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '수신대기중', vesselCount: '0', status: 'OFF', lastUpdate: '' },
  { no: 7, source: '대산항', code: 'DS', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '0', status: 'OFF', lastUpdate: '2026-03-15 15:38:57' },
  { no: 8, source: '대산항', code: 'DS', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '0', status: 'OFF', lastUpdate: '2026-03-15 15:38:56' },
  { no: 9, source: '경인항', code: 'GI', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '120 / 136', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 10, source: '경인항', code: 'GI', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '55 / 467', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 11, source: '경인연안', code: 'GIC', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '180 / 216', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 12, source: '경인연안', code: 'GIC', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '수신대기중', vesselCount: '0', status: 'OFF', lastUpdate: '' },
  { no: 13, source: '군산항', code: 'GS', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '수신대기중', vesselCount: '0', status: 'OFF', lastUpdate: '' },
  { no: 14, source: '군산항', code: 'GS', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '수신대기중', vesselCount: '0', status: 'OFF', lastUpdate: '' },
  { no: 15, source: '인천항', code: 'IC', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '149 / 176', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 16, source: '인천항', code: 'IC', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '55 / 503', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 17, source: '진도연안', code: 'JDC', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '433 / 524', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 18, source: '진도연안', code: 'JDC', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '256 / 1619', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 19, source: '제주항', code: 'JJ', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '429 / 508', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 20, source: '제주항', code: 'JJ', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '00:00:00', vesselCount: '160 / 1592', status: 'ON', lastUpdate: '2026-03-25 10:29:09' },
  { no: 21, source: '목포항', code: 'MP', system: 'VTS_AIS', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '수신대기중', vesselCount: '0', status: 'OFF', lastUpdate: '' },
  { no: 22, source: '목포항', code: 'MP', system: 'VTS_RT', linkInfo: 'VTS', storage: 'signal_t_dynamic_all_reply', linkMethod: 'KAFKA', cycle: '수신대기중', vesselCount: '0', status: 'OFF', lastUpdate: '' },
];

// ─── 채널 테이블 컬럼 정의 ───────────────────

const channelColumns: DataColumn<ChannelRecord>[] = [
  { key: 'no', label: '번호', width: '50px', align: 'center', sortable: true,
    render: (v) => <span className="text-hint">{v as number}</span>,
  },
  { key: 'source', label: '원천기관', width: '80px', sortable: true,
    render: (v) => <span className="text-label">{v as string}</span>,
  },
  { key: 'code', label: '기관코드', width: '65px', align: 'center',
    render: (v) => <span className="text-hint font-mono">{v as string}</span>,
  },
  { key: 'system', label: '정보시스템명', width: '100px', sortable: true,
    render: (v) => <span className="text-cyan-400 font-medium">{v as string}</span>,
  },
  { key: 'linkInfo', label: '연계정보', width: '65px' },
  { key: 'storage', label: '저장장소', render: (v) => <span className="text-hint font-mono text-[9px]">{v as string}</span> },
  { key: 'linkMethod', label: '연계방식', width: '70px', align: 'center',
    render: (v) => <Badge intent="purple" size="sm">{v as string}</Badge>,
  },
  { key: 'cycle', label: '수집주기', width: '80px', align: 'center',
    render: (v) => {
      const s = v as string;
      return s === '수신대기중'
        ? <span className="text-orange-400 text-[9px]">{s}</span>
        : <span className="text-muted-foreground font-mono text-[10px]">{s}</span>;
    },
  },
  { key: 'vesselCount', label: '선박건수/신호건수', width: '120px', align: 'right', sortable: true,
    render: (v) => <span className="text-heading font-mono">{v as string}</span>,
  },
  { key: 'status', label: '연결상태', width: '80px', align: 'center', sortable: true,
    render: (v, row) => {
      const on = v === 'ON';
      return (
        <div className="flex flex-col items-center gap-0.5">
          <Badge intent={on ? 'info' : 'critical'} size="xs">
            {v as string}
          </Badge>
          {row.lastUpdate && (
            <span className="text-[8px] text-hint">{row.lastUpdate as string}</span>
          )}
        </div>
      );
    },
  },
];

// ─── 히트맵 컴포넌트 ──────────────────────

function SignalTimeline({ source }: { source: SignalSource }) {
  return (
    <div className="flex items-center gap-3">
      {/* 라벨 */}
      <div className="w-16 shrink-0 text-right">
        <div className="text-[11px] font-bold" style={{
          color: source.name === 'VTS' ? '#22c55e'
            : source.name === 'VTS-AIS' ? '#3b82f6'
            : source.name === 'V-PASS' ? '#a855f7'
            : source.name === 'E-NAVI' ? '#ef4444'
            : '#eab308',
        }}>{source.name}</div>
        <div className="text-[10px] text-hint">{source.rate}%</div>
      </div>
      {/* 타임라인 바 */}
      <div className="flex-1 flex gap-px">
        {source.timeline.map((status, i) => (
          <div
            key={i}
            className="flex-1 h-5 rounded-[1px]"
            style={{ backgroundColor: getConnectionStatusHex(status), minWidth: '2px' }}
            title={`${String(Math.floor(i / 6)).padStart(2, '0')}:${String((i % 6) * 10).padStart(2, '0')} — ${status === 'ok' ? '정상' : status === 'warn' ? '지연' : '장애'}`}
          />
        ))}
      </div>
    </div>
  );
}

// ─── ③ 수집 작업 관리 데이터 ──────────────────

type JobStatus = '정지' | '대기중' | '수행중' | '장애발생';
type ServerType = 'SQL' | 'FILE' | 'FTP';

interface CollectJob {
  id: string;
  name: string;
  serverType: ServerType;
  serverName: string;
  serverIp: string;
  status: JobStatus;
  schedule: string;
  lastRun: string;
  successRate: number;
  [key: string]: unknown;
}

const COLLECT_JOBS: CollectJob[] = [
  { id: 'COL-001', name: '부산항 AIS 수집', serverType: 'SQL', serverName: 'vts-bs-db01', serverIp: '10.20.30.11', status: '수행중', schedule: '매 10분', lastRun: '2026-04-03 09:20:00', successRate: 98.5 },
  { id: 'COL-002', name: '인천항 VTS 수집', serverType: 'SQL', serverName: 'vts-ic-db01', serverIp: '10.20.30.12', status: '수행중', schedule: '매 10분', lastRun: '2026-04-03 09:20:00', successRate: 97.2 },
  { id: 'COL-003', name: 'V-PASS 파일 수집', serverType: 'FILE', serverName: 'vpass-ftp01', serverIp: '10.20.31.20', status: '수행중', schedule: '매 30분', lastRun: '2026-04-03 09:00:00', successRate: 94.1 },
  { id: 'COL-004', name: 'E-NAVI 로그 수집', serverType: 'FILE', serverName: 'enavi-nas01', serverIp: '10.20.31.30', status: '대기중', schedule: '매 1시간', lastRun: '2026-04-03 08:00:00', successRate: 91.8 },
  { id: 'COL-005', name: 'S&P AIS 해외 수집', serverType: 'FTP', serverName: 'sp-ais-ftp', serverIp: '203.45.67.89', status: '수행중', schedule: '매 15분', lastRun: '2026-04-03 09:15:00', successRate: 85.4 },
  { id: 'COL-006', name: '동해안 VTS 수집', serverType: 'SQL', serverName: 'vts-dh-db01', serverIp: '10.20.30.15', status: '장애발생', schedule: '매 10분', lastRun: '2026-04-02 22:10:00', successRate: 0 },
  { id: 'COL-007', name: '군산항 레이더 수집', serverType: 'SQL', serverName: 'vts-gs-db01', serverIp: '10.20.30.18', status: '장애발생', schedule: '매 10분', lastRun: '2026-04-01 14:30:00', successRate: 0 },
  { id: 'COL-008', name: '제주항 CCTV 수집', serverType: 'FTP', serverName: 'jj-cctv-ftp', serverIp: '10.20.32.50', status: '정지', schedule: '매 1시간', lastRun: '2026-03-28 12:00:00', successRate: 0 },
  { id: 'COL-009', name: '위성 SAR 수집', serverType: 'FTP', serverName: 'sat-sar-ftp', serverIp: '10.20.40.10', status: '수행중', schedule: '매 6시간', lastRun: '2026-04-03 06:00:00', successRate: 99.0 },
  { id: 'COL-010', name: '해수부 VMS 연동', serverType: 'SQL', serverName: 'mof-vms-db', serverIp: '10.20.50.11', status: '수행중', schedule: '매 5분', lastRun: '2026-04-03 09:20:00', successRate: 96.3 },
];

const collectColumns: DataColumn<CollectJob>[] = [
  { key: 'id', label: 'ID', width: '80px', render: (v) => <span className="text-hint font-mono text-[10px]">{v as string}</span> },
  { key: 'name', label: '작업명', sortable: true, render: (v) => <span className="text-heading font-medium">{v as string}</span> },
  { key: 'serverType', label: '타입', width: '60px', align: 'center', sortable: true,
    render: (v) => {
      const t = v as string;
      const intent: BadgeIntent = t === 'SQL' ? 'info' : t === 'FILE' ? 'success' : 'purple';
      return <Badge intent={intent} size="xs">{t}</Badge>;
    },
  },
  { key: 'serverName', label: '서버명', width: '120px', render: (v) => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'serverIp', label: 'IP', width: '120px', render: (v) => <span className="text-hint font-mono text-[10px]">{v as string}</span> },
  { key: 'status', label: '상태', width: '80px', align: 'center', sortable: true,
    render: (v) => <Badge intent={jobStatusIntent(v as string)} size="xs">{v as string}</Badge>,
  },
  { key: 'schedule', label: '스케줄', width: '80px' },
  { key: 'lastRun', label: '최종 수행', width: '140px', sortable: true, render: (v) => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'successRate', label: '성공률', width: '70px', align: 'right', sortable: true,
    render: (v) => {
      const n = v as number;
      const c = n >= 90 ? 'text-green-400' : n >= 70 ? 'text-yellow-400' : n > 0 ? 'text-red-400' : 'text-hint';
      return <span className={`font-bold text-[11px] ${c}`}>{n > 0 ? `${n}%` : '-'}</span>;
    },
  },
  { key: 'id', label: '', width: '70px', align: 'center', sortable: false,
    render: (_v, row) => (
      <div className="flex items-center gap-0.5">
        {row.status === '정지' ? (
          <button type="button" className="p-1 text-hint hover:text-green-400" title="시작"><Play className="w-3 h-3" /></button>
        ) : row.status !== '장애발생' ? (
          <button type="button" className="p-1 text-hint hover:text-orange-400" title="정지"><Square className="w-3 h-3" /></button>
        ) : null}
        <button type="button" className="p-1 text-hint hover:text-blue-400" title="편집"><Edit2 className="w-3 h-3" /></button>
        <button type="button" className="p-1 text-hint hover:text-cyan-400" title="이력"><FileText className="w-3 h-3" /></button>
      </div>
    ),
  },
];

// ─── ④ 적재 작업 관리 데이터 ──────────────────

interface LoadJob {
  id: string;
  name: string;
  sourceJob: string;
  targetTable: string;
  targetDb: string;
  status: JobStatus;
  schedule: string;
  lastRun: string;
  recordCount: string;
  [key: string]: unknown;
}

const LOAD_JOBS: LoadJob[] = [
  { id: 'LOD-001', name: 'AIS 동적정보 적재', sourceJob: 'COL-001', targetTable: 'tb_ais_dynamic', targetDb: 'MDA_DB', status: '수행중', schedule: '매 10분', lastRun: '2026-04-03 09:20:00', recordCount: '12,450' },
  { id: 'LOD-002', name: 'VTS 레이더 적재', sourceJob: 'COL-002', targetTable: 'tb_vts_radar', targetDb: 'MDA_DB', status: '수행중', schedule: '매 10분', lastRun: '2026-04-03 09:20:00', recordCount: '8,320' },
  { id: 'LOD-003', name: 'V-PASS 위치 적재', sourceJob: 'COL-003', targetTable: 'tb_vpass_position', targetDb: 'MDA_DB', status: '수행중', schedule: '매 30분', lastRun: '2026-04-03 09:00:00', recordCount: '3,210' },
  { id: 'LOD-004', name: 'VMS 데이터 적재', sourceJob: 'COL-010', targetTable: 'tb_vms_track', targetDb: 'MDA_DB', status: '수행중', schedule: '매 5분', lastRun: '2026-04-03 09:20:00', recordCount: '5,677' },
  { id: 'LOD-005', name: 'SAR 위성 적재', sourceJob: 'COL-009', targetTable: 'tb_sat_imagery', targetDb: 'SAT_DB', status: '대기중', schedule: '매 6시간', lastRun: '2026-04-03 06:00:00', recordCount: '24' },
  { id: 'LOD-006', name: '해외 AIS 적재', sourceJob: 'COL-005', targetTable: 'tb_sais_global', targetDb: 'MDA_DB', status: '수행중', schedule: '매 15분', lastRun: '2026-04-03 09:15:00', recordCount: '45,200' },
  { id: 'LOD-007', name: '동해안 VTS 적재', sourceJob: 'COL-006', targetTable: 'tb_vts_dh', targetDb: 'MDA_DB', status: '장애발생', schedule: '매 10분', lastRun: '2026-04-02 22:10:00', recordCount: '0' },
];

const loadColumns: DataColumn<LoadJob>[] = [
  { key: 'id', label: 'ID', width: '80px', render: (v) => <span className="text-hint font-mono text-[10px]">{v as string}</span> },
  { key: 'name', label: '작업명', sortable: true, render: (v) => <span className="text-heading font-medium">{v as string}</span> },
  { key: 'sourceJob', label: '수집원', width: '80px', render: (v) => <Badge intent="cyan" size="sm">{v as string}</Badge> },
  { key: 'targetTable', label: '대상 테이블', width: '140px', render: (v) => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'targetDb', label: 'DB', width: '70px', align: 'center' },
  { key: 'status', label: '상태', width: '80px', align: 'center', sortable: true,
    render: (v) => <Badge intent={jobStatusIntent(v as string)} size="xs">{v as string}</Badge>,
  },
  { key: 'schedule', label: '스케줄', width: '80px' },
  { key: 'lastRun', label: '최종 적재', width: '140px', sortable: true, render: (v) => <span className="text-muted-foreground font-mono text-[10px]">{v as string}</span> },
  { key: 'recordCount', label: '적재건수', width: '80px', align: 'right', render: (v) => <span className="text-heading font-bold">{v as string}</span> },
  { key: 'id', label: '', width: '70px', align: 'center', sortable: false,
    render: () => (
      <div className="flex items-center gap-0.5">
        <button type="button" className="p-1 text-hint hover:text-blue-400" title="편집"><Edit2 className="w-3 h-3" /></button>
        <button type="button" className="p-1 text-hint hover:text-cyan-400" title="이력"><FileText className="w-3 h-3" /></button>
        <button type="button" className="p-1 text-hint hover:text-orange-400" title="스토리지"><HardDrive className="w-3 h-3" /></button>
      </div>
    ),
  },
];

// ─── ⑤ 연계서버 모니터링 데이터 ────────────────

type AgentRole = '수집' | '적재';

interface AgentServer {
  id: string;
  name: string;
  role: AgentRole;
  hostname: string;
  ip: string;
  port: string;
  mac: string;
  status: JobStatus;
  taskCount: number;
  cpuUsage: number;
  memUsage: number;
  diskUsage: number;
  lastHeartbeat: string;
  [key: string]: unknown;
}

const AGENTS: AgentServer[] = [
  { id: 'AGT-1001', name: '부산항 AIS 수집Agent', role: '수집', hostname: 'vts-bs-col01', ip: '10.20.30.11', port: '8081', mac: '00:1A:2B:3C:4D:01', status: '수행중', taskCount: 3, cpuUsage: 42, memUsage: 65, diskUsage: 38, lastHeartbeat: '2026-04-03 09:20:05' },
  { id: 'AGT-1002', name: '인천항 VTS 수집Agent', role: '수집', hostname: 'vts-ic-col01', ip: '10.20.30.12', port: '8081', mac: '00:1A:2B:3C:4D:02', status: '수행중', taskCount: 2, cpuUsage: 35, memUsage: 52, diskUsage: 41, lastHeartbeat: '2026-04-03 09:20:03' },
  { id: 'AGT-1003', name: '제주항 수집Agent', role: '수집', hostname: 'vts-jj-col01', ip: '10.20.30.19', port: '8081', mac: '00:1A:2B:3C:4D:03', status: '수행중', taskCount: 2, cpuUsage: 28, memUsage: 45, diskUsage: 55, lastHeartbeat: '2026-04-03 09:20:02' },
  { id: 'AGT-1004', name: '동해안 수집Agent', role: '수집', hostname: 'vts-dh-col01', ip: '10.20.30.15', port: '8081', mac: '00:1A:2B:3C:4D:04', status: '장애발생', taskCount: 0, cpuUsage: 0, memUsage: 0, diskUsage: 72, lastHeartbeat: '2026-04-02 22:10:15' },
  { id: 'AGT-1005', name: 'V-PASS 수집Agent', role: '수집', hostname: 'vpass-col01', ip: '10.20.31.20', port: '8082', mac: '00:1A:2B:3C:4D:05', status: '수행중', taskCount: 1, cpuUsage: 18, memUsage: 30, diskUsage: 25, lastHeartbeat: '2026-04-03 09:20:01' },
  { id: 'AGT-2001', name: 'MDA DB 적재Agent', role: '적재', hostname: 'mda-lod01', ip: '10.20.40.11', port: '9091', mac: '00:1A:2B:3C:4D:11', status: '수행중', taskCount: 5, cpuUsage: 55, memUsage: 72, diskUsage: 48, lastHeartbeat: '2026-04-03 09:20:04' },
  { id: 'AGT-2002', name: 'SAT DB 적재Agent', role: '적재', hostname: 'sat-lod01', ip: '10.20.40.12', port: '9091', mac: '00:1A:2B:3C:4D:12', status: '대기중', taskCount: 1, cpuUsage: 5, memUsage: 22, diskUsage: 33, lastHeartbeat: '2026-04-03 09:20:00' },
  { id: 'AGT-2003', name: '백업 적재Agent', role: '적재', hostname: 'bak-lod01', ip: '10.20.40.13', port: '9091', mac: '00:1A:2B:3C:4D:13', status: '정지', taskCount: 0, cpuUsage: 0, memUsage: 12, diskUsage: 15, lastHeartbeat: '2026-03-30 18:00:00' },
];

function UsageBar({ value, color }: { value: number; color: string }) {
  return (
    <div className="flex items-center gap-1.5">
      <div className="w-14 h-1.5 bg-switch-background/60 rounded-full overflow-hidden">
        <div className={`h-full rounded-full ${color}`} style={{ width: `${value}%` }} />
      </div>
      <span className="text-[9px] text-muted-foreground w-7 text-right">{value}%</span>
    </div>
  );
}

// ─── 메인 컴포넌트 ──────────────────────

type Tab = 'signal' | 'monitor' | 'collect' | 'load' | 'agents';

export function DataHub() {
  const { t } = useTranslation('admin');
  const [tab, setTab] = useState<Tab>('signal');
  const [selectedDate, setSelectedDate] = useState('2026-04-02');
  const [statusFilter, setStatusFilter] = useState<'' | 'ON' | 'OFF'>('');

  // 수집 작업 필터
  const [collectTypeFilter, setCollectTypeFilter] = useState<'' | ServerType>('');
  const [collectStatusFilter, setCollectStatusFilter] = useState<'' | JobStatus>('');
  // 적재 작업 필터
  const [loadStatusFilter, setLoadStatusFilter] = useState<'' | JobStatus>('');
  // 연계서버 필터
  const [agentRoleFilter, setAgentRoleFilter] = useState<'' | AgentRole>('');
  const [agentStatusFilter, setAgentStatusFilter] = useState<'' | JobStatus>('');

  const onCount = CHANNELS.filter((c) => c.status === 'ON').length;
  const offCount = CHANNELS.filter((c) => c.status === 'OFF').length;
  const hasPartialOff = offCount > 0;

  const filteredChannels = statusFilter
    ? CHANNELS.filter((c) => c.status === statusFilter)
    : CHANNELS;

  const filteredCollectJobs = COLLECT_JOBS.filter((j) =>
    (!collectTypeFilter || j.serverType === collectTypeFilter) &&
    (!collectStatusFilter || j.status === collectStatusFilter)
  );

  const filteredLoadJobs = LOAD_JOBS.filter((j) =>
    (!loadStatusFilter || j.status === loadStatusFilter)
  );

  const filteredAgents = AGENTS.filter((a) =>
    (!agentRoleFilter || a.role === agentRoleFilter) &&
    (!agentStatusFilter || a.status === agentStatusFilter)
  );

  return (
    <PageContainer>
      <PageHeader
        icon={Database}
        iconColor="text-cyan-400"
        title={t('dataHub.title')}
        description={t('dataHub.desc')}
        demo
        actions={
          <Button variant="secondary" size="sm" icon={<RefreshCw className="w-3 h-3" />}>
            새로고침
          </Button>
        }
      />

      {/* KPI */}
      <div className="flex gap-2">
        {[
          { label: '전체 채널', value: CHANNELS.length, icon: Layers, color: 'text-label', bg: 'bg-muted' },
          { label: 'ON', value: onCount, icon: Wifi, color: 'text-blue-400', bg: 'bg-blue-500/10' },
          { label: 'OFF', value: offCount, icon: WifiOff, color: 'text-red-400', bg: 'bg-red-500/10' },
          { label: '평균 수신율', value: '86.5%', icon: BarChart3, color: 'text-green-400', bg: 'bg-green-500/10' },
          { label: '데이터 소스', value: '5종', icon: Radio, color: 'text-purple-400', bg: 'bg-purple-500/10' },
          { label: '연계 방식', value: 'KAFKA', icon: Server, color: 'text-orange-400', bg: 'bg-orange-500/10' },
        ].map((kpi) => (
          <div key={kpi.label} className="flex-1 flex items-center gap-2 px-3 py-2 rounded-xl border border-border bg-card">
            <div className={`p-1.5 rounded-lg ${kpi.bg}`}>
              <kpi.icon className={`w-3.5 h-3.5 ${kpi.color}`} />
            </div>
            <span className={`text-base font-bold ${kpi.color}`}>{kpi.value}</span>
            <span className="text-[9px] text-hint">{kpi.label}</span>
          </div>
        ))}
      </div>

      {/* 탭 */}
      <TabBar variant="pill">
        {[
          { key: 'signal' as Tab, icon: Activity, label: '선박신호 수신 현황' },
          { key: 'monitor' as Tab, icon: Server, label: '선박위치정보 모니터링' },
          { key: 'collect' as Tab, icon: ArrowDownToLine, label: '수집 작업 관리' },
          { key: 'load' as Tab, icon: HardDrive, label: '적재 작업 관리' },
          { key: 'agents' as Tab, icon: Network, label: '연계서버 모니터링' },
        ].map((t) => (
          <TabButton
            key={t.key}
            variant="pill"
            active={tab === t.key}
            onClick={() => setTab(t.key)}
            icon={<t.icon className="w-3.5 h-3.5" />}
          >
            {t.label}
          </TabButton>
        ))}
      </TabBar>

      {/* ── ① 선박신호 수신 현황 ── */}
      {tab === 'signal' && (
        <Card>
          <CardContent className="p-4">
            {/* 상단: 제목 + 날짜 */}
            <div className="flex items-center justify-between mb-4">
              <div className="text-sm font-bold text-heading">선박신호 수신 현황</div>
              <div className="flex items-center gap-2">
                <div className="relative">
                  <input
                    aria-label="수신 현황 기준일"
                    type="date"
                    value={selectedDate}
                    onChange={(e) => setSelectedDate(e.target.value)}
                    className="bg-surface-overlay border border-slate-700/50 rounded-lg px-3 py-1.5 text-[11px] text-heading focus:outline-none focus:border-cyan-500/50"
                  />
                </div>
                <Button variant="secondary" size="sm" icon={<RefreshCw className="w-3 h-3" />}>
                  새로고침
                </Button>
              </div>
            </div>

            {/* 시간축 헤더 */}
            <div className="flex items-center gap-3 mb-2">
              <div className="w-16 shrink-0" />
              <div className="flex-1 flex">
                {HOURS.map((h, i) => (
                  <div key={i} className="flex-1 text-center text-[8px] text-hint" style={{ minWidth: 0 }}>
                    {i % 2 === 0 ? h : ''}
                  </div>
                ))}
              </div>
            </div>

            {/* 타임라인 히트맵 */}
            <div className="space-y-2">
              {SIGNAL_SOURCES.map((src) => (
                <SignalTimeline key={src.name} source={src} />
              ))}
            </div>

            {/* 범례 */}
            <div className="flex items-center gap-4 mt-4 pt-3 border-t border-border">
              <div className="text-[9px] text-hint">범례:</div>
              {[
                { label: '정상 수신', color: '#22c55e' },
                { label: '지연/경고', color: '#eab308' },
                { label: '장애/미수신', color: '#ef4444' },
              ].map((item) => (
                <div key={item.label} className="flex items-center gap-1.5">
                  <div className="w-3 h-3 rounded-sm" style={{ backgroundColor: item.color }} />
                  <span className="text-[9px] text-muted-foreground">{item.label}</span>
                </div>
              ))}
              <div className="ml-auto text-[9px] text-hint">
                10분 단위 집계 · 24시간 (144 슬롯)
              </div>
            </div>
          </CardContent>
        </Card>
      )}

      {/* ── ② 선박위치정보 모니터링 ── */}
      {tab === 'monitor' && (
        <div className="space-y-3">
          {/* 상태 요약 바 */}
          <div className="flex items-center gap-3 px-4 py-2 rounded-xl border border-border bg-card">
            <div className="flex items-center gap-1.5">
              {hasPartialOff ? (
                <AlertTriangle className="w-3.5 h-3.5 text-orange-400" />
              ) : (
                <CheckCircle className="w-3.5 h-3.5 text-green-400" />
              )}
              <span className={`text-[11px] font-bold ${hasPartialOff ? 'text-orange-400' : 'text-green-400'}`}>
                {hasPartialOff ? `일부 OFF (${offCount}/${CHANNELS.length})` : '전체 정상'}
              </span>
            </div>
            <span className="text-[10px] text-hint">
              연계 채널 {CHANNELS.length}개 (ON: {onCount} / OFF: {offCount})
            </span>
            <span className="text-[10px] text-hint ml-1">
              갱신: 오후 06:57:33
            </span>

            {/* 상태 필터 */}
            <div className="ml-auto flex items-center gap-1">
              {(['', 'ON', 'OFF'] as const).map((f) => (
                <TabButton
                  key={f}
                  variant="pill"
                  active={statusFilter === f}
                  onClick={() => setStatusFilter(f)}
                  className="px-2.5 py-1 text-[10px]"
                >
                  {f || '전체'}
                </TabButton>
              ))}
            </div>
          </div>

          {/* DataTable */}
          <DataTable
            data={filteredChannels}
            columns={channelColumns}
            pageSize={12}
            searchPlaceholder="기관명, 코드, 시스템명 검색..."
            searchKeys={['source', 'code', 'system', 'linkMethod']}
            exportFilename="선박위치정보_모니터링"
          />
        </div>
      )}

      {/* ── ③ 수집 작업 관리 ── */}
      {tab === 'collect' && (
        <div className="space-y-3">
          <div className="flex items-center gap-3 px-4 py-2 rounded-xl border border-border bg-card">
            <span className="text-[10px] text-hint">서버 타입:</span>
            {(['', 'SQL', 'FILE', 'FTP'] as const).map((f) => (
              <TabButton key={f} variant="pill" active={collectTypeFilter === f} onClick={() => setCollectTypeFilter(f)} className="px-2.5 py-1 text-[10px]">
                {f || '전체'}
              </TabButton>
            ))}
            <span className="text-[10px] text-hint ml-3">상태:</span>
            {(['', '수행중', '대기중', '장애발생', '정지'] as const).map((f) => (
              <TabButton key={f} variant="pill" active={collectStatusFilter === f} onClick={() => setCollectStatusFilter(f)} className="px-2.5 py-1 text-[10px]">
                {f || '전체'}
              </TabButton>
            ))}
            <div className="ml-auto">
              <Button variant="primary" size="sm" icon={<Plus className="w-3 h-3" />}>
                작업 등록
              </Button>
            </div>
          </div>
          <DataTable data={filteredCollectJobs} columns={collectColumns} pageSize={10}
            searchPlaceholder="작업명, 서버명, IP 검색..." searchKeys={['name', 'serverName', 'serverIp']} exportFilename="수집작업목록" />
        </div>
      )}

      {/* ── ④ 적재 작업 관리 ── */}
      {tab === 'load' && (
        <div className="space-y-3">
          <div className="flex items-center gap-3 px-4 py-2 rounded-xl border border-border bg-card">
            <span className="text-[10px] text-hint">상태:</span>
            {(['', '수행중', '대기중', '장애발생', '정지'] as const).map((f) => (
              <TabButton key={f} variant="pill" active={loadStatusFilter === f} onClick={() => setLoadStatusFilter(f)} className="px-2.5 py-1 text-[10px]">
                {f || '전체'}
              </TabButton>
            ))}
            <div className="ml-auto flex items-center gap-2">
              <Button variant="secondary" size="sm" icon={<FolderOpen className="w-3 h-3" />}>
                스토리지 관리
              </Button>
              <Button variant="primary" size="sm" icon={<Plus className="w-3 h-3" />}>
                작업 등록
              </Button>
            </div>
          </div>
          <DataTable data={filteredLoadJobs} columns={loadColumns} pageSize={10}
            searchPlaceholder="작업명, 테이블명, DB 검색..." searchKeys={['name', 'targetTable', 'targetDb', 'sourceJob']} exportFilename="적재작업목록" />
        </div>
      )}

      {/* ── ⑤ 연계서버 모니터링 ── */}
      {tab === 'agents' && (
        <div className="space-y-3">
          <div className="flex items-center gap-3 px-4 py-2 rounded-xl border border-border bg-card">
            <span className="text-[10px] text-hint">종류:</span>
            {(['', '수집', '적재'] as const).map((f) => (
              <TabButton key={f} variant="pill" active={agentRoleFilter === f} onClick={() => setAgentRoleFilter(f)} className="px-2.5 py-1 text-[10px]">
                {f || '전체'}
              </TabButton>
            ))}
            <span className="text-[10px] text-hint ml-3">상태:</span>
            {(['', '수행중', '대기중', '장애발생', '정지'] as const).map((f) => (
              <TabButton key={f} variant="pill" active={agentStatusFilter === f} onClick={() => setAgentStatusFilter(f)} className="px-2.5 py-1 text-[10px]">
                {f || '전체'}
              </TabButton>
            ))}
            <div className="ml-auto">
              <Button variant="secondary" size="sm" icon={<RefreshCw className="w-3 h-3" />}>
                새로고침
              </Button>
            </div>
          </div>

          {/* 연계서버 카드 그리드 */}
          <div className="grid grid-cols-2 gap-3">
            {filteredAgents.map((agent) => {
              return (
                <Card key={agent.id} className="bg-surface-raised border-border">
                  <CardContent className="p-4">
                    <div className="flex items-start justify-between mb-3">
                      <div>
                        <div className="text-[12px] font-bold text-heading">{agent.name}</div>
                        <div className="text-[10px] text-hint">{agent.id} · {agent.role}에이전트</div>
                      </div>
                      <Badge intent={jobStatusIntent(agent.status)} size="xs">{agent.status}</Badge>
                    </div>
                    <div className="grid grid-cols-2 gap-x-4 gap-y-1 text-[10px] mb-3">
                      <div className="flex justify-between"><span className="text-hint">Hostname</span><span className="text-label font-mono">{agent.hostname}</span></div>
                      <div className="flex justify-between"><span className="text-hint">IP</span><span className="text-label font-mono">{agent.ip}</span></div>
                      <div className="flex justify-between"><span className="text-hint">Port</span><span className="text-label font-mono">{agent.port}</span></div>
                      <div className="flex justify-between"><span className="text-hint">MAC</span><span className="text-muted-foreground font-mono text-[9px]">{agent.mac}</span></div>
                    </div>
                    <div className="space-y-1 pt-2 border-t border-border">
                      <div className="flex items-center justify-between"><span className="text-[9px] text-hint w-10">CPU</span><UsageBar value={agent.cpuUsage} color={agent.cpuUsage > 80 ? 'bg-red-500' : agent.cpuUsage > 50 ? 'bg-yellow-500' : 'bg-green-500'} /></div>
                      <div className="flex items-center justify-between"><span className="text-[9px] text-hint w-10">MEM</span><UsageBar value={agent.memUsage} color={agent.memUsage > 80 ? 'bg-red-500' : agent.memUsage > 50 ? 'bg-yellow-500' : 'bg-green-500'} /></div>
                      <div className="flex items-center justify-between"><span className="text-[9px] text-hint w-10">DISK</span><UsageBar value={agent.diskUsage} color={agent.diskUsage > 80 ? 'bg-red-500' : agent.diskUsage > 50 ? 'bg-yellow-500' : 'bg-green-500'} /></div>
                    </div>
                    <div className="flex items-center justify-between mt-3 pt-2 border-t border-border">
                      <span className="text-[9px] text-hint">작업 {agent.taskCount}건 · heartbeat {agent.lastHeartbeat.slice(11)}</span>
                      <div className="flex gap-0.5">
                        <button type="button" className="p-1 text-hint hover:text-blue-400" title="상태 상세"><Eye className="w-3 h-3" /></button>
                        <button type="button" className="p-1 text-hint hover:text-yellow-400" title="이름 변경"><Edit2 className="w-3 h-3" /></button>
                        <button type="button" className="p-1 text-hint hover:text-red-400" title="삭제"><Trash2 className="w-3 h-3" /></button>
                      </div>
                    </div>
                  </CardContent>
                </Card>
              );
            })}
          </div>
        </div>
      )}
    </PageContainer>
  );
}
