import { useState, useEffect, useCallback } from 'react';
import {
  getRecentObservation,
  OBS_STATION_CODES,
  type RecentObservation,
} from '@tabs/weather/services/khoaApi';
import {
  getUltraShortForecast,
  getMarineForecast,
  convertToGridCoords,
  getCurrentBaseDateTime,
  MARINE_REGIONS,
  type WeatherForecastData,
  type MarineWeatherData,
} from '@tabs/weather/services/weatherApi';

const KEY_TO_NAME: Record<string, string> = {
  incheon: '인천',
  gunsan: '군산',
  mokpo: '목포',
  yeosu: '여수',
  tongyeong: '통영',
  ulsan: '울산',
  pohang: '포항',
  donghae: '동해',
  sokcho: '속초',
  jeju: '제주',
};

// 조위관측소 목록
const STATIONS = Object.entries(OBS_STATION_CODES).map(([key, code]) => ({
  key,
  code,
  name: KEY_TO_NAME[key] ?? key,
}));

// 기상청 초단기실황 지점 (위경도)
const WEATHER_STATIONS = [
  { name: '인천', lat: 37.4563, lon: 126.7052 },
  { name: '군산', lat: 35.9679, lon: 126.7361 },
  { name: '목포', lat: 34.8118, lon: 126.3922 },
  { name: '부산', lat: 35.1028, lon: 129.0323 },
  { name: '제주', lat: 33.5131, lon: 126.5297 },
];

// 해역 목록
const MARINE_REGION_LIST = Object.entries(MARINE_REGIONS).map(([name, regId]) => ({
  name,
  regId,
}));

type TabId = 'khoa' | 'kma-ultra' | 'kma-marine';

interface KhoaRow {
  stationName: string;
  data: RecentObservation | null;
  error: boolean;
}

interface KmaUltraRow {
  stationName: string;
  data: WeatherForecastData | null;
  error: boolean;
}

interface MarineRow {
  name: string;
  regId: string;
  data: MarineWeatherData | null;
  error: boolean;
}

const fmt = (v: number | null | undefined, digits = 1): string =>
  v != null ? v.toFixed(digits) : '-';

function StatusBadge({
  loading,
  errorCount,
  total,
}: {
  loading: boolean;
  errorCount: number;
  total: number;
}) {
  if (loading) {
    return (
      <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-caption bg-bg-elevated text-t2">
        <span className="w-1.5 h-1.5 rounded-full bg-cyan-400 animate-pulse" />
        조회 중...
      </span>
    );
  }
  if (errorCount === total) {
    return (
      <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-caption bg-red-500/10 text-red-400">
        <span className="w-1.5 h-1.5 rounded-full bg-red-400" />
        연계 오류
      </span>
    );
  }
  if (errorCount > 0) {
    return (
      <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-caption bg-yellow-500/10 text-yellow-400">
        <span className="w-1.5 h-1.5 rounded-full bg-yellow-400" />
        일부 오류 ({errorCount}/{total})
      </span>
    );
  }
  return (
    <span className="inline-flex items-center gap-1 px-2 py-0.5 rounded text-caption bg-emerald-500/10 text-emerald-400">
      <span className="w-1.5 h-1.5 rounded-full bg-emerald-400" />
      정상
    </span>
  );
}

function KhoaTable({ rows, loading }: { rows: KhoaRow[]; loading: boolean }) {
  const headers = [
    '관측소',
    '수온(°C)',
    '기온(°C)',
    '기압(hPa)',
    '풍향(°)',
    '풍속(m/s)',
    '유향(°)',
    '유속(m/s)',
    '조위(cm)',
    '상태',
  ];

  return (
    <div className="overflow-auto">
      <table className="w-full text-caption border-collapse">
        <thead>
          <tr className="bg-bg-elevated text-t3 uppercase tracking-wide">
            {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: 5 }).map((_, i) => (
                <tr key={i} className="border-b border-stroke-1 animate-pulse">
                  {headers.map((_, j) => (
                    <td key={j} className="px-3 py-2">
                      <div className="h-3 bg-bg-elevated rounded w-12" />
                    </td>
                  ))}
                </tr>
              ))
            : rows.map((row) => (
                <tr
                  key={row.stationName}
                  className="border-b border-stroke-1 hover:bg-bg-surface/50"
                >
                  <td className="px-3 py-2 font-medium text-t1 whitespace-nowrap">
                    {row.stationName}
                  </td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.water_temp)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.air_temp)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.air_pres)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.wind_dir, 0)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.wind_speed)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.current_dir, 0)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.current_speed)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.tide_level, 0)}</td>
                  <td className="px-3 py-2">
                    {row.error ? (
                      <span className="text-red-400 text-caption">오류</span>
                    ) : row.data ? (
                      <span className="text-emerald-400 text-caption">정상</span>
                    ) : (
                      <span className="text-t3 text-caption">-</span>
                    )}
                  </td>
                </tr>
              ))}
        </tbody>
      </table>
    </div>
  );
}

