import { useMemo } from 'react';
import type { GeoJSON } from 'geojson';
import type { Ship, VesselAnalysisDto } from '../../types';
import type { GearCorrelationItem, CorrelationVesselTrack } from '../../services/vesselAnalysis';
import type { UseGroupPolygonsResult } from '../../hooks/useGroupPolygons';
import type { FleetListItem } from './fleetClusterTypes';
import { buildInterpPolygon } from './fleetClusterUtils';
import { MODEL_ORDER, MODEL_COLORS } from './fleetClusterConstants';

export interface UseFleetClusterGeoJsonParams {
  ships: Ship[];
  shipMap: Map<string, Ship>;
  groupPolygons: UseGroupPolygonsResult | undefined;
  analysisMap: Map<string, VesselAnalysisDto>;
  hoveredFleetId: number | null;
  selectedGearGroup: string | null;
  pickerHoveredGroup: string | null;
  historyActive: boolean;
  correlationData: GearCorrelationItem[];
  correlationTracks: CorrelationVesselTrack[];
  enabledModels: Set<string>;
  enabledVessels: Set<string>;
  hoveredMmsi: string | null;
}

export interface FleetClusterGeoJsonResult {
  // static/base GeoJSON
  fleetPolygonGeoJSON: GeoJSON;
  lineGeoJSON: GeoJSON;
  hoveredGeoJSON: GeoJSON;
  gearClusterGeoJson: GeoJSON;
  memberMarkersGeoJson: GeoJSON;
  pickerHighlightGeoJson: GeoJSON;
  selectedGearHighlightGeoJson: GeoJSON.FeatureCollection | null;
  // correlation GeoJSON
  correlationVesselGeoJson: GeoJSON;
  correlationTrailGeoJson: GeoJSON;
  modelBadgesGeoJson: GeoJSON;
  hoverHighlightGeoJson: GeoJSON;
  hoverHighlightTrailGeoJson: GeoJSON;
  // operational polygons (per model)
  operationalPolygons: { modelName: string; color: string; geojson: GeoJSON.FeatureCollection }[];
  // derived values
  fleetList: FleetListItem[];
  correlationByModel: Map<string, GearCorrelationItem[]>;
  availableModels: { name: string; count: number; isDefault: boolean }[];
}

const EMPTY_FC: GeoJSON = { type: 'FeatureCollection', features: [] };

