import { useCallback, useEffect, useMemo, useRef } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import { ContextType } from '@/logging/contextTypes';
import { eventLogger } from '@/utils/event-logger';
import { EventNames } from '@/utils/event-names';

export function useStudioTimelineAnalytics(
  studioProjectId: string,
  studioProjectSessionId: string
) {
  const { session } = useStores();

  // Timeline playback tracking state
  const timelineSessionStarted = useRef<boolean>(false);
  const timelinePlaybackStartTime = useRef<number | null>(null);

  // Common base event structure for all timeline analytics events
  const baseEvent = useMemo(
    () => ({
      songSessionId: studioProjectSessionId,
      hasClip: false,
      songId: null,
      contextId: studioProjectId,
      contextType: ContextType.StudioNewTimeline,
      isAudioElementNull: false,
      isUserSongOwner: true, // User owns their studio project
      volume: 100,
      clickSourceUrl: location.pathname,
      isAutoplayOn: false,
      isRepeatOn: false,
      userId: session?.userId,
      previousSongSessionId: null,
      actionIndex: -1,
      songLength: 0, // Timeline doesn't have a fixed length
      studioProjectSessionId: studioProjectSessionId,
    }),
    [studioProjectSessionId, studioProjectId, session?.userId]
  );

  // Reset timeline session when studio project session changes
  useEffect(() => {
    timelineSessionStarted.current = false;
    timelinePlaybackStartTime.current = null;
  }, [studioProjectSessionId]);

  const onTimelinePlayStart = useCallback(
    (currentTimeSeconds: number) => {
      timelinePlaybackStartTime.current = currentTimeSeconds;

      // Log timeline play event
      const isFirstPlay = !timelineSessionStarted.current;
      timelineSessionStarted.current = true;

      const playEvent = {
        ...baseEvent,
        isPlaying: true,
        audioElementCurrentTime: currentTimeSeconds,
        actionName: isFirstPlay ? 'PlayNewSong' : 'PlaySong',
      };

      eventLogger.segmentTrack(EventNames.audioPlayerEvent, playEvent, session);
    },
    [baseEvent, session]
  );

  const onTimelinePlayStop = useCallback(
    (currentTimeSeconds: number) => {
      if (timelinePlaybackStartTime.current === null) return;

      const endTimeSeconds = currentTimeSeconds;
      const startTimeSeconds = timelinePlaybackStartTime.current;
      const playDuration = endTimeSeconds - startTimeSeconds;

      if (playDuration <= 0) {
        return;
      }

      const pauseEvent = {
        ...baseEvent,
        isPlaying: false,
        audioElementCurrentTime: endTimeSeconds,
        actionName: 'PauseSong',
        startTime: startTimeSeconds,
        endTime: endTimeSeconds,
        playDuration: playDuration,
      };

      eventLogger.segmentTrack(
        EventNames.audioPlayerEvent,
        pauseEvent,
        session
      );
      timelinePlaybackStartTime.current = null;
    },
    [baseEvent, session]
  );

  // Cleanup timeline tracking on unmount or when playback is active
  const onCleanup = useCallback(
    (currentTimeSeconds: number, isPlaying: boolean) => {
      if (timelinePlaybackStartTime.current !== null && isPlaying) {
        const endTimeSeconds = currentTimeSeconds;
        const startTimeSeconds = timelinePlaybackStartTime.current;
        const playDuration = endTimeSeconds - startTimeSeconds;

        if (playDuration <= 0) {
          return;
        }

        const cleanupPauseEvent = {
          ...baseEvent,
          isPlaying: false,
          audioElementCurrentTime: endTimeSeconds,
          actionName: 'PauseSong',
          startTime: startTimeSeconds,
          endTime: endTimeSeconds,
          playDuration: playDuration,
        };

        eventLogger.segmentTrack(
          EventNames.audioPlayerEvent,
          cleanupPauseEvent,
          session
        );
      }
    },
    [baseEvent, session]
  );

  const onSeekStart = useCallback(
    (currentTimeSeconds: number) => {
      if (timelinePlaybackStartTime.current === null) return;

      const startTimeSeconds = timelinePlaybackStartTime.current;
      const playDuration = currentTimeSeconds - startTimeSeconds;

      if (playDuration <= 0) {
        return;
      }

      const seekPauseEvent = {
        ...baseEvent,
        isPlaying: false,
        audioElementCurrentTime: currentTimeSeconds,
        actionName: 'SeekProgressBarPauseSong',
        startTime: startTimeSeconds,
        endTime: currentTimeSeconds,
        playDuration: playDuration,
      };

      eventLogger.segmentTrack(
        EventNames.audioPlayerEvent,
        seekPauseEvent,
        session
      );
    },
    [baseEvent, session]
  );

  const onSeekEnd = useCallback(
    (newStartTimeSeconds: number) => {
      // Update the playback start time for future duration calculations
      timelinePlaybackStartTime.current = newStartTimeSeconds;

      const seekPlayEvent = {
        ...baseEvent,
        isPlaying: true,
        audioElementCurrentTime: newStartTimeSeconds,
        actionName: 'SeekProgressBarPlaySong',
      };

      eventLogger.segmentTrack(
        EventNames.audioPlayerEvent,
        seekPlayEvent,
        session
      );
    },
    [baseEvent, session]
  );

  return useMemo(
    () => ({
      onTimelinePlayStart,
      onTimelinePlayStop,
      onCleanup,
      onSeekStart,
      onSeekEnd,
    }),
    [onTimelinePlayStart, onTimelinePlayStop, onCleanup, onSeekStart, onSeekEnd]
  );
}
