import { useEffect, useState } from 'react';
import { Map, useControl } from '@vis.gl/react-maplibre';
import { MapboxOverlay } from '@deck.gl/mapbox';
import { GeoJsonLayer } from '@deck.gl/layers';
import type { Layer } from '@deck.gl/core';
import 'maplibre-gl/dist/maplibre-gl.css';
import { useBaseMapStyle } from '@common/hooks/useBaseMapStyle';
import { S57EncOverlay } from '@common/components/map/S57EncOverlay';
import { useMapStore } from '@common/store/mapStore';

const MAP_CENTER: [number, number] = [127.5, 36.0];
const MAP_ZOOM = 5.5;

const CONSIDER_FILL: [number, number, number, number] = [59, 130, 246, 60];
const CONSIDER_LINE: [number, number, number, number] = [59, 130, 246, 220];
const RESTRICT_FILL: [number, number, number, number] = [239, 68, 68, 60];
const RESTRICT_LINE: [number, number, number, number] = [239, 68, 68, 220];

type ZoneKey = 'consider' | 'restrict';

// deck.gl 오버레이 컴포넌트
function DeckGLOverlay({ layers }: { layers: Layer[] }) {
  const overlay = useControl<MapboxOverlay>(() => new MapboxOverlay({ interleaved: true }));
  overlay.setProps({ layers });
  return null;
}

// 구역 설명 데이터
const ZONE_INFO: Record<ZoneKey, { label: string; rows: { key: string; value: string }[] }> = {
  consider: {
    label: '사용고려해역',
    rows: [
      { key: '수심', value: '20m 이상 ※ (IMO) 대형 20m, 중소형 10m 이상' },
      {
        key: '사용거리',
        value:
          '해안 2km, 중요 민감자원으로부터 5km 이상 떨어진 경우 ※ (IMO) 대형 1km, 중소형 0.5km 이상',
      },
      { key: '사용승인(절차)', value: '현장 방제책임자 재량 사용 ※ (IMO) 의결정 절차 지침' },
    ],
  },
  restrict: {
    label: '사용제한해역',
    rows: [
      { key: '수심', value: '수심 10m 이하' },
      {
        key: '사용거리',
        value: '어장·양식장, 발전소 취수구, 종묘배양장 및 폐쇄성 해역 특정해역중 수자원 보호구역',
      },
      {
        key: '사용승인(절차)',
        value:
          '심의위원회 승인을 받아 관할 방제책임기관 또는 방제대책 본부장이 결정 ※ 긴급한 경우 先사용, 後심의',
      },
    ],
  },
};