function KmaUltraTable({ rows, loading }: { rows: KmaUltraRow[]; loading: boolean }) {
  const headers = [
    '지점',
    '기온(°C)',
    '풍속(m/s)',
    '풍향(°)',
    '파고(m)',
    '강수(mm)',
    '습도(%)',
    '상태',
  ];

  return (
    <div className="overflow-auto">
      <table className="w-full text-caption border-collapse">
        <thead>
          <tr className="bg-bg-elevated text-t3 uppercase tracking-wide">
            {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: 3 }).map((_, i) => (
                <tr key={i} className="border-b border-stroke-1 animate-pulse">
                  {headers.map((_, j) => (
                    <td key={j} className="px-3 py-2">
                      <div className="h-3 bg-bg-elevated rounded w-12" />
                    </td>
                  ))}
                </tr>
              ))
            : rows.map((row) => (
                <tr
                  key={row.stationName}
                  className="border-b border-stroke-1 hover:bg-bg-surface/50"
                >
                  <td className="px-3 py-2 font-medium text-t1 whitespace-nowrap">
                    {row.stationName}
                  </td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.temperature)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.windSpeed)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.windDirection, 0)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.waveHeight)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.precipitation)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.humidity, 0)}</td>
                  <td className="px-3 py-2">
                    {row.error ? (
                      <span className="text-red-400 text-caption">오류</span>
                    ) : row.data ? (
                      <span className="text-emerald-400 text-caption">정상</span>
                    ) : (
                      <span className="text-t3 text-caption">-</span>
                    )}
                  </td>
                </tr>
              ))}
        </tbody>
      </table>
    </div>
  );
}

function MarineTable({ rows, loading }: { rows: MarineRow[]; loading: boolean }) {
  const headers = ['해역명', '파고(m)', '풍속(m/s)', '풍향', '수온(°C)', '상태'];

  return (
    <div className="overflow-auto">
      <table className="w-full text-caption border-collapse">
        <thead>
          <tr className="bg-bg-elevated text-t3 uppercase tracking-wide">
            {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: 4 }).map((_, i) => (
                <tr key={i} className="border-b border-stroke-1 animate-pulse">
                  {headers.map((_, j) => (
                    <td key={j} className="px-3 py-2">
                      <div className="h-3 bg-bg-elevated rounded w-14" />
                    </td>
                  ))}
                </tr>
              ))
            : rows.map((row) => (
                <tr key={row.regId} className="border-b border-stroke-1 hover:bg-bg-surface/50">
                  <td className="px-3 py-2 font-medium text-t1 whitespace-nowrap">{row.name}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.waveHeight)}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.windSpeed)}</td>
                  <td className="px-3 py-2 text-t2">{row.data?.windDirection || '-'}</td>
                  <td className="px-3 py-2 text-t2">{fmt(row.data?.temperature)}</td>
                  <td className="px-3 py-2">
                    {row.error ? (
                      <span className="text-red-400 text-caption">오류</span>
                    ) : row.data ? (
                      <span className="text-emerald-400 text-caption">정상</span>
                    ) : (
                      <span className="text-t3 text-caption">-</span>
                    )}
                  </td>
                </tr>
              ))}
        </tbody>
      </table>
    </div>
  );
}

