/**
 * 항적 조회 Zustand 스토어
 * 참조: mda-react-front/src/tracking/stores/trackQueryStore.ts
 *
 * - 항적 데이터 관리 (조회 결과)
 * - 타임라인 (시간 범위, 현재 시간)
 * - 선박별/장비별 활성/비활성 토글
 * - 장비 필터 (통합선박 AVETDR)
 */
import { create } from 'zustand';
import { subscribeWithSelector } from 'zustand/middleware';
import {
  fetchTrackQuery,
  extractVesselIdentifier,
  toLocalISOString,
  buildVesselListForQuery,
} from '../api/trackApi';

// =====================
// 선종별 항적 색상 (RGBA)
// =====================
export const SHIP_KIND_TRACK_COLORS = {
  '000020': [25, 116, 25, 150],     // 어선
  '000021': [0, 41, 255, 150],      // 함정
  '000022': [176, 42, 42, 150],     // 여객선
  '000023': [255, 139, 54, 150],    // 화물선
  '000024': [255, 0, 0, 150],       // 유조선
  '000025': [92, 30, 224, 150],     // 관공선
  '000027': [255, 135, 207, 150],   // 기타
  '000028': [232, 95, 27, 150],     // 부이
};

export const DEFAULT_TRACK_COLOR = [128, 128, 128, 150];

/**
 * 선종코드로 항적 색상 반환
 */
export function getShipKindTrackColor(shipKindCode) {
  return SHIP_KIND_TRACK_COLORS[shipKindCode] || DEFAULT_TRACK_COLOR;
}

/** 기본 조회 기간 (3일) */
const DEFAULT_QUERY_DAYS = 3;

