'use client';

import { useState, useRef, useEffect, forwardRef, useImperativeHandle } from 'react';

interface AudioPlayerProps {
    src: string;
    unlockedSeconds: number; // 2, 4, 7, 11, 16, 30 (or full length)
    startTime?: number; // Start offset in seconds (for curated specials)
    onPlay?: () => void;
    onReplay?: () => void;
    autoPlay?: boolean;
    onHasPlayedChange?: (hasPlayed: boolean) => void;
}

export interface AudioPlayerRef {
    play: () => void;
}

const AudioPlayer = forwardRef<AudioPlayerRef, AudioPlayerProps>(({ src, unlockedSeconds, startTime = 0, onPlay, onReplay, autoPlay = false, onHasPlayedChange }, ref) => {
    const audioRef = useRef<HTMLAudioElement>(null);
    const [isPlaying, setIsPlaying] = useState(false);
    const [progress, setProgress] = useState(0);
    const [hasPlayedOnce, setHasPlayedOnce] = useState(false);

    const [processedSrc, setProcessedSrc] = useState<string | null>(null);
    const [processedUnlockedSeconds, setProcessedUnlockedSeconds] = useState<number | null>(null);

    useEffect(() => {
        console.log('[AudioPlayer] MOUNTED');
        return () => console.log('[AudioPlayer] UNMOUNTED');
    }, []);

    useEffect(() => {
        if (audioRef.current) {
            // Check if props changed compared to what we last processed
            const hasChanged = src !== processedSrc || unlockedSeconds !== processedUnlockedSeconds;

            if (hasChanged) {
                audioRef.current.pause();

                let startPos = startTime;

                // If same song but more time unlocked, start from where previous segment ended
                if (processedSrc !== null && src === processedSrc && processedUnlockedSeconds !== null && unlockedSeconds > processedUnlockedSeconds) {
                    startPos = startTime + processedUnlockedSeconds;
                }

                const targetPos = startPos;
                audioRef.current.currentTime = targetPos;

                // Ensure position is set correctly even if browser resets it
                setTimeout(() => {
                    if (audioRef.current && Math.abs(audioRef.current.currentTime - targetPos) > 0.5) {
                        audioRef.current.currentTime = targetPos;
                    }
                }, 50);

                setIsPlaying(false);

                // Calculate initial progress
                const initialElapsed = startPos - startTime;
                const initialPercent = unlockedSeconds > 0 ? (initialElapsed / unlockedSeconds) * 100 : 0;
                setProgress(Math.min(initialPercent, 100));

                // Only reset hasPlayedOnce if the song changed, not if just more time was unlocked
                if (processedSrc !== null && src !== processedSrc) {
                    setHasPlayedOnce(false); // Reset for new song
                    onHasPlayedChange?.(false); // Notify parent
                }

                // Update processed state
                setProcessedSrc(src);
                setProcessedUnlockedSeconds(unlockedSeconds);

                if (autoPlay) {
                    // Delay play slightly to ensure currentTime sticks
                    setTimeout(() => {
                        if (audioRef.current) {
                            // Use startPos (which may be startTime + processedUnlockedSeconds if more time was unlocked)
                            // instead of always using startTime
                            audioRef.current.currentTime = startPos;
                            const playPromise = audioRef.current.play();
                            if (playPromise !== undefined) {
                                playPromise
                                    .then(() => {
                                        setIsPlaying(true);
                                        onPlay?.();
                                        setHasPlayedOnce(true);
                                        onHasPlayedChange?.(true); // Notify parent
                                    })
                                    .catch(error => {
                                        console.log("Autoplay prevented:", error);
                                        setIsPlaying(false);
                                    });
                            }
                        }
                    }, 150);
                }
            } else if (startTime !== undefined && startTime > 0) {
                // If startTime is set and we haven't processed changes, ensure currentTime is at least at startTime
                // This handles the case where the audio element was reset or reloaded, or when manually playing for the first time
                const current = audioRef.current.currentTime;
                if (current < startTime) {
                    audioRef.current.currentTime = startTime;
                }
            }
        }
    }, [src, unlockedSeconds, startTime, autoPlay, processedSrc, processedUnlockedSeconds]);

    // Expose play method to parent component
    useImperativeHandle(ref, () => ({
        play: () => {
            if (!audioRef.current) return;

            // Check if we need to reset to startTime
            const current = audioRef.current.currentTime;
            const elapsed = current - startTime;
            
            // Reset if: never played before, current position is before startTime, or we've exceeded the unlocked segment
            if (!hasPlayedOnce || current < startTime || elapsed >= unlockedSeconds) {
                // Reset to start of segment
                audioRef.current.currentTime = startTime;
            }
            
            const playPromise = audioRef.current.play();
            if (playPromise !== undefined) {
                playPromise
                    .then(() => {
                        setIsPlaying(true);
                        onPlay?.();
                        if (!hasPlayedOnce) {
                            setHasPlayedOnce(true);
                            onHasPlayedChange?.(true);
                        }
                    })
                    .catch(error => {
                        console.error("Play failed:", error);
                        setIsPlaying(false);
                    });
            }
        }
    }));

    const togglePlay = () => {
        if (!audioRef.current) return;

        if (isPlaying) {
            audioRef.current.pause();
            setIsPlaying(false);
        } else {
            // Ensure we're at the correct position before playing
            const current = audioRef.current.currentTime;
            const elapsed = current - startTime;
            
            // Determine target position
            let targetPos = startTime;
            
            // If we've played before and we're within the unlocked segment, continue from current position
            if (hasPlayedOnce && current >= startTime && elapsed < unlockedSeconds) {
                targetPos = current; // Continue from current position
            } else {
                // Reset to start of segment if: never played, before startTime, or exceeded unlocked segment
                targetPos = startTime;
            }
            
            // Set position before playing
            audioRef.current.currentTime = targetPos;
            
            // Ensure position sticks (browser might reset it)
            setTimeout(() => {
                if (audioRef.current && Math.abs(audioRef.current.currentTime - targetPos) > 0.5) {
                    audioRef.current.currentTime = targetPos;
                }
            }, 50);
            
            audioRef.current.play();
            setIsPlaying(true);
            onPlay?.();

            if (hasPlayedOnce) {
                onReplay?.();
            } else {
                setHasPlayedOnce(true);
                onHasPlayedChange?.(true); // Notify parent
            }
        }
    };

    const handleTimeUpdate = () => {
        if (!audioRef.current) return;

        const current = audioRef.current.currentTime;
        const elapsed = current - startTime;
        const percent = (elapsed / unlockedSeconds) * 100;
        setProgress(Math.min(percent, 100));

        if (elapsed >= unlockedSeconds) {
            audioRef.current.pause();
            audioRef.current.currentTime = startTime;
            setIsPlaying(false);
            setProgress(0);
        }
    };

    return (
        <div className="audio-player">
            <audio
                ref={audioRef}
                src={src}
                onTimeUpdate={handleTimeUpdate}
                onEnded={() => setIsPlaying(false)}
            />

            <div className="player-controls">
                <button onClick={togglePlay} className="play-button">
                    {isPlaying ? (
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" width="24" height="24">
                            <path strokeLinecap="round" strokeLinejoin="round" d="M15.75 5.25v13.5m-7.5-13.5v13.5" />
                        </svg>
                    ) : (
                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" width="24" height="24" style={{ marginLeft: '4px' }}>
                            <path strokeLinecap="round" strokeLinejoin="round" d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.348a1.125 1.125 0 010 1.971l-11.54 6.347a1.125 1.125 0 01-1.667-.985V5.653z" />
                        </svg>
                    )}
                </button>

                <div className="progress-bar-container">
                    <div
                        className="progress-bar"
                        style={{ width: `${progress}%` }}
                    />
                </div>

                <div style={{ fontFamily: 'monospace', fontSize: '0.875rem', color: '#4b5563' }}>
                    {unlockedSeconds}s
                </div>
            </div>
        </div>
    );
});

AudioPlayer.displayName = 'AudioPlayer';



export default AudioPlayer;