export default function MonitorRealtimePanel() {
  const [activeTab, setActiveTab] = useState<TabId>('khoa');
  const [lastUpdate, setLastUpdate] = useState<Date | null>(null);

  // KHOA 조위관측소
  const [khoaRows, setKhoaRows] = useState<KhoaRow[]>([]);
  const [khoaLoading, setKhoaLoading] = useState(false);

  // 기상청 초단기실황
  const [kmaRows, setKmaRows] = useState<KmaUltraRow[]>([]);
  const [kmaLoading, setKmaLoading] = useState(false);

  // 기상청 해상예보
  const [marineRows, setMarineRows] = useState<MarineRow[]>([]);
  const [marineLoading, setMarineLoading] = useState(false);

  const fetchKhoa = useCallback(async () => {
    setKhoaLoading(true);
    const results = await Promise.allSettled(STATIONS.map((s) => getRecentObservation(s.code)));
    const rows: KhoaRow[] = STATIONS.map((s, i) => {
      const result = results[i];
      if (result.status === 'fulfilled') {
        return { stationName: s.name, data: result.value, error: false };
      }
      return { stationName: s.name, data: null, error: true };
    });
    setKhoaRows(rows);
    setKhoaLoading(false);
    setLastUpdate(new Date());
  }, []);

  const fetchKmaUltra = useCallback(async () => {
    setKmaLoading(true);
    const { baseDate, baseTime } = getCurrentBaseDateTime();
    const results = await Promise.allSettled(
      WEATHER_STATIONS.map((s) => {
        const { nx, ny } = convertToGridCoords(s.lat, s.lon);
        return getUltraShortForecast(nx, ny, baseDate, baseTime);
      }),
    );
    const rows: KmaUltraRow[] = WEATHER_STATIONS.map((s, i) => {
      const result = results[i];
      if (result.status === 'fulfilled' && result.value.length > 0) {
        return { stationName: s.name, data: result.value[0], error: false };
      }
      return { stationName: s.name, data: null, error: result.status === 'rejected' };
    });
    setKmaRows(rows);
    setKmaLoading(false);
    setLastUpdate(new Date());
  }, []);

  const fetchMarine = useCallback(async () => {
    setMarineLoading(true);
    const now = new Date();
    const pad = (n: number) => String(n).padStart(2, '0');
    const tmFc = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}${pad(now.getHours())}00`;

    const results = await Promise.allSettled(
      MARINE_REGION_LIST.map((r) => getMarineForecast(r.regId, tmFc)),
    );
    const rows: MarineRow[] = MARINE_REGION_LIST.map((r, i) => {
      const result = results[i];
      if (result.status === 'fulfilled') {
        return { name: r.name, regId: r.regId, data: result.value, error: false };
      }
      return { name: r.name, regId: r.regId, data: null, error: true };
    });
    setMarineRows(rows);
    setMarineLoading(false);
    setLastUpdate(new Date());
  }, []);

  // 탭 전환 시 해당 데이터 로드
  useEffect(() => {
    let isMounted = true;

    if (activeTab === 'khoa' && khoaRows.length === 0) {
      void Promise.resolve().then(() => {
        if (isMounted) void fetchKhoa();
      });
    } else if (activeTab === 'kma-ultra' && kmaRows.length === 0) {
      void Promise.resolve().then(() => {
        if (isMounted) void fetchKmaUltra();
      });
    } else if (activeTab === 'kma-marine' && marineRows.length === 0) {
      void Promise.resolve().then(() => {
        if (isMounted) void fetchMarine();
      });
    }

    return () => {
      isMounted = false;
    };
  }, [
    activeTab,
    khoaRows.length,
    kmaRows.length,
    marineRows.length,
    fetchKhoa,
    fetchKmaUltra,
    fetchMarine,
  ]);

  const handleRefresh = () => {
    if (activeTab === 'khoa') fetchKhoa();
    else if (activeTab === 'kma-ultra') fetchKmaUltra();
    else fetchMarine();
  };

  const isLoading =
    activeTab === 'khoa' ? khoaLoading : activeTab === 'kma-ultra' ? kmaLoading : marineLoading;
  const currentRows =
    activeTab === 'khoa' ? khoaRows : activeTab === 'kma-ultra' ? kmaRows : marineRows;
  const errorCount = currentRows.filter((r) => r.error).length;
  const totalCount =
    activeTab === 'khoa'
      ? STATIONS.length
      : activeTab === 'kma-ultra'
        ? WEATHER_STATIONS.length
        : MARINE_REGION_LIST.length;

  const TABS: { id: TabId; label: string }[] = [
    { id: 'khoa', label: 'KHOA 조위관측소' },
    { id: 'kma-ultra', label: '기상청 초단기실황' },
    { id: 'kma-marine', label: '기상청 해상예보' },
  ];

  return (
    <div className="flex flex-col h-full overflow-hidden">
      {/* 헤더 */}
      <div className="flex items-center justify-between px-5 py-3 border-b border-stroke-1 shrink-0">
        <h2 className="text-body-2 font-semibold text-t1">실시간 관측자료 모니터링</h2>
        <div className="flex items-center gap-3">
          {lastUpdate && (
            <span className="text-caption text-t3">
              갱신:{' '}
              {lastUpdate.toLocaleTimeString('ko-KR', {
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit',
              })}
            </span>
          )}
          <button
            onClick={handleRefresh}
            disabled={isLoading}
            className="flex items-center gap-1.5 px-3 py-1.5 text-caption 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 ${isLoading ? '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 gap-0 border-b border-stroke-1 shrink-0 px-5">
        {TABS.map((tab) => (
          <button
            key={tab.id}
            onClick={() => setActiveTab(tab.id)}
            className={`px-4 py-2.5 text-caption font-medium border-b-2 transition-colors ${
              activeTab === tab.id
                ? 'border-cyan-400 text-cyan-400'
                : 'border-transparent text-t3 hover:text-t2'
            }`}
          >
            {tab.label}
          </button>
        ))}
      </div>

      {/* 상태 표시줄 */}
      <div className="flex items-center gap-3 px-5 py-2 shrink-0 border-b border-stroke-1 bg-bg-base">
        <StatusBadge loading={isLoading} errorCount={errorCount} total={totalCount} />
        <span className="text-caption text-t3">
          {activeTab === 'khoa' && `관측소 ${totalCount}개`}
          {activeTab === 'kma-ultra' && `지점 ${totalCount}개`}
          {activeTab === 'kma-marine' && `해역 ${totalCount}개`}
        </span>
      </div>

      {/* 테이블 콘텐츠 */}
      <div className="flex-1 overflow-auto p-5">
        {activeTab === 'khoa' && <KhoaTable rows={khoaRows} loading={khoaLoading} />}
        {activeTab === 'kma-ultra' && <KmaUltraTable rows={kmaRows} loading={kmaLoading} />}
        {activeTab === 'kma-marine' && <MarineTable rows={marineRows} loading={marineLoading} />}
      </div>
    </div>
  );
}