export function useFleetClusterGeoJson(params: UseFleetClusterGeoJsonParams): FleetClusterGeoJsonResult {
  const {
    ships,
    shipMap,
    groupPolygons,
    hoveredFleetId,
    selectedGearGroup,
    pickerHoveredGroup,
    historyActive,
    correlationData,
    correlationTracks,
    enabledModels,
    enabledVessels,
    hoveredMmsi,
  } = params;

  // ── 선단 폴리곤 GeoJSON (서버 제공) ──
  const fleetPolygonGeoJSON = useMemo((): GeoJSON => {
    const features: GeoJSON.Feature[] = [];
    if (!groupPolygons) return { type: 'FeatureCollection', features };
    for (const g of groupPolygons.fleetGroups) {
      if (!g.polygon) continue;
      features.push({
        type: 'Feature',
        properties: { clusterId: Number(g.groupKey), color: g.color },
        geometry: g.polygon,
      });
    }
    return { type: 'FeatureCollection', features };
  }, [groupPolygons]);

  // 2척 선단 라인은 서버에서 Shapely buffer로 이미 Polygon 처리되므로 빈 컬렉션
  const lineGeoJSON = useMemo((): GeoJSON => ({
    type: 'FeatureCollection', features: [],
  }), []);

  // 호버 하이라이트용 단일 폴리곤
  const hoveredGeoJSON = useMemo((): GeoJSON => {
    if (hoveredFleetId === null || !groupPolygons) return EMPTY_FC;
    const g = groupPolygons.fleetGroups.find(f => Number(f.groupKey) === hoveredFleetId);
    if (!g?.polygon) return EMPTY_FC;
    return {
      type: 'FeatureCollection',
      features: [{
        type: 'Feature',
        properties: { clusterId: hoveredFleetId, color: g.color },
        geometry: g.polygon,
      }],
    };
  }, [hoveredFleetId, groupPolygons]);

  // 모델별 연관성 데이터 그룹핑
  const correlationByModel = useMemo(() => {
    const map = new Map<string, GearCorrelationItem[]>();
    for (const c of correlationData) {
      const list = map.get(c.modelName) ?? [];
      list.push(c);
      map.set(c.modelName, list);
    }
    return map;
  }, [correlationData]);

  // 사용 가능한 모델 목록 (데이터가 있는 모델만)
  const availableModels = useMemo(() => {
    const models: { name: string; count: number; isDefault: boolean }[] = [];
    for (const [name, items] of correlationByModel) {
      models.push({ name, count: items.length, isDefault: items[0]?.isDefault ?? false });
    }
    models.sort((a, b) => (a.isDefault ? -1 : 0) - (b.isDefault ? -1 : 0));
    return models;
  }, [correlationByModel]);

  // 오퍼레이셔널 폴리곤 (비재생 정적 연산)
  const operationalPolygons = useMemo(() => {
    if (!selectedGearGroup || !groupPolygons) return [];
    const allGroups = [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups];
    const group = allGroups.find(g => g.groupKey === selectedGearGroup);
    if (!group) return [];
    const basePts: [number, number][] = group.members.map(m => [m.lon, m.lat]);
    const result: { modelName: string; color: string; geojson: GeoJSON.FeatureCollection }[] = [];
    for (const [mn, items] of correlationByModel) {
      if (!enabledModels.has(mn)) continue;
      const extra: [number, number][] = [];
      for (const c of items) {
        if (c.score < 0.7) continue;
        const s = ships.find(x => x.mmsi === c.targetMmsi);
        if (s) extra.push([s.lng, s.lat]);
      }
      if (extra.length === 0) continue;
      const polygon = buildInterpPolygon([...basePts, ...extra]);
      if (!polygon) continue;
      const color = MODEL_COLORS[mn] ?? '#94a3b8';
      result.push({
        modelName: mn,
        color,
        geojson: {
          type: 'FeatureCollection',
          features: [{ type: 'Feature', properties: { modelName: mn, color }, geometry: polygon }],
        },
      });
    }
    return result;
  }, [selectedGearGroup, groupPolygons, correlationByModel, enabledModels, ships]);

  // 어구 클러스터 GeoJSON (서버 제공)
  const gearClusterGeoJson = useMemo((): GeoJSON => {
    const features: GeoJSON.Feature[] = [];
    if (!groupPolygons) return { type: 'FeatureCollection', features };
    for (const g of [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups]) {
      if (!g.polygon) continue;
      features.push({
        type: 'Feature',
        properties: {
          name: g.groupKey,
          gearCount: g.memberCount,
          inZone: g.groupType === 'GEAR_IN_ZONE' ? 1 : 0,
        },
        geometry: g.polygon,
      });
    }
    return { type: 'FeatureCollection', features };
  }, [groupPolygons]);

  // 가상 선박 마커 GeoJSON (API members + shipMap heading 보정)
  const memberMarkersGeoJson = useMemo((): GeoJSON => {
    const features: GeoJSON.Feature[] = [];
    if (!groupPolygons) return { type: 'FeatureCollection', features };

    const addMember = (
      m: { mmsi: string; name: string; lat: number; lon: number; cog: number; isParent: boolean; role: string },
      groupKey: string,
      groupType: string,
      color: string,
    ) => {
      const realShip = shipMap.get(m.mmsi);
      const heading = realShip?.heading ?? m.cog ?? 0;
      const lat = realShip?.lat ?? m.lat;
      const lon = realShip?.lng ?? m.lon;
      features.push({
        type: 'Feature',
        properties: {
          mmsi: m.mmsi,
          name: m.name,
          groupKey,
          groupType,
          role: m.role,
          isParent: m.isParent ? 1 : 0,
          isGear: (groupType !== 'FLEET' && !m.isParent) ? 1 : 0,
          color,
          cog: heading,
          baseSize: (groupType !== 'FLEET' && !m.isParent) ? 0.11 : m.isParent ? 0.18 : 0.14,
        },
        geometry: { type: 'Point', coordinates: [lon, lat] },
      });
    };

    for (const g of groupPolygons.fleetGroups) {
      for (const m of g.members) addMember(m, g.groupKey, 'FLEET', g.color);
    }
    for (const g of [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups]) {
      const color = g.groupType === 'GEAR_IN_ZONE' ? '#dc2626' : '#f97316';
      for (const m of g.members) addMember(m, g.groupKey, g.groupType, color);
    }
    return { type: 'FeatureCollection', features };
  }, [groupPolygons, shipMap]);

  // picker 호버 하이라이트 (선단 + 어구 통합)
  const pickerHighlightGeoJson = useMemo((): GeoJSON => {
    if (!pickerHoveredGroup || !groupPolygons) return EMPTY_FC;
    const fleet = groupPolygons.fleetGroups.find(x => String(x.groupKey) === pickerHoveredGroup);
    if (fleet?.polygon) return { type: 'FeatureCollection', features: [{ type: 'Feature', properties: {}, geometry: fleet.polygon }] };
    const all = [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups];
    const g = all.find(x => x.groupKey === pickerHoveredGroup);
    if (!g?.polygon) return EMPTY_FC;
    return { type: 'FeatureCollection', features: [{ type: 'Feature', properties: {}, geometry: g.polygon }] };
  }, [pickerHoveredGroup, groupPolygons]);

  // 선택된 어구 그룹 하이라이트 폴리곤
  const selectedGearHighlightGeoJson = useMemo((): GeoJSON.FeatureCollection | null => {
    if (!selectedGearGroup || !enabledModels.has('identity') || historyActive) return null;
    const allGroups = groupPolygons
      ? [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups]
      : [];
    const group = allGroups.find(g => g.groupKey === selectedGearGroup);
    if (!group?.polygon) return null;
    return {
      type: 'FeatureCollection',
      features: [{
        type: 'Feature',
        properties: {},
        geometry: group.polygon,
      }],
    };
  }, [selectedGearGroup, enabledModels, historyActive, groupPolygons]);

  // ── 연관 대상 마커 (ships[] fallback) ──
  const correlationVesselGeoJson = useMemo((): GeoJSON => {
    if (!selectedGearGroup || correlationByModel.size === 0) return EMPTY_FC;
    const features: GeoJSON.Feature[] = [];
    const seen = new Set<string>();

    for (const [mn, items] of correlationByModel) {
      if (!enabledModels.has(mn)) continue;
      const color = MODEL_COLORS[mn] ?? '#94a3b8';
      for (const c of items) {
        if (seen.has(c.targetMmsi)) continue;
        const s = ships.find(x => x.mmsi === c.targetMmsi);
        if (!s) continue;
        seen.add(c.targetMmsi);
        features.push({
          type: 'Feature',
          properties: {
            mmsi: c.targetMmsi,
            name: c.targetName || c.targetMmsi,
            score: c.score,
            cog: s.course ?? 0,
            color,
            isVessel: c.targetType === 'VESSEL' ? 1 : 0,
          },
          geometry: { type: 'Point', coordinates: [s.lng, s.lat] },
        });
      }
    }
    return { type: 'FeatureCollection', features };
  }, [selectedGearGroup, correlationByModel, enabledModels, ships]);

  // 연관 대상 트레일 (전체 항적)
  const correlationTrailGeoJson = useMemo((): GeoJSON => {
    if (correlationTracks.length === 0) return EMPTY_FC;
    const features: GeoJSON.Feature[] = [];
    const vesselColor = new Map<string, string>();
    for (const [mn, items] of correlationByModel) {
      if (!enabledModels.has(mn)) continue;
      for (const c of items) {
        if (!vesselColor.has(c.targetMmsi)) vesselColor.set(c.targetMmsi, MODEL_COLORS[mn] ?? '#60a5fa');
      }
    }
    for (const vt of correlationTracks) {
      if (!enabledVessels.has(vt.mmsi)) continue;
      const color = vesselColor.get(vt.mmsi) ?? '#60a5fa';
      const coords: [number, number][] = vt.track.map(pt => [pt.lon, pt.lat]);
      if (coords.length >= 2) {
        features.push({ type: 'Feature', properties: { mmsi: vt.mmsi, color }, geometry: { type: 'LineString', coordinates: coords } });
      }
    }
    return { type: 'FeatureCollection', features };
  }, [correlationTracks, enabledVessels, correlationByModel, enabledModels]);

  // 모델 배지 GeoJSON (groupPolygons 기반)
  const modelBadgesGeoJson = useMemo((): GeoJSON => {
    if (!selectedGearGroup) return EMPTY_FC;
    const targets = new Map<string, { lon: number; lat: number; models: Set<string> }>();

    if (enabledModels.has('identity') && groupPolygons) {
      const all = [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups];
      const members = all.find(g => g.groupKey === selectedGearGroup)?.members ?? [];
      for (const m of members) {
        const e = targets.get(m.mmsi) ?? { lon: m.lon, lat: m.lat, models: new Set<string>() };
        e.lon = m.lon; e.lat = m.lat; e.models.add('identity');
        targets.set(m.mmsi, e);
      }
    }
    for (const [mn, items] of correlationByModel) {
      if (!enabledModels.has(mn)) continue;
      for (const c of items) {
        if (c.score < 0.3) continue;
        const s = ships.find(x => x.mmsi === c.targetMmsi);
        if (!s) continue;
        const e = targets.get(c.targetMmsi) ?? { lon: s.lng, lat: s.lat, models: new Set<string>() };
        e.lon = s.lng; e.lat = s.lat; e.models.add(mn);
        targets.set(c.targetMmsi, e);
      }
    }
    const features: GeoJSON.Feature[] = [];
    for (const [mmsi, t] of targets) {
      if (t.models.size === 0) continue;
      const props: Record<string, unknown> = { mmsi };
      for (let i = 0; i < MODEL_ORDER.length; i++) props[`m${i}`] = t.models.has(MODEL_ORDER[i]) ? 1 : 0;
      features.push({ type: 'Feature', properties: props, geometry: { type: 'Point', coordinates: [t.lon, t.lat] } });
    }
    return { type: 'FeatureCollection', features };
  }, [selectedGearGroup, enabledModels, groupPolygons, correlationByModel, ships]);

  // 호버 하이라이트 — 대상 위치
  const hoverHighlightGeoJson = useMemo((): GeoJSON => {
    if (!hoveredMmsi || !selectedGearGroup) return EMPTY_FC;
    if (groupPolygons) {
      const all = [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups];
      const m = all.find(g => g.groupKey === selectedGearGroup)?.members.find(x => x.mmsi === hoveredMmsi);
      if (m) return { type: 'FeatureCollection', features: [{ type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: [m.lon, m.lat] } }] };
    }
    const s = ships.find(x => x.mmsi === hoveredMmsi);
    if (s) return { type: 'FeatureCollection', features: [{ type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: [s.lng, s.lat] } }] };
    return EMPTY_FC;
  }, [hoveredMmsi, selectedGearGroup, groupPolygons, ships]);

  // 호버 하이라이트 — 대상 항적
  const hoverHighlightTrailGeoJson = useMemo((): GeoJSON => {
    if (!hoveredMmsi) return EMPTY_FC;
    const vt = correlationTracks.find(v => v.mmsi === hoveredMmsi);
    if (!vt) return EMPTY_FC;
    const coords: [number, number][] = vt.track.map(pt => [pt.lon, pt.lat]);
    if (coords.length < 2) return EMPTY_FC;
    return { type: 'FeatureCollection', features: [{ type: 'Feature', properties: {}, geometry: { type: 'LineString', coordinates: coords } }] };
  }, [hoveredMmsi, correlationTracks]);

  // 선단 목록 (멤버 수 내림차순)
  const fleetList = useMemo((): FleetListItem[] => {
    if (!groupPolygons) return [];
    return groupPolygons.fleetGroups.map(g => ({
      id: Number(g.groupKey),
      mmsiList: g.members.map(m => m.mmsi),
      label: g.groupLabel,
      memberCount: g.memberCount,
      areaSqNm: g.areaSqNm,
      color: g.color,
      members: g.members,
    })).sort((a, b) => b.memberCount - a.memberCount);
  }, [groupPolygons]);

  return {
    fleetPolygonGeoJSON,
    lineGeoJSON,
    hoveredGeoJSON,
    gearClusterGeoJson,
    memberMarkersGeoJson,
    pickerHighlightGeoJson,
    selectedGearHighlightGeoJson,
    correlationVesselGeoJson,
    correlationTrailGeoJson,
    modelBadgesGeoJson,
    hoverHighlightGeoJson,
    hoverHighlightTrailGeoJson,
    operationalPolygons,
    fleetList,
    correlationByModel,
    availableModels,
  };
}