const DispersingZonePanel = () => {
  const currentMapStyle = useBaseMapStyle();
  const mapToggles = useMapStore((s) => s.mapToggles);
  const [showConsider, setShowConsider] = useState(true);
  const [showRestrict, setShowRestrict] = useState(true);
  const [expandedZone, setExpandedZone] = useState<ZoneKey | null>(null);
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const [considerData, setConsiderData] = useState<any>(null);
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const [restrictData, setRestrictData] = useState<any>(null);

  useEffect(() => {
    fetch('/dispersant-consider.geojson')
      .then((r) => r.json())
      .then(setConsiderData)
      .catch(() => {
        /* GeoJSON 없을 때 빈 상태 유지 */
      });

    fetch('/dispersant-restrict.geojson')
      .then((r) => r.json())
      .then(setRestrictData)
      .catch(() => {
        /* GeoJSON 없을 때 빈 상태 유지 */
      });
  }, []);

  const layers: Layer[] = [
    ...(showConsider && considerData
      ? [
          new GeoJsonLayer({
            id: 'dispersant-consider',
            data: considerData,
            getFillColor: CONSIDER_FILL,
            getLineColor: CONSIDER_LINE,
            lineWidthMinPixels: 1.5,
            pickable: false,
          }),
        ]
      : []),
    ...(showRestrict && restrictData
      ? [
          new GeoJsonLayer({
            id: 'dispersant-restrict',
            data: restrictData,
            getFillColor: RESTRICT_FILL,
            getLineColor: RESTRICT_LINE,
            lineWidthMinPixels: 1.5,
            pickable: false,
          }),
        ]
      : []),
  ];

  const handleToggleExpand = (zone: ZoneKey) => {
    setExpandedZone((prev) => (prev === zone ? null : zone));
  };

  const renderZoneCard = (zone: ZoneKey) => {
    const info = ZONE_INFO[zone];
    const isConsider = zone === 'consider';
    const showLayer = isConsider ? showConsider : showRestrict;
    const setShowLayer = isConsider ? setShowConsider : setShowRestrict;
    const swatchColor = isConsider ? 'bg-blue-500' : 'bg-red-500';
    const isExpanded = expandedZone === zone;

    return (
      <div key={zone} className="border border-stroke rounded-lg overflow-hidden">
        {/* 카드 헤더 */}
        <div
          className="flex items-center gap-2 px-3 py-2.5 cursor-pointer hover:bg-[rgba(255,255,255,0.03)] transition-colors"
          onClick={() => handleToggleExpand(zone)}
        >
          <span className={`w-3 h-3 rounded-sm shrink-0 ${swatchColor}`} />
          <span className="flex-1 text-caption font-semibold text-fg font-korean">
            {info.label}
          </span>
          {/* 토글 스위치 */}
          <button
            onClick={(e) => {
              e.stopPropagation();
              setShowLayer((prev) => !prev);
            }}
            title={showLayer ? '레이어 숨기기' : '레이어 표시'}
            className={`relative inline-flex h-5 w-9 items-center rounded-full transition-colors shrink-0 ${
              showLayer ? 'bg-color-accent' : 'bg-[rgba(255,255,255,0.08)] border border-stroke'
            }`}
          >
            <span
              className={`inline-block h-3.5 w-3.5 transform rounded-full bg-white shadow transition-transform ${
                showLayer ? 'translate-x-[18px]' : 'translate-x-0.5'
              }`}
            />
          </button>
          {/* 펼침 화살표 */}
          <span className="text-fg-disabled text-caption shrink-0">{isExpanded ? '▲' : '▼'}</span>
        </div>

        {/* 펼침 영역 */}
        {isExpanded && (
          <div className="border-t border-stroke px-3 py-3">
            <table className="w-full">
              <tbody>
                {info.rows.map((row) => (
                  <tr key={row.key} className="border-b border-stroke last:border-0">
                    <td className="py-2 pr-2 text-label-2 text-fg-disabled font-korean whitespace-nowrap align-top w-24">
                      {row.key}
                    </td>
                    <td className="py-2 text-label-2 text-fg-sub font-korean leading-relaxed">
                      {row.value}
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    );
  };

  return (
    <div className="flex flex-1 overflow-hidden">
      {/* 지도 영역 */}
      <div className="flex-1 relative">
        <Map
          initialViewState={{
            longitude: MAP_CENTER[0],
            latitude: MAP_CENTER[1],
            zoom: MAP_ZOOM,
          }}
          style={{ width: '100%', height: '100%' }}
          mapStyle={currentMapStyle}
        >
          <S57EncOverlay visible={mapToggles['s57'] ?? false} />
          <DeckGLOverlay layers={layers} />
        </Map>

        {/* 범례 */}
        <div className="absolute bottom-4 left-4 bg-bg-surface border border-stroke rounded-lg px-3 py-2 flex flex-col gap-1.5">
          <div className="flex items-center gap-2">
            <span className="w-3 h-3 rounded-sm bg-blue-500 opacity-80" />
            <span className="text-label-2 text-fg-sub font-korean">사용고려해역</span>
          </div>
          <div className="flex items-center gap-2">
            <span className="w-3 h-3 rounded-sm bg-red-500 opacity-80" />
            <span className="text-label-2 text-fg-sub font-korean">사용제한해역</span>
          </div>
        </div>
      </div>

      {/* 우측 패널 */}
      <div className="w-[280px] bg-bg-surface border-l border-stroke flex flex-col overflow-hidden shrink-0">
        {/* 헤더 */}
        <div className="px-4 py-4 border-b border-stroke shrink-0">
          <h1 className="text-body-2 font-bold text-fg font-korean">유처리제 제한구역</h1>
          <p className="text-label-2 text-fg-disabled mt-0.5 font-korean">해양환경관리법 기준</p>
        </div>

        {/* 구역 카드 목록 */}
        <div className="flex-1 overflow-y-auto p-3 flex flex-col gap-2">
          {renderZoneCard('consider')}
          {renderZoneCard('restrict')}
        </div>
      </div>
    </div>
  );
};

export default DispersingZonePanel;
