import { useMemo } from 'react';
import { getCurrentPositions } from '../lib/interpolate';
import { createReplayTrailLayer } from '../layers/replayLayers';
import { createDynamicTrackLayers, createStaticTrackLayers } from '../layers/trackLayers';
import type { CurrentVesselPosition, ProcessedTrack } from '../model/track.types';
import { useTrackPlaybackStore } from '../stores/trackPlaybackStore';
import { useTrackQueryStore } from '../stores/trackQueryStore';

export interface TrackReplayDeckRenderState {
  trackReplayDeckLayers: unknown[];
  enabledTracks: ProcessedTrack[];
  currentPositions: CurrentVesselPosition[];
  showPoints: boolean;
  showVirtualShip: boolean;
  showLabels: boolean;
  renderEpoch: number;
}

export function useTrackReplayDeckLayers(): TrackReplayDeckRenderState {
  const tracks = useTrackQueryStore((state) => state.tracks);
  const disabledVesselIds = useTrackQueryStore((state) => state.disabledVesselIds);
  const highlightedVesselId = useTrackQueryStore((state) => state.highlightedVesselId);
  const setHighlightedVesselId = useTrackQueryStore((state) => state.setHighlightedVesselId);
  const showPoints = useTrackQueryStore((state) => state.showPoints);
  const showVirtualShip = useTrackQueryStore((state) => state.showVirtualShip);
  const showLabels = useTrackQueryStore((state) => state.showLabels);
  const showTrail = useTrackQueryStore((state) => state.showTrail);
  const renderEpoch = useTrackQueryStore((state) => state.renderEpoch);

  const isPlaying = useTrackPlaybackStore((state) => state.isPlaying);
  const currentTime = useTrackPlaybackStore((state) => state.currentTime);

  const playbackRenderTime = useMemo(() => {
    if (!isPlaying) return currentTime;
    // Throttle to ~10fps while playing to reduce relayout pressure.
    return Math.floor(currentTime / 100) * 100;
  }, [isPlaying, currentTime]);

  const enabledTracks = useMemo(() => {
    if (!tracks.length) return [];
    if (disabledVesselIds.size === 0) return tracks;
    return tracks.filter((track) => !disabledVesselIds.has(track.vesselId));
  }, [tracks, disabledVesselIds]);

  const currentPositions = useMemo(() => {
    void renderEpoch;
    if (enabledTracks.length === 0) return [];
    const sampled = getCurrentPositions(enabledTracks, playbackRenderTime);
    if (sampled.length > 0 || isPlaying) return sampled;

    // Ensure an immediate first-frame marker when query data arrives but
    // playback has not started yet (globe static-render case).
    return enabledTracks.flatMap((track) => {
      if (track.geometry.length === 0) return [];
      const firstTs = track.timestampsMs[0] ?? playbackRenderTime;
      return [
        {
          vesselId: track.vesselId,
          targetId: track.targetId,
          sigSrcCd: track.sigSrcCd,
          shipName: track.shipName,
          shipKindCode: track.shipKindCode,
          nationalCode: track.nationalCode,
          position: track.geometry[0],
          heading: 0,
          speed: track.speeds[0] ?? 0,
          timestamp: firstTs,
        } as CurrentVesselPosition,
      ];
    });
  }, [enabledTracks, playbackRenderTime, isPlaying, renderEpoch]);

  const staticLayers = useMemo(
    () => {
      void renderEpoch;
      return createStaticTrackLayers({
        tracks: enabledTracks,
        showPoints,
        highlightedVesselId,
        onPathHover: setHighlightedVesselId,
      });
    },
    [enabledTracks, showPoints, highlightedVesselId, setHighlightedVesselId, renderEpoch],
  );

  const dynamicLayers = useMemo(
    () => {
      void renderEpoch;
      return createDynamicTrackLayers({
        currentPositions,
        showVirtualShip,
        showLabels,
        onPathHover: setHighlightedVesselId,
      });
    },
    [currentPositions, showVirtualShip, showLabels, setHighlightedVesselId, renderEpoch],
  );

  const trailLayer = useMemo(
    () => {
      void renderEpoch;
      return createReplayTrailLayer({
        tracks: enabledTracks,
        currentTime: playbackRenderTime,
        showTrail,
      });
    },
    [enabledTracks, playbackRenderTime, showTrail, renderEpoch],
  );

  const trackReplayDeckLayers = useMemo(
    () => [...staticLayers, ...(trailLayer ? [trailLayer] : []), ...dynamicLayers],
    [staticLayers, dynamicLayers, trailLayer],
  );

  return {
    trackReplayDeckLayers,
    enabledTracks,
    currentPositions,
    showPoints,
    showVirtualShip,
    showLabels,
    renderEpoch,
  };
}
