import { useState, useRef, useEffect } from 'react';
import { FiMic, FiSquare, FiPlay, FiPause, FiTrash2 } from 'react-icons/fi';

export interface AudioRecorderProps {
	onRecordingComplete: (audioBlob: Blob) => void;
	onError?: (error: string) => void;
	disabled?: boolean;
	className?: string;
}

export function AudioRecorder({ onRecordingComplete, onError, disabled = false, className = '' }: AudioRecorderProps) {
	const [isRecording, setIsRecording] = useState(false);
	const [isPaused, setIsPaused] = useState(false);
	const [recordingTime, setRecordingTime] = useState(0);
	const [audioUrl, setAudioUrl] = useState<string | null>(null);
	const [isPlaying, setIsPlaying] = useState(false);

	const mediaRecorderRef = useRef<MediaRecorder | null>(null);
	const audioChunksRef = useRef<Blob[]>([]);
	const streamRef = useRef<MediaStream | null>(null);
	const timerRef = useRef<NodeJS.Timeout | null>(null);
	const audioRef = useRef<HTMLAudioElement | null>(null);

	useEffect(() => {
		return () => {
			if (timerRef.current) {
				clearInterval(timerRef.current);
			}
			if (streamRef.current) {
				streamRef.current.getTracks().forEach(track => track.stop());
			}
			if (audioUrl) {
				URL.revokeObjectURL(audioUrl);
			}
		};
	}, [audioUrl]);

	const formatTime = (seconds: number): string => {
		const mins = Math.floor(seconds / 60);
		const secs = seconds % 60;
		return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
	};

	const startRecording = async () => {
		try {
			const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
			streamRef.current = stream;

			const mediaRecorder = new MediaRecorder(stream, {
				mimeType: 'audio/webm',
			});
			mediaRecorderRef.current = mediaRecorder;
			audioChunksRef.current = [];

			mediaRecorder.ondataavailable = event => {
				if (event.data.size > 0) {
					audioChunksRef.current.push(event.data);
				}
			};

			mediaRecorder.onstop = () => {
				const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' });
				const url = URL.createObjectURL(audioBlob);
				setAudioUrl(url);
				onRecordingComplete(audioBlob);
			};

			mediaRecorder.start();
			setIsRecording(true);
			setIsPaused(false);
			setRecordingTime(0);

			timerRef.current = setInterval(() => {
				setRecordingTime(prev => prev + 1);
			}, 1000);
		} catch (error) {
			const errorMessage = error instanceof Error ? error.message : 'Failed to access microphone';
			onError?.(errorMessage);
			console.error('Error starting recording:', error);
		}
	};

	const stopRecording = () => {
		if (mediaRecorderRef.current && isRecording) {
			mediaRecorderRef.current.stop();
			if (streamRef.current) {
				streamRef.current.getTracks().forEach(track => track.stop());
			}
			setIsRecording(false);
			setIsPaused(false);
			if (timerRef.current) {
				clearInterval(timerRef.current);
				timerRef.current = null;
			}
		}
	};

	const pauseRecording = () => {
		if (mediaRecorderRef.current && isRecording && !isPaused) {
			mediaRecorderRef.current.pause();
			setIsPaused(true);
			if (timerRef.current) {
				clearInterval(timerRef.current);
				timerRef.current = null;
			}
		}
	};

	const resumeRecording = () => {
		if (mediaRecorderRef.current && isRecording && isPaused) {
			mediaRecorderRef.current.resume();
			setIsPaused(false);
			timerRef.current = setInterval(() => {
				setRecordingTime(prev => prev + 1);
			}, 1000);
		}
	};

	const playRecording = () => {
		if (audioUrl && audioRef.current) {
			audioRef.current.play();
			setIsPlaying(true);
		}
	};

	const pausePlayback = () => {
		if (audioRef.current) {
			audioRef.current.pause();
			setIsPlaying(false);
		}
	};

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

	const clearRecording = () => {
		if (audioUrl) {
			URL.revokeObjectURL(audioUrl);
			setAudioUrl(null);
		}
		setRecordingTime(0);
		setIsPlaying(false);
		if (audioRef.current) {
			audioRef.current.pause();
			audioRef.current.currentTime = 0;
		}
	};

	return (
		<div className={`space-y-4 ${className}`}>
			<div className='flex items-center gap-4'>
				{!isRecording && !audioUrl && (
					<button
						type='button'
						onClick={startRecording}
						disabled={disabled}
						className='flex items-center gap-2 px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed'
					>
						<FiMic className='w-5 h-5' />
						Start Recording
					</button>
				)}

				{isRecording && (
					<>
						<button
							type='button'
							onClick={isPaused ? resumeRecording : pauseRecording}
							className='flex items-center gap-2 px-4 py-2 bg-yellow-500 text-white rounded-lg hover:bg-yellow-600 transition-colors'
						>
							{isPaused ? <FiPlay className='w-5 h-5' /> : <FiPause className='w-5 h-5' />}
							{isPaused ? 'Resume' : 'Pause'}
						</button>
						<button
							type='button'
							onClick={stopRecording}
							className='flex items-center gap-2 px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors'
						>
							<FiSquare className='w-5 h-5' />
							Stop Recording
						</button>
						<div className='flex items-center gap-2 text-text-primary font-mono'>
							<span className='w-3 h-3 bg-red-500 rounded-full animate-pulse'></span>
							<span>{formatTime(recordingTime)}</span>
						</div>
					</>
				)}

				{audioUrl && !isRecording && (
					<>
						<button
							type='button'
							onClick={isPlaying ? pausePlayback : playRecording}
							className='flex items-center gap-2 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors'
						>
							{isPlaying ? <FiPause className='w-5 h-5' /> : <FiPlay className='w-5 h-5' />}
							{isPlaying ? 'Pause' : 'Play'}
						</button>
						<button
							type='button'
							onClick={clearRecording}
							className='flex items-center gap-2 px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600 transition-colors'
						>
							<FiTrash2 className='w-5 h-5' />
							Clear
						</button>
					</>
				)}
			</div>

			{audioUrl && (
				<div className='space-y-2'>
					<audio ref={audioRef} src={audioUrl} onEnded={handleAudioEnded} controls className='w-full' />
				</div>
			)}
		</div>
	);
}
