import { create } from 'zustand';
import { api } from '../services/api';
import { haversineDistance, polygonAreaKm2 } from '../utils/geo';

export interface MapTypeItem {
  mapKey: string;
  mapNm: string;
  mapLevelCd: string | null;
}

export type MeasureMode = 'distance' | 'area' | null;

export interface MeasurePoint {
  lat: number;
  lon: number;
}

export interface MeasureResult {
  id: string;
  mode: 'distance' | 'area';
  points: MeasurePoint[];
  value: number; // distance(m) or area(km²)
}

interface MapToggles {
  s57: boolean;
  s101: boolean;
  threeD: boolean;
  satellite: boolean;
}

interface MapState {
  mapToggles: MapToggles;
  mapTypes: MapTypeItem[];
  toggleMap: (key: keyof MapToggles) => void;
  loadMapTypes: () => Promise<void>;
  // 측정
  measureMode: MeasureMode;
  measureInProgress: MeasurePoint[];
  measurements: MeasureResult[];
  setMeasureMode: (mode: MeasureMode) => void;
  addMeasurePoint: (pt: MeasurePoint) => void;
  commitAreaMeasurement: () => void;
  removeMeasurement: (id: string) => void;
  clearAllMeasurements: () => void;
}

const DEFAULT_MAP_TYPES: MapTypeItem[] = [
  { mapKey: 's57', mapNm: 'S-57 전자해도', mapLevelCd: 'S-57' },
  { mapKey: 's101', mapNm: 'S-101 전자해도', mapLevelCd: 'S-101' },
  { mapKey: 'threeD', mapNm: '3D 지도', mapLevelCd: '3D' },
  { mapKey: 'satellite', mapNm: '위성 영상', mapLevelCd: 'SAT' },
];

let measureIdCounter = 0;

export const useMapStore = create<MapState>((set, get) => ({
  mapToggles: { s57: false, s101: false, threeD: false, satellite: false },
  mapTypes: DEFAULT_MAP_TYPES,
  toggleMap: (key) =>
    set((s) => {
      const isCurrentlyOn = s.mapToggles[key];
      const allOff: MapToggles = { s57: false, s101: false, threeD: false, satellite: false };
      return {
        mapToggles: isCurrentlyOn ? allOff : { ...allOff, [key]: true },
      };
    }),
  loadMapTypes: async () => {
    try {
      const res = await api.get<MapTypeItem[]>('/map-base/active');
      const types = res.data;
      const current = get().mapToggles;
      const newToggles: Partial<MapToggles> = {};
      for (const t of types) {
        if (t.mapKey in current) {
          newToggles[t.mapKey as keyof MapToggles] = current[t.mapKey as keyof MapToggles] ?? false;
        }
      }
      // 모든 토글 기본 off (기본지도 표시)
      set({ mapTypes: types, mapToggles: { ...current, ...newToggles } });
    } catch {
      // API 실패 시 fallback 유지
    }
  },

  // 측정
  measureMode: null,
  measureInProgress: [],
  measurements: [],

  setMeasureMode: (mode) => set({ measureMode: mode, measureInProgress: [] }),

  addMeasurePoint: (pt) => {
    const { measureMode, measureInProgress } = get();
    if (measureMode === 'distance') {
      const next = [...measureInProgress, pt];
      if (next.length >= 2) {
        const dist = haversineDistance(next[0], next[1]);
        const id = `measure-${++measureIdCounter}`;
        set((s) => ({
          measurements: [
            ...s.measurements,
            { id, mode: 'distance', points: [next[0], next[1]], value: dist },
          ],
          measureInProgress: [],
        }));
      } else {
        set({ measureInProgress: next });
      }
    } else if (measureMode === 'area') {
      set({ measureInProgress: [...measureInProgress, pt] });
    }
  },

  commitAreaMeasurement: () => {
    const { measureInProgress } = get();
    if (measureInProgress.length < 3) return;
    const area = polygonAreaKm2(measureInProgress);
    const id = `measure-${++measureIdCounter}`;
    set((s) => ({
      measurements: [
        ...s.measurements,
        { id, mode: 'area', points: [...measureInProgress], value: area },
      ],
      measureInProgress: [],
    }));
  },

  removeMeasurement: (id) =>
    set((s) => ({ measurements: s.measurements.filter((m) => m.id !== id) })),

  clearAllMeasurements: () => set({ measurements: [], measureInProgress: [], measureMode: null }),
}));