// =====================
// 항적 스토어
// =====================
const useTrackStore = create(subscribeWithSelector((set, get) => ({
  // =====================
  // 항적 데이터
  // =====================

  /** 조회된 항적 배열 (ProcessedTrack[]) */
  tracks: [],

  /** 비활성화된 선박 ID Set */
  disabledVesselIds: new Set(),

  /** 비활성화된 장비(신호원) Set - 통합선박 장비필터용 */
  disabledSigSrcCds: new Set(),

  // =====================
  // 시간 범위
  // =====================

  /** 데이터 전체 시작 시간 (ms) */
  dataStartTime: 0,

  /** 데이터 전체 종료 시간 (ms) */
  dataEndTime: 0,

  /** 조회 요청 시작 시간 (ms) */
  requestedStartTime: 0,

  /** 현재 시간 위치 (ms) - 프로그레스 바 위치 */
  currentTime: 0,

  // =====================
  // 로딩/에러
  // =====================
  isLoading: false,
  error: null,

  // =====================
  // 표시 옵션
  // =====================
  showPoints: true,
  showVirtualShip: true,
  showLabels: true,

  // =====================
  // 모달 상태
  // =====================

  /** 항적 조회 모달 배열 [{ ships, id, initialPos, isIntegrated }] */
  trackModals: [],

  // =====================
  // 액션 (Actions)
  // =====================

  /**
   * 항적 데이터 설정
   * currentTime을 dataEndTime으로 설정하여 전체 항적이 즉시 보이도록 함
   */
  setTracks: (tracks, requestedStartTime) => {
    if (!tracks || tracks.length === 0) {
      set({
        tracks: [],
        dataStartTime: 0,
        dataEndTime: 0,
        requestedStartTime: 0,
        currentTime: 0,
        disabledVesselIds: new Set(),
        disabledSigSrcCds: new Set(),
      });
      return;
    }

    // 전체 시간 범위 계산
    let minTime = Infinity;
    let maxTime = -Infinity;

    tracks.forEach((track) => {
      if (track.timestampsMs.length > 0) {
        const first = track.timestampsMs[0];
        const last = track.timestampsMs[track.timestampsMs.length - 1];
        if (first < minTime) minTime = first;
        if (last > maxTime) maxTime = last;
      }
    });

    set({
      tracks,
      dataStartTime: minTime,
      dataEndTime: maxTime,
      requestedStartTime: requestedStartTime || minTime,
      // 핵심 수정: currentTime을 dataEndTime으로 설정 → 전체 항적 즉시 표시
      currentTime: maxTime,
      disabledVesselIds: new Set(),
      disabledSigSrcCds: new Set(),
      error: null,
    });
  },

  /**
   * 현재 시간 설정 (범위 클램프)
   */
  setCurrentTime: (time) => {
    const { dataStartTime, dataEndTime } = get();
    const clamped = Math.max(dataStartTime, Math.min(dataEndTime, time));
    set({ currentTime: clamped });
  },

  /**
   * 진행률로 시간 설정 (0~1)
   */
  setProgressByRatio: (ratio) => {
    const { dataStartTime, dataEndTime } = get();
    const time = dataStartTime + (dataEndTime - dataStartTime) * ratio;
    set({ currentTime: time });
  },

  setLoading: (loading) => set({ isLoading: loading }),
  setError: (error) => set({ error }),
  setShowPoints: (show) => set({ showPoints: show }),
  setShowVirtualShip: (show) => set({ showVirtualShip: show }),
  setShowLabels: (show) => set({ showLabels: show }),

  /**
   * 선박 활성/비활성 토글
   */
  toggleVesselEnabled: (vesselId) => {
    const { disabledVesselIds } = get();
    const newSet = new Set(disabledVesselIds);
    if (newSet.has(vesselId)) {
      newSet.delete(vesselId);
    } else {
      newSet.add(vesselId);
    }
    set({ disabledVesselIds: newSet });
  },

  isVesselEnabled: (vesselId) => !get().disabledVesselIds.has(vesselId),

  /**
   * 장비(신호원) 토글 - 통합선박 장비필터
   */
  toggleEquipment: (sigSrcCd) => {
    const { disabledSigSrcCds, tracks } = get();
    const newDisabledSrc = new Set(disabledSigSrcCds);
    const newDisabledVessels = new Set(get().disabledVesselIds);

    if (newDisabledSrc.has(sigSrcCd)) {
      // 활성화
      newDisabledSrc.delete(sigSrcCd);
      tracks.filter((t) => t.sigSrcCd === sigSrcCd).forEach((t) => {
        newDisabledVessels.delete(t.vesselId);
      });
    } else {
      // 비활성화
      newDisabledSrc.add(sigSrcCd);
      tracks.filter((t) => t.sigSrcCd === sigSrcCd).forEach((t) => {
        newDisabledVessels.add(t.vesselId);
      });
    }

    set({ disabledSigSrcCds: newDisabledSrc, disabledVesselIds: newDisabledVessels });
  },

  /** 장비 전체 활성화 */
  enableAllEquipment: () => {
    set({ disabledSigSrcCds: new Set(), disabledVesselIds: new Set() });
  },

  /** 장비 기본값 복원 (ship의 active 장비만 활성) */
  resetEquipmentToDefault: (ship) => {
    if (!ship) return;
    const { tracks } = get();
    const newDisabledSrc = new Set();
    const newDisabledVessels = new Set();

    // ship 객체의 active 플래그로 판단
    const activeMap = {
      '000001': ship.ais,
      '000003': ship.vpass,
      '000002': ship.enav,
      '000004': ship.vtsAis,
      '000016': ship.dMfHf,
      '000005': ship.vtsRadar,
    };

    Object.entries(activeMap).forEach(([srcCd, isActive]) => {
      if (!isActive) {
        newDisabledSrc.add(srcCd);
        tracks.filter((t) => t.sigSrcCd === srcCd).forEach((t) => {
          newDisabledVessels.add(t.vesselId);
        });
      }
    });

    set({ disabledSigSrcCds: newDisabledSrc, disabledVesselIds: newDisabledVessels });
  },

  isEquipmentEnabled: (sigSrcCd) => !get().disabledSigSrcCds.has(sigSrcCd),

  /**
   * 활성화된 항적만 반환
   */
  getEnabledTracks: () => {
    const { tracks, disabledVesselIds } = get();
    return tracks.filter((t) => !disabledVesselIds.has(t.vesselId));
  },

  /**
   * 현재 시간 기준 각 선박의 보간된 위치 반환
   * 이진 탐색 + 선형 보간
   */
  getCurrentPositions: () => {
    const { tracks, currentTime, disabledVesselIds } = get();
    const positions = [];

    tracks.forEach((track) => {
      if (disabledVesselIds.has(track.vesselId)) return;

      const { timestampsMs, geometry, speeds } = track;
      if (timestampsMs.length === 0) return;

      // 범위 밖
      if (currentTime <= timestampsMs[0]) {
        positions.push({
          vesselId: track.vesselId,
          lon: geometry[0][0],
          lat: geometry[0][1],
          heading: 0,
          speed: speeds[0] || 0,
          shipName: track.shipName,
          shipKindCode: track.shipKindCode,
        });
        return;
      }

      if (currentTime >= timestampsMs[timestampsMs.length - 1]) {
        const last = geometry.length - 1;
        positions.push({
          vesselId: track.vesselId,
          lon: geometry[last][0],
          lat: geometry[last][1],
          heading: 0,
          speed: speeds[last] || 0,
          shipName: track.shipName,
          shipKindCode: track.shipKindCode,
        });
        return;
      }

      // 이진 탐색
      let lo = 0;
      let hi = timestampsMs.length - 1;
      while (lo < hi - 1) {
        const mid = (lo + hi) >> 1;
        if (timestampsMs[mid] <= currentTime) lo = mid;
        else hi = mid;
      }

      // 선형 보간
      const t1 = timestampsMs[lo];
      const t2 = timestampsMs[hi];
      const ratio = t2 === t1 ? 0 : (currentTime - t1) / (t2 - t1);

      const p1 = geometry[lo];
      const p2 = geometry[hi];
      const lon = p1[0] + (p2[0] - p1[0]) * ratio;
      const lat = p1[1] + (p2[1] - p1[1]) * ratio;

      // 방위각
      const dLon = (p2[0] - p1[0]) * Math.PI / 180;
      const lat1Rad = p1[1] * Math.PI / 180;
      const lat2Rad = p2[1] * Math.PI / 180;
      const y = Math.sin(dLon) * Math.cos(lat2Rad);
      const x = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
                Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon);
      let heading = Math.atan2(y, x) * 180 / Math.PI;
      if (heading < 0) heading += 360;

      const speed = speeds[lo] + (speeds[hi] - speeds[lo]) * ratio;

      positions.push({
        vesselId: track.vesselId,
        lon, lat, heading, speed,
        shipName: track.shipName,
        shipKindCode: track.shipKindCode,
      });
    });

    return positions;
  },

  getProgress: () => {
    const { dataStartTime, dataEndTime, currentTime } = get();
    if (dataEndTime === dataStartTime) return 0;
    return ((currentTime - dataStartTime) / (dataEndTime - dataStartTime)) * 100;
  },

  // =====================
  // 항적 모달 관리
  // =====================

  /**
   * 항적 조회 모달 열기 + 즉시 3일 자동 조회
   */
  openTrackModal: (ships) => {
    const state = get();
    const id = ships.map((s) => s.featureId || s.originalTargetId).join(',');

    if (state.trackModals.some((m) => m.id === id)) return;

    // 통합선박 여부 판단
    const isIntegrated = ships.length === 1 && !!ships[0].integrate;

    const newModal = { ships, id, isIntegrated };

    // 기존 모달 대체 (하나의 항적만 활성)
    set({ trackModals: [newModal] });

    // 즉시 3일 자동 조회
    get().queryTracks(ships);
  },

  /**
   * 항적 조회 실행
   */
  queryTracks: async (ships, startDate, endDate) => {
    const now = new Date();
    const start = startDate || new Date(now.getTime() - DEFAULT_QUERY_DAYS * 24 * 60 * 60 * 1000);
    const end = endDate || now;

    set({ isLoading: true, error: null });

    try {
      const startTime = toLocalISOString(start);
      const endTime = toLocalISOString(end);

      // 통합선박이면 장비별로 쿼리 목록 생성
      const ship = ships[0];
      const isIntegrated = ships.length === 1 && ship.integrate;
      const vessels = isIntegrated
        ? buildVesselListForQuery(ship)
        : ships.map((s) => extractVesselIdentifier(s));

      const result = await fetchTrackQuery({
        startTime,
        endTime,
        vessels,
        isIntegration: false,
      });

      get().setTracks(result, start.getTime());
    } catch (err) {
      set({ error: err.message || '항적 조회 실패' });
    } finally {
      set({ isLoading: false });
    }
  },

  /**
   * 항적 모달 닫기
   */
  closeTrackModal: (modalId) => {
    set({
      trackModals: [],
      tracks: [],
      dataStartTime: 0,
      dataEndTime: 0,
      currentTime: 0,
      error: null,
      isLoading: false,
      disabledVesselIds: new Set(),
      disabledSigSrcCds: new Set(),
    });
  },

  /** 전체 초기화 */
  reset: () => {
    set({
      tracks: [],
      disabledVesselIds: new Set(),
      disabledSigSrcCds: new Set(),
      dataStartTime: 0,
      dataEndTime: 0,
      requestedStartTime: 0,
      currentTime: 0,
      isLoading: false,
      error: null,
      showPoints: true,
      showVirtualShip: true,
      showLabels: true,
      trackModals: [],
    });
  },
})));

export default useTrackStore;
