import React, { useCallback, useEffect, useRef, useState } from 'react';
import ReactPlayer from 'react-player';

import { PauseIcon, PlayIcon } from '@/icons';

interface SyncedVideoAudioPlayerProps {
  videoUrl: string;
  audioUrl: string;
  imageUrl?: string;
  className?: string;
}

function formatTime(secs: number) {
  const m = Math.floor(secs / 60)
    .toString()
    .padStart(2, '0');
  const s = Math.floor(secs % 60)
    .toString()
    .padStart(2, '0');
  return `${m}:${s}`;
}

const SyncedVideoAudioPlayer: React.FC<SyncedVideoAudioPlayerProps> = ({
  videoUrl,
  audioUrl,
  imageUrl,
  className,
}) => {
  const videoRef = useRef<ReactPlayer>(null);
  const audioRef = useRef<HTMLAudioElement>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [videoDuration, setVideoDuration] = useState(1);
  const [audioDuration, setAudioDuration] = useState(1);
  const [currentTime, setCurrentTime] = useState(0);
  const [isVideoReady, setIsVideoReady] = useState(false);

  const handlePlay = useCallback(() => {
    setIsPlaying(true);
    if (audioRef.current) {
      audioRef.current.play();
    }
  }, []);

  const handlePause = useCallback(() => {
    setIsPlaying(false);
    if (audioRef.current) {
      audioRef.current.pause();
    }
  }, []);

  // Sync video with audio time - only seek when necessary
  useEffect(() => {
    if (!isPlaying || !audioRef.current || !isVideoReady) return;

    const handleTimeUpdate = () => {
      const audioTime = audioRef.current?.currentTime || 0;
      setCurrentTime(audioTime);

      // Only seek video if it's significantly out of sync
      if (videoRef.current && videoDuration > 0) {
        const expectedVideoTime = audioTime % videoDuration;
        const currentVideoTime = videoRef.current.getCurrentTime();

        // Check if video is more than 0.5 seconds out of sync
        const timeDiff = Math.abs(expectedVideoTime - currentVideoTime);
        if (timeDiff > 0.5) {
          videoRef.current.seekTo(expectedVideoTime);
        }
      }
    };

    const interval = setInterval(handleTimeUpdate, 500); // Less frequent updates
    return () => clearInterval(interval);
  }, [isPlaying, videoDuration, isVideoReady]);

  // Handle audio events
  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) return;

    const handleEnded = () => {
      setIsPlaying(false);
    };

    audio.addEventListener('ended', handleEnded);

    return () => {
      audio.removeEventListener('ended', handleEnded);
    };
  }, []);

  useEffect(() => {
    if (isVideoReady && videoDuration > 0 && audioRef.current) {
      const audioTime = audioRef.current.currentTime || 0;
      const videoTime = audioTime % videoDuration;
      if (videoRef.current) {
        videoRef.current.seekTo(videoTime);
      }
    }
  }, [isVideoReady, videoDuration]);

  return (
    <div className={`relative ${className}`}>
      {/* Hidden audio element */}
      <audio
        ref={audioRef}
        src={audioUrl}
        preload='metadata'
        onLoadedMetadata={() => {
          if (audioRef.current) {
            setAudioDuration(audioRef.current.duration);
          }
        }}
      />

      {/* Video player */}
      <ReactPlayer
        ref={videoRef}
        url={videoUrl}
        light={(!isPlaying && imageUrl) || false}
        playing={isPlaying}
        volume={0}
        muted={true}
        width='100%'
        height='100%'
        playIcon={<></>}
        loop={true}
        onDuration={setVideoDuration}
        onReady={() => setIsVideoReady(true)}
        playsinline={true}
        config={{
          file: {
            attributes: {
              style: {
                objectFit: 'cover',
                width: '100%',
                height: '100%',
                borderRadius: '5%',
              },
              poster: imageUrl,
            },
          },
        }}
      />

      {/* Custom controls */}
      <div className='absolute right-0 bottom-0 left-0 bg-black/50 p-2'>
        <div className='flex items-center gap-2'>
          <button
            onClick={isPlaying ? handlePause : handlePlay}
            className='flex items-center justify-center rounded-full bg-white/20 p-2 text-white hover:bg-white/30'
            style={{ width: 36, height: 36 }}
            aria-label={isPlaying ? 'Pause' : 'Play'}
          >
            {isPlaying ? (
              <PauseIcon className='h-6 w-6 text-white' />
            ) : (
              <PlayIcon className='h-6 w-6 text-white' />
            )}
          </button>
          <div className='h-2 flex-1 rounded-full bg-white/20'>
            <div
              className='h-2 rounded-full bg-white transition-all duration-100'
              style={{ width: `${(currentTime / audioDuration) * 100}%` }}
            />
          </div>
          <span
            className='font-mono text-xs text-white'
            style={{ minWidth: 60, textAlign: 'right' }}
          >
            {formatTime(currentTime)} / {formatTime(audioDuration)}
          </span>
        </div>
      </div>
    </div>
  );
};

export default SyncedVideoAudioPlayer;
