import { useCallback, useEffect, useRef, useState } from 'react';
import { usePersistedState } from '../../shared/hooks';
import type { VesselTypeCode } from '../../entities/vessel/model/types';
import type { MapToggleState } from '../../features/mapToggles/MapToggles';
import type { LegacyAlarmKind } from '../../features/legacyDashboard/model/types';
import { LEGACY_ALARM_KINDS } from '../../features/legacyDashboard/model/types';
import type { BaseMapId, Map3DSettings, MapProjectionId } from '../../widgets/map3d/Map3D';
import type { MapViewState } from '../../widgets/map3d/types';
import { DEFAULT_MAP_STYLE_SETTINGS } from '../../features/mapSettings/types';
import type { MapStyleSettings } from '../../features/mapSettings/types';
import { DEFAULT_OCEAN_MAP_SETTINGS } from '../../features/oceanMap/model/types';
import type { OceanMapSettings } from '../../features/oceanMap/model/types';
import { DEFAULT_ENC_MAP_SETTINGS } from '../../features/encMap/model/types';
import type { EncMapSettings } from '../../features/encMap/model/types';
import { fmtDateTimeFull } from '../../shared/lib/datetime';

export type Bbox = [number, number, number, number];
export type FleetRelationSortMode = 'count' | 'range';

