'use client';

import { useEffect, useRef } from 'react';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setProgress, setIsPlaying, playNext } from '@/store/slices/playerSlice';
import { audioPlayer } from '@/lib/audioPlayer';
import { ignoreNextAudioPause, setIgnoreAudioPause } from '@/lib/audioPlayerState';

export function useAudioSync() {
  const dispatch = useAppDispatch();
  const { currentTrack, isPlaying, volume, type, isRepeat } = useAppSelector((s) => s.player);

  const prevTrackId = useRef<string | null>(null);
  const isNewTrack = useRef(false);

  // Mirror isRepeat into a ref so the audio 'ended' handler (registered once)
  // always sees the latest value without needing to re-register.
  const isRepeatRef = useRef(isRepeat);
  useEffect(() => { isRepeatRef.current = isRepeat; }, [isRepeat]);

  // 1. New audio track → start playback
  useEffect(() => {
    if (!currentTrack || type !== 'audio') return;
    if (currentTrack.id === prevTrackId.current) return;

    prevTrackId.current = currentTrack.id;
    isNewTrack.current = true;

    const url = currentTrack.audioUrl;
    if (url) {
      audioPlayer.play(url).finally(() => { isNewTrack.current = false; });
    } else {
      isNewTrack.current = false;
    }
  }, [currentTrack, type]);

  // 2. Play/pause toggle (only when audio is active)
  useEffect(() => {
    if (type !== 'audio') return;
    if (isNewTrack.current) return;
    isPlaying ? audioPlayer.resume() : audioPlayer.pause();
  }, [isPlaying, type]);

  // 3. Stop audio when video/short takes over
  useEffect(() => {
    if (type !== 'audio') {
      setIgnoreAudioPause(true);
      audioPlayer.pause();
    }
  }, [type]);

  // 4. Volume sync
  useEffect(() => {
    audioPlayer.setVolume(volume);
  }, [volume]);

  // 5. HTML5 audio events → Redux
  useEffect(() => {
    const audio = audioPlayer.audio;

    const onTimeUpdate = () => {
      if (!audio.duration || isNaN(audio.duration)) return;
      dispatch(setProgress((audio.currentTime / audio.duration) * 100));
    };

    const onEnded = () => {
      if (isRepeatRef.current) {
        // Loop: seek back to the beginning and resume — do NOT advance the queue
        audioPlayer.seek(0);
        audioPlayer.audio.play().catch(() => {});
        dispatch(setProgress(0));
        dispatch(setIsPlaying(true));
        return;
      }
      // Not repeating — stop and advance to the next queued track
      dispatch(setIsPlaying(false));
      dispatch(playNext());
    };

    const onPlay  = () => dispatch(setIsPlaying(true));

    const onPause = () => {
      if (ignoreNextAudioPause) {
        setIgnoreAudioPause(false);
        return;
      }
      dispatch(setIsPlaying(false));
    };

    audio.addEventListener('timeupdate', onTimeUpdate);
    audio.addEventListener('ended',      onEnded);
    audio.addEventListener('play',       onPlay);
    audio.addEventListener('pause',      onPause);

    return () => {
      audio.removeEventListener('timeupdate', onTimeUpdate);
      audio.removeEventListener('ended',      onEnded);
      audio.removeEventListener('play',       onPlay);
      audio.removeEventListener('pause',      onPause);
    };
  }, [dispatch]);
}
