/**
 * 클라이언트 지리정보 스토어 (Zustand)
 *
 * 폴더 선택으로 파싱한 드론 프레임 / POI / 측점 / 중심선 / ENU 원점을 보관한다.
 * 4개 소비 컴포넌트(GeoSearch / StationVerify / StationOverlay / RoutePanel)가
 * 이 스토어를 단일 소스로 구독한다(서버 /api/geo/* 대체).
 *
 * playerStore.ts 패턴을 따른다.
 *
 * POI 위치 보정(poiOverrides): 마우스 드래그로 만든 title→{lat,lon,z} 맵.
 *   basePois(파싱 원본)에 applyPoiOverrides 를 적용한 결과가 pois 다.
 *   내보내기/가져오기 파일(`<base>_poi_overrides.json`)로 영속화한다.
 */

import { create } from 'zustand';
import type {
  DroneFrame,
  GeoPoint,
  CenterlinePoint,
  GeoOrigin,
  RouteMeta,
  RouteStructure,
  DirectionChange,
  PoiOverride,
  PoiOverrideMap,
} from '../types/geo';
import { loadFolderGeoData, applyPoiOverrides } from '../utils/geoData';

interface GeoStore {
  loaded: boolean;
  frames: DroneFrame[];
  pois: GeoPoint[]; // type==='poi' (poiOverrides 적용 결과)
  basePois: GeoPoint[]; // 파싱 원본 (보정 전) — 보정 재적용용
  poiOverrides: PoiOverrideMap; // title → {lat,lon,z}
  stations: GeoPoint[]; // type==='station' (stationOrder 정렬)
  centerline: CenterlinePoint[];
  origin: GeoOrigin | null;
  baseName: string | null;
  routeMeta: RouteMeta | null;
  /** v2.0 CSV(03)교량/04)터널/06)구교) 유래 구조물 + route.json 보정. */
  structures: RouteStructure[];
  /** 측점 비고에서 추출한 방향전환점 목록. */
  directionChanges: DirectionChange[];

  /**
   * 폴더 선택 파일에서 지리정보를 파싱해 스토어에 적재한다.
   * 발견한 영상 File 을 반환(없으면 null) — 호출자가 loadLocalFile 로 재생.
   */
  loadFromFolder: (files: FileList | File[]) => Promise<File | null>;
  /** 단일 POI 보정 설정/갱신 (드래그 종료 시). title 키. */
  setPoiOverride: (title: string, ov: PoiOverride) => void;
  /** 단일 POI 보정 해제. */
  clearPoiOverride: (title: string) => void;
  /** 보정맵 전체 교체 (가져오기). */
  setPoiOverrides: (map: PoiOverrideMap) => void;
  clear: () => void;
}

const EMPTY = {
  loaded: false,
  frames: [] as DroneFrame[],
  pois: [] as GeoPoint[],
  basePois: [] as GeoPoint[],
  poiOverrides: {} as PoiOverrideMap,
  stations: [] as GeoPoint[],
  centerline: [] as CenterlinePoint[],
  origin: null as GeoOrigin | null,
  baseName: null as string | null,
  routeMeta: null as RouteMeta | null,
  structures: [] as RouteStructure[],
  directionChanges: [] as DirectionChange[],
};

export const useGeoStore = create<GeoStore>((set) => ({
  ...EMPTY,

  loadFromFolder: async (files) => {
    const data = await loadFolderGeoData(files);
    set({
      loaded: true,
      frames: data.frames,
      basePois: data.pois,
      poiOverrides: data.poiOverrides,
      pois: applyPoiOverrides(data.pois, data.poiOverrides),
      stations: data.stations,
      centerline: data.centerline,
      origin: data.origin,
      baseName: data.baseName,
      routeMeta: data.routeMeta,
      structures: data.structures,
      directionChanges: data.directionChanges,
    });
    return data.videoFile;
  },

  setPoiOverride: (title, ov) =>
    set((s) => {
      const poiOverrides = { ...s.poiOverrides, [title]: ov };
      return { poiOverrides, pois: applyPoiOverrides(s.basePois, poiOverrides) };
    }),

  clearPoiOverride: (title) =>
    set((s) => {
      const poiOverrides = { ...s.poiOverrides };
      delete poiOverrides[title];
      return { poiOverrides, pois: applyPoiOverrides(s.basePois, poiOverrides) };
    }),

  setPoiOverrides: (map) =>
    set((s) => ({ poiOverrides: map, pois: applyPoiOverrides(s.basePois, map) })),

  clear: () => set({ ...EMPTY }),
}));