export function useDashboardState(uid: number | null) {
  // ── Map instance ──
  const [mapInstance, setMapInstance] = useState<import('maplibre-gl').Map | null>(null);
  const handleMapReady = useCallback((map: import('maplibre-gl').Map) => setMapInstance(map), []);

  // ── Viewport / API BBox ──
  const [viewBbox, setViewBbox] = useState<Bbox | null>(null);
  const [useViewportFilter, setUseViewportFilter] = useState(false);
  const [useApiBbox, setUseApiBbox] = useState(false);
  const [apiBbox, setApiBbox] = useState<string | undefined>(undefined);

  // ── Selection & hover ──
  const [selectedMmsi, setSelectedMmsi] = useState<number | null>(null);
  const [highlightedMmsiSet, setHighlightedMmsiSet] = useState<number[]>([]);
  const [hoveredMmsiSet, setHoveredMmsiSet] = useState<number[]>([]);
  const [hoveredFleetMmsiSet, setHoveredFleetMmsiSet] = useState<number[]>([]);
  const [hoveredPairMmsiSet, setHoveredPairMmsiSet] = useState<number[]>([]);
  const [hoveredFleetOwnerKey, setHoveredFleetOwnerKey] = useState<string | null>(null);

  // ── Filters (persisted) ──
  const [typeEnabled, setTypeEnabled] = usePersistedState<Record<VesselTypeCode, boolean>>(
    uid, 'typeEnabled', { PT: true, 'PT-S': true, GN: true, OT: true, PS: true, FC: true },
  );
  const [showTargets, setShowTargets] = usePersistedState(uid, 'showTargets', true);
  const [showOthers, setShowOthers] = usePersistedState(uid, 'showOthers', true);

  // ── Map settings (persisted) ──
  const [baseMap, setBaseMap] = usePersistedState<BaseMapId>(uid, 'baseMap', 'ocean');
  const [projection, setProjection] = useState<MapProjectionId>('mercator');
  const [mapStyleSettings, setMapStyleSettings] = usePersistedState<MapStyleSettings>(uid, 'mapStyleSettings', DEFAULT_MAP_STYLE_SETTINGS);
  const [overlays, setOverlays] = usePersistedState<MapToggleState>(uid, 'overlays', {
    pairLines: false, pairRange: false, fcLines: false, zones: true,
    fleetCircles: false, predictVectors: false, shipLabels: true, subcables: false,
  });
  const [settings, setSettings] = usePersistedState<Map3DSettings>(uid, 'map3dSettings', {
    showShips: true, showDensity: false, showSeamark: false,
  });
  const [mapView, setMapView] = usePersistedState<MapViewState | null>(uid, 'mapView', null);
  const [oceanMapSettings, setOceanMapSettings] = usePersistedState<OceanMapSettings>(uid, 'oceanMapSettings', DEFAULT_OCEAN_MAP_SETTINGS);
  const [encMapSettingsRaw, setEncMapSettings] = usePersistedState<EncMapSettings>(uid, 'encMapSettings', DEFAULT_ENC_MAP_SETTINGS);
  // Merge with defaults to fill missing fields from older localStorage entries
  const encMapSettings: EncMapSettings = { ...DEFAULT_ENC_MAP_SETTINGS, ...encMapSettingsRaw };

  // ── 자유 시점 (모드별 독립) ──
  const [freeCameraMercator, setFreeCameraMercator] = usePersistedState(uid, 'freeCameraMercator', true);
  const [freeCameraGlobe, setFreeCameraGlobe] = usePersistedState(uid, 'freeCameraGlobe', true);
  const freeCamera = projection === 'globe' ? freeCameraGlobe : freeCameraMercator;
  const toggleFreeCamera = useCallback(() => {
    if (projection === 'globe') setFreeCameraGlobe((v) => !v);
    else setFreeCameraMercator((v) => !v);
  }, [projection, setFreeCameraGlobe, setFreeCameraMercator]);

  // ── Sort & alarm filters (persisted) ──
  const [fleetRelationSortMode, setFleetRelationSortMode] = usePersistedState<FleetRelationSortMode>(uid, 'sortMode', 'count');
  const [alarmKindEnabled, setAlarmKindEnabled] = usePersistedState<Record<LegacyAlarmKind, boolean>>(
    uid, 'alarmKindEnabled',
    () => Object.fromEntries(LEGACY_ALARM_KINDS.map((k) => [k, false])) as Record<LegacyAlarmKind, boolean>,
  );

  // ── Fleet focus ──
  const [fleetFocus, setFleetFocus] = useState<{ id: string | number; center: [number, number]; zoom?: number } | undefined>(undefined);

  // ── Cable ──
  const [hoveredCableId, setHoveredCableId] = useState<string | null>(null);
  const [selectedCableId, setSelectedCableId] = useState<string | null>(null);

  // ── Track context menu ──
  const [trackContextMenu, setTrackContextMenu] = useState<{ x: number; y: number; mmsi: number; vesselName: string; isPermitted: boolean } | null>(null);
  const handleOpenTrackMenu = useCallback((info: { x: number; y: number; mmsi: number; vesselName: string; isPermitted: boolean }) => setTrackContextMenu(info), []);
  const handleCloseTrackMenu = useCallback(() => setTrackContextMenu(null), []);

  // ── Projection loading ──
  const [isProjectionLoading, setIsProjectionLoading] = useState(false);
  const [isGlobeShipsReady, setIsGlobeShipsReady] = useState(false);
  const handleProjectionLoadingChange = useCallback((loading: boolean) => setIsProjectionLoading(loading), []);
  const showMapLoader = isProjectionLoading;
  const isProjectionToggleDisabled = !isGlobeShipsReady || isProjectionLoading;

  // ── Clock ──
  const [clock, setClock] = useState(() => fmtDateTimeFull(new Date()));
  useEffect(() => {
    const id = window.setInterval(() => setClock(fmtDateTimeFull(new Date())), 1000);
    return () => window.clearInterval(id);
  }, []);

  // ── Admin mode (7 clicks within 900ms) ──
  const [adminMode, setAdminMode] = useState(false);
  const clicksRef = useRef<number[]>([]);
  const onLogoClick = () => {
    const now = Date.now();
    clicksRef.current = clicksRef.current.filter((t) => now - t < 900);
    clicksRef.current.push(now);
    if (clicksRef.current.length >= 7) {
      clicksRef.current = [];
      setAdminMode((v) => !v);
    }
  };

  // ── Helpers ──
  const setUniqueSorted = (items: number[]) =>
    Array.from(new Set(items.filter((item) => Number.isFinite(item)))).sort((a, b) => a - b);

  const setSortedIfChanged = (next: number[]) => {
    const sorted = setUniqueSorted(next);
    return (prev: number[]) => (prev.length === sorted.length && prev.every((v, i) => v === sorted[i]) ? prev : sorted);
  };

  const toggleHighlightedMmsi = (mmsi: number) => {
    setHighlightedMmsiSet((prev) => {
      const s = new Set(prev);
      if (s.has(mmsi)) s.delete(mmsi);
      else s.add(mmsi);
      return Array.from(s).sort((a, b) => a - b);
    });
  };

  return {
    mapInstance, handleMapReady,
    viewBbox, setViewBbox, useViewportFilter, setUseViewportFilter,
    useApiBbox, setUseApiBbox, apiBbox, setApiBbox,
    selectedMmsi, setSelectedMmsi,
    highlightedMmsiSet,
    hoveredMmsiSet, setHoveredMmsiSet,
    hoveredFleetMmsiSet, setHoveredFleetMmsiSet,
    hoveredPairMmsiSet, setHoveredPairMmsiSet,
    hoveredFleetOwnerKey, setHoveredFleetOwnerKey,
    typeEnabled, setTypeEnabled, showTargets, setShowTargets, showOthers, setShowOthers,
    baseMap, setBaseMap, projection, setProjection,
    mapStyleSettings, setMapStyleSettings,
    overlays, setOverlays, settings, setSettings,
    mapView, setMapView, freeCamera, toggleFreeCamera,
    oceanMapSettings, setOceanMapSettings,
    encMapSettings, setEncMapSettings,
    fleetRelationSortMode, setFleetRelationSortMode,
    alarmKindEnabled, setAlarmKindEnabled,
    fleetFocus, setFleetFocus,
    hoveredCableId, setHoveredCableId, selectedCableId, setSelectedCableId,
    trackContextMenu, handleOpenTrackMenu, handleCloseTrackMenu,
    handleProjectionLoadingChange,
    isGlobeShipsReady, setIsGlobeShipsReady,
    showMapLoader, isProjectionToggleDisabled,
    clock, adminMode, onLogoClick,
    setUniqueSorted, setSortedIfChanged, toggleHighlightedMmsi,
  };
}
