import { useState, useRef, useEffect, useCallback } from 'react'
import { Button } from '@/components/ui/button'
import { Slider } from '@/components/ui/slider'
import { cn } from '@/lib/utils'
import { Play, Pause, Volume2, VolumeX, Loader2 } from 'lucide-react'

interface AudioPlayerProps {
    /** Audio source URL */
    src: string
    /** Optional title for accessibility */
    title?: string
    /** Additional CSS classes */
    className?: string
    /** Compact mode for smaller spaces */
    compact?: boolean
}

function formatTime(seconds: number): string {
    if (!isFinite(seconds) || isNaN(seconds)) return '0:00'
    const mins = Math.floor(seconds / 60)
    const secs = Math.floor(seconds % 60)
    return `${mins}:${secs.toString().padStart(2, '0')}`
}

export function AudioPlayer({ src, title, className, compact = false }: AudioPlayerProps) {
    const audioRef = useRef<HTMLAudioElement>(null)
    const [isPlaying, setIsPlaying] = useState(false)
    const [isBuffering, setIsBuffering] = useState(false)
    const [currentTime, setCurrentTime] = useState(0)
    const [duration, setDuration] = useState(0)
    const [volume, setVolume] = useState(1)
    const [isMuted, setIsMuted] = useState(false)
    const [error, setError] = useState<string | null>(null)

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

        const handleLoadedMetadata = () => {
            setDuration(audio.duration)
        }

        const handleDurationChange = () => {
            if (audio.duration && isFinite(audio.duration)) {
                setDuration(audio.duration)
            }
        }

        const handleTimeUpdate = () => {
            setCurrentTime(audio.currentTime)
        }

        const handleEnded = () => {
            setIsPlaying(false)
            setCurrentTime(0)
            audio.currentTime = 0
        }

        const handleError = () => {
            setError('Failed to load audio')
            setIsPlaying(false)
            setIsBuffering(false)
        }

        const handleWaiting = () => {
            setIsBuffering(true)
        }

        const handleCanPlay = () => {
            setIsBuffering(false)
        }

        const handlePlaying = () => {
            setIsBuffering(false)
            setIsPlaying(true)
        }

        const handlePause = () => {
            setIsPlaying(false)
        }

        audio.addEventListener('loadedmetadata', handleLoadedMetadata)
        audio.addEventListener('durationchange', handleDurationChange)
        audio.addEventListener('timeupdate', handleTimeUpdate)
        audio.addEventListener('ended', handleEnded)
        audio.addEventListener('error', handleError)
        audio.addEventListener('waiting', handleWaiting)
        audio.addEventListener('canplay', handleCanPlay)
        audio.addEventListener('playing', handlePlaying)
        audio.addEventListener('pause', handlePause)

        // Try to load metadata
        audio.load()

        return () => {
            audio.removeEventListener('loadedmetadata', handleLoadedMetadata)
            audio.removeEventListener('durationchange', handleDurationChange)
            audio.removeEventListener('timeupdate', handleTimeUpdate)
            audio.removeEventListener('ended', handleEnded)
            audio.removeEventListener('error', handleError)
            audio.removeEventListener('waiting', handleWaiting)
            audio.removeEventListener('canplay', handleCanPlay)
            audio.removeEventListener('playing', handlePlaying)
            audio.removeEventListener('pause', handlePause)
        }
    }, [src])

    // Sync volume with audio element
    useEffect(() => {
        const audio = audioRef.current
        if (audio) {
            audio.volume = isMuted ? 0 : volume
        }
    }, [volume, isMuted])

    const togglePlay = useCallback(async () => {
        const audio = audioRef.current
        if (!audio) return

        try {
            if (isPlaying) {
                audio.pause()
            } else {
                setIsBuffering(true)
                await audio.play()
            }
        } catch (err) {
            console.error('Playback error:', err)
            setError('Playback failed')
            setIsBuffering(false)
        }
    }, [isPlaying])

    const handleSeek = useCallback((value: number[]) => {
        const audio = audioRef.current
        if (!audio) return

        const newTime = value[0]
        audio.currentTime = newTime
        setCurrentTime(newTime)
    }, [])

    const toggleMute = useCallback(() => {
        setIsMuted(!isMuted)
    }, [isMuted])

    const handleVolumeChange = useCallback((value: number[]) => {
        const newVolume = value[0]
        setVolume(newVolume)
        if (newVolume > 0 && isMuted) {
            setIsMuted(false)
        }
    }, [isMuted])

    if (error) {
        return (
            <div className={cn('flex items-center gap-2 text-sm text-destructive p-2', className)}>
                <span>{error}</span>
            </div>
        )
    }

    // Compact mode - single row layout
    if (compact) {
        return (
            <div className={cn('flex items-center gap-2 w-full', className)}>
                <audio ref={audioRef} src={src} preload="metadata" />

                <Button
                    type="button"
                    variant="outline"
                    size="icon"
                    onClick={togglePlay}
                    className="h-8 w-8 shrink-0"
                    title={isPlaying ? 'Pause' : 'Play'}
                >
                    {isBuffering ? (
                        <Loader2 className="h-4 w-4 animate-spin" />
                    ) : isPlaying ? (
                        <Pause className="h-4 w-4" />
                    ) : (
                        <Play className="h-4 w-4" />
                    )}
                </Button>

                <Slider
                    value={[currentTime]}
                    max={duration || 100}
                    step={0.1}
                    onValueChange={handleSeek}
                    className="flex-1 min-w-[60px]"
                />

                <span className="text-xs text-muted-foreground tabular-nums whitespace-nowrap shrink-0">
                    {formatTime(currentTime)}/{formatTime(duration)}
                </span>
            </div>
        )
    }

    // Full mode - with volume control
    return (
        <div className={cn('rounded-lg border bg-card p-3 w-full', className)}>
            <audio ref={audioRef} src={src} preload="metadata" title={title} />

            <div className="flex items-center gap-3">
                {/* Play/Pause Button */}
                <Button
                    type="button"
                    variant="outline"
                    size="icon"
                    onClick={togglePlay}
                    className="h-10 w-10 shrink-0"
                    title={isPlaying ? 'Pause' : 'Play'}
                >
                    {isBuffering ? (
                        <Loader2 className="h-5 w-5 animate-spin" />
                    ) : isPlaying ? (
                        <Pause className="h-5 w-5" />
                    ) : (
                        <Play className="h-5 w-5" />
                    )}
                </Button>

                {/* Progress Section */}
                <div className="flex flex-1 flex-col gap-1 min-w-0">
                    <Slider
                        value={[currentTime]}
                        max={duration || 100}
                        step={0.1}
                        onValueChange={handleSeek}
                        className="w-full"
                    />
                    <div className="flex justify-between text-xs text-muted-foreground tabular-nums">
                        <span>{formatTime(currentTime)}</span>
                        <span>{formatTime(duration)}</span>
                    </div>
                </div>

                {/* Volume Control - hidden on mobile */}
                <div className="hidden sm:flex items-center gap-2">
                    <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        onClick={toggleMute}
                        className="h-8 w-8 shrink-0"
                        title={isMuted ? 'Unmute' : 'Mute'}
                    >
                        {isMuted || volume === 0 ? (
                            <VolumeX className="h-4 w-4" />
                        ) : (
                            <Volume2 className="h-4 w-4" />
                        )}
                    </Button>
                    <Slider
                        value={[isMuted ? 0 : volume]}
                        max={1}
                        step={0.01}
                        onValueChange={handleVolumeChange}
                        className="w-20"
                    />
                </div>
            </div>
        </div>
    )
}
