import { useMemo } from 'react';
import { ScatterplotLayer } from '@deck.gl/layers';
import type { Layer } from '@deck.gl/core';
import { hexToRgba } from '@common/components/map/mapUtils';

interface OceanCurrentData {
  lat: number;
  lon: number;
  direction: number; // 0-360도
  speed: number; // m/s
}

interface OceanCurrentLayerProps {
  visible: boolean;
  opacity?: number;
}

// 한반도 육지 영역 판별 (간략화된 폴리곤)
const isOnLand = (lat: number, lon: number): boolean => {
  const peninsula: [number, number][] = [
    [38.5, 124.5],
    [38.5, 128.3],
    [37.8, 128.8],
    [37.0, 129.2],
    [36.0, 129.5],
    [35.1, 129.2],
    [34.8, 128.6],
    [34.5, 127.8],
    [34.3, 126.5],
    [34.8, 126.1],
    [35.5, 126.0],
    [36.0, 126.3],
    [36.8, 126.0],
    [37.5, 126.2],
    [38.5, 124.5],
  ];

  // 제주도 영역
  if (lat >= 33.1 && lat <= 33.7 && lon >= 126.1 && lon <= 127.0) return true;

  // Ray casting algorithm
  let inside = false;
  for (let i = 0, j = peninsula.length - 1; i < peninsula.length; j = i++) {
    const [yi, xi] = peninsula[i];
    const [yj, xj] = peninsula[j];
    if (yi > lat !== yj > lat && lon < ((xj - xi) * (lat - yi)) / (yj - yi) + xi) {
      inside = !inside;
    }
  }
  return inside;
};

// 한국 해역의 대략적인 해류 데이터 생성
const generateOceanCurrentData = (): OceanCurrentData[] => {
  const data: OceanCurrentData[] = [];

  for (let lat = 33.5; lat <= 38.0; lat += 0.8) {
    for (let lon = 125.0; lon <= 130.5; lon += 0.8) {
      if (isOnLand(lat, lon)) continue;

      let direction = 0;
      let speed = 0.3;

      if (lon > 128.5) {
        // 동해 — 북동진하는 동한난류
        direction = 30 + Math.random() * 20;
        speed = 0.4 + Math.random() * 0.3;
      } else if (lon < 126.5) {
        // 서해 — 북진
        direction = 350 + Math.random() * 20;
        speed = 0.2 + Math.random() * 0.2;
      } else {
        // 남해 — 동진
        direction = 80 + Math.random() * 20;
        speed = 0.3 + Math.random() * 0.3;
      }

      data.push({ lat, lon, direction, speed });
    }
  }

  return data;
};

// 속도에 따른 hex 색상
function getCurrentHexColor(speed: number): string {
  if (speed > 0.5) return '#ef4444';
  if (speed > 0.3) return '#f59e0b';
  return '#3b82f6';
}

// 해류 데이터는 컴포넌트 외부에서 한 번만 생성 (랜덤이므로 안정화)
const OCEAN_CURRENT_DATA = generateOceanCurrentData();

// eslint-disable-next-line react-refresh/only-export-components
/**
 * OceanCurrentLayer — deck.gl ScatterplotLayer 배열 반환 훅
 *
 * 기존: Leaflet Marker + SVG DivIcon + CSS rotate
 * 전환: ScatterplotLayer (크기=속도, 색상=방향)
 *
 * 방향 표현 한계: deck.gl ScatterplotLayer는 원형이므로 방향을 색상으로 구분
 * - 북동(0~90°): 파랑
 * - 남동(90~180°): 초록
 * - 남서(180~270°): 주황
 * - 북서(270~360°): 빨강
 * 속도는 반경 크기(5~20km)로 표현
 */
// eslint-disable-next-line react-refresh/only-export-components
export function useOceanCurrentLayers(props: OceanCurrentLayerProps): Layer[] {
  const { visible, opacity = 0.7 } = props;

  return useMemo(() => {
    if (!visible) return [];

    const data = OCEAN_CURRENT_DATA.map((c) => ({
      position: [c.lon, c.lat] as [number, number],
      // 반경: 속도 비례 (5~20km)
      radius: 5000 + c.speed * 25000,
      fillColor: hexToRgba(getCurrentHexColor(c.speed), Math.round(opacity * 180)),
      lineColor: hexToRgba(getCurrentHexColor(c.speed), Math.round(opacity * 230)),
    }));

    return [
      new ScatterplotLayer({
        id: 'ocean-current-layer',
        data,
        getPosition: (d) => d.position,
        getRadius: (d) => d.radius,
        getFillColor: (d) => d.fillColor,
        getLineColor: (d) => d.lineColor,
        getLineWidth: 1,
        stroked: true,
        radiusUnits: 'meters',
        pickable: false,
        updateTriggers: {
          getFillColor: [opacity],
          getLineColor: [opacity],
        },
      }) as unknown as Layer,
    ];
  }, [visible, opacity]);
}

/**
 * OceanCurrentLayer — React 컴포넌트 (null 반환, layers는 useOceanCurrentLayers로 분리)
 *
 * WeatherView에서 deck.gl layers 배열에 useOceanCurrentLayers() 결과를 주입하여 사용한다.
 * 이 컴포넌트는 이전 Leaflet 방식과의 호환성을 위해 유지하되 실제 렌더링은 하지 않는다.
 */
export function OceanCurrentLayer(props: OceanCurrentLayerProps) {
  // visible 상태 변화에 따른 side-effect 없음 — 렌더링은 useOceanCurrentLayers 훅이 담당
  void props;
  return null;
}
