/**
 * AudioRecorder Component
 * 
 * Records audio using MediaRecorder API and automatically uploads to server.
 * Handles browser permissions, recording state, and error scenarios.
 */

function AudioRecorder({ noteId, onRecordingComplete, onCancel }) {
    const [isRecording, setIsRecording] = React.useState(false);
    const [duration, setDuration] = React.useState(0);
    const [status, setStatus] = React.useState('Ready to record');
    const [error, setError] = React.useState(null);
    const [isUploading, setIsUploading] = React.useState(false);

    const mediaRecorderRef = React.useRef(null);
    const audioChunksRef = React.useRef([]);
    const timerRef = React.useRef(null);
    const streamRef = React.useRef(null);

    // Cleanup on unmount
    React.useEffect(() => {
        return () => {
            if (timerRef.current) {
                clearInterval(timerRef.current);
            }
            if (streamRef.current) {
                streamRef.current.getTracks().forEach(track => track.stop());
            }
        };
    }, []);

    // Check browser compatibility
    const checkBrowserSupport = () => {
        if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
            setError('Audio recording not supported in this browser');
            setStatus('Browser not supported');
            return false;
        }

        if (typeof MediaRecorder === 'undefined') {
            setError('MediaRecorder API not available');
            setStatus('Recording not available');
            return false;
        }

        return true;
    };

    const startRecording = async () => {
        if (!checkBrowserSupport()) {
            return;
        }

        try {
            setStatus('Requesting microphone access...');
            setError(null);

            // Request microphone permission with optimal settings
            const stream = await navigator.mediaDevices.getUserMedia({
                audio: {
                    echoCancellation: true,
                    noiseSuppression: true,
                    autoGainControl: true
                }
            });

            streamRef.current = stream;

            // Determine best MIME type
            let mimeType = 'audio/webm';
            if (MediaRecorder.isTypeSupported('audio/webm;codecs=opus')) {
                mimeType = 'audio/webm;codecs=opus';
            } else if (MediaRecorder.isTypeSupported('audio/webm')) {
                mimeType = 'audio/webm';
            } else if (MediaRecorder.isTypeSupported('audio/mp4')) {
                mimeType = 'audio/mp4';
            } else if (MediaRecorder.isTypeSupported('audio/ogg')) {
                mimeType = 'audio/ogg';
            }

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

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

            // Handle recording stop
            mediaRecorder.onstop = async () => {
                const audioBlob = new Blob(audioChunksRef.current, { type: mimeType });
                await uploadRecording(audioBlob, mimeType);
            };

            // Handle errors
            mediaRecorder.onerror = (event) => {
                console.error('[AudioRecorder] Recording error:', event);
                setError('Recording failed');
                setStatus('Error occurred');
                setIsRecording(false);
            };

            // Start recording
            mediaRecorder.start();
            setIsRecording(true);
            setStatus('Recording...');
            setDuration(0);

            // Start timer
            timerRef.current = setInterval(() => {
                setDuration(prev => {
                    const newDuration = prev + 1;

                    // Auto-stop after 10 minutes (600 seconds)
                    if (newDuration >= 600) {
                        stopRecording();
                        setError('Maximum recording duration (10 min) reached');
                    }

                    return newDuration;
                });
            }, 1000);

        } catch (err) {
            console.error('[AudioRecorder] Start error:', err);

            // Handle specific permission errors
            if (err.name === 'NotAllowedError' || err.name === 'PermissionDeniedError') {
                setError('Microphone permission denied. Please allow access in browser settings.');
                setStatus('Permission denied');
            } else if (err.name === 'NotFoundError' || err.name === 'DevicesNotFoundError') {
                setError('No microphone found. Please connect a microphone.');
                setStatus('No microphone');
            } else if (err.name === 'NotReadableError' || err.name === 'TrackStartError') {
                setError('Microphone is being used by another application.');
                setStatus('Microphone busy');
            } else {
                setError(`Failed to start recording: ${err.message}`);
                setStatus('Error');
            }

            setIsRecording(false);
        }
    };

    const stopRecording = () => {
        if (mediaRecorderRef.current && isRecording) {
            mediaRecorderRef.current.stop();
            setIsRecording(false);
            setStatus('Processing...');

            // Stop timer
            if (timerRef.current) {
                clearInterval(timerRef.current);
            }

            // Stop all tracks
            if (streamRef.current) {
                streamRef.current.getTracks().forEach(track => track.stop());
            }
        }
    };

    const uploadRecording = async (audioBlob, mimeType) => {
        try {
            setIsUploading(true);
            setStatus('Uploading recording...');

            // Create file from blob
            const fileExtension = mimeType.includes('webm') ? 'webm' :
                mimeType.includes('mp4') ? 'm4a' : 'ogg';
            const filename = `recording_${Date.now()}.${fileExtension}`;
            const file = new File([audioBlob], filename, { type: mimeType });

            // Upload to server
            const formData = new FormData();
            formData.append('file', file);
            formData.append('position', 0);

            const token = localStorage.getItem('token');
            const response = await fetch(`${API_URL}/notes/${noteId}/content/audio`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token}` },
                body: formData
            });

            if (response.ok) {
                const data = await response.json();
                setStatus('Upload complete!');

                // Call success callback
                if (onRecordingComplete) {
                    onRecordingComplete(data);
                }
            } else {
                const errorData = await response.json();
                throw new Error(errorData.detail || 'Upload failed');
            }

        } catch (uploadError) {
            console.error('[AudioRecorder] Upload error:', uploadError);
            setError(`Upload failed: ${uploadError.message}`);
            setStatus('Upload failed');
        } finally {
            setIsUploading(false);
        }
    };

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

    // Component styles
    const styles = {
        container: {
            background: 'var(--card-bg)',
            borderRadius: '12px',
            padding: '2rem',
            width: '100%'
        },
        header: {
            fontSize: '1.25rem',
            fontWeight: '600',
            marginBottom: '1.5rem',
            textAlign: 'center',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            gap: '0.5rem'
        },
        statusContainer: {
            textAlign: 'center',
            marginBottom: '1.5rem'
        },
        status: {
            fontSize: '0.95rem',
            color: 'var(--text-secondary)',
            marginBottom: '0.5rem'
        },
        duration: {
            fontSize: '2rem',
            fontWeight: '700',
            color: isRecording ? 'var(--danger)' : 'var(--text-primary)',
            fontFamily: 'monospace'
        },
        recordingIndicator: {
            display: 'inline-block',
            width: '12px',
            height: '12px',
            borderRadius: '50%',
            background: 'var(--danger)',
            marginLeft: '0.5rem',
            animation: 'pulse 1.5s ease-in-out infinite'
        },
        error: {
            background: 'rgba(239, 68, 68, 0.1)',
            border: '1px solid var(--danger)',
            borderRadius: '8px',
            padding: '1rem',
            marginBottom: '1rem',
            color: 'var(--danger)',
            fontSize: '0.875rem',
            textAlign: 'center'
        },
        controls: {
            display: 'flex',
            gap: '1rem',
            justifyContent: 'center'
        },
        button: {
            padding: '0.75rem 1.5rem',
            border: 'none',
            borderRadius: '8px',
            fontSize: '1rem',
            cursor: 'pointer',
            fontWeight: '600',
            transition: 'all 0.2s',
            display: 'flex',
            alignItems: 'center',
            gap: '0.5rem'
        },
        primaryButton: {
            background: isRecording ? 'var(--danger)' : 'var(--primary)',
            color: 'white'
        },
        secondaryButton: {
            background: 'var(--bg-secondary)',
            color: 'var(--text-primary)',
            border: '1px solid var(--border-color)'
        }
    };

    return (
        <div style={styles.container}>
            <div style={styles.header}>
                🎙️ Audio Recorder
            </div>

            {error && (
                <div style={styles.error}>
                    ⚠️ {error}
                </div>
            )}

            <div style={styles.statusContainer}>
                <div style={styles.status}>
                    {status}
                    {isRecording && <span style={styles.recordingIndicator} />}
                </div>
                <div style={styles.duration}>
                    {formatDuration(duration)}
                </div>
            </div>

            <div style={styles.controls}>
                {!isRecording && !isUploading ? (
                    <>
                        <button
                            onClick={startRecording}
                            style={{ ...styles.button, ...styles.primaryButton }}
                            disabled={!!error}
                        >
                            🎤 Start Recording
                        </button>
                        <button
                            onClick={onCancel}
                            style={{ ...styles.button, ...styles.secondaryButton }}
                        >
                            ✖️ Cancel
                        </button>
                    </>
                ) : isRecording ? (
                    <button
                        onClick={stopRecording}
                        style={{ ...styles.button, ...styles.primaryButton }}
                    >
                        ⏹️ Stop & Upload
                    </button>
                ) : (
                    <div style={{ ...styles.status, width: '100%' }}>
                        Uploading... Please wait
                    </div>
                )}
            </div>

            <style>{`
                @keyframes pulse {
                    0%, 100% { opacity: 1; }
                    50% { opacity: 0.3; }
                }
            `}</style>
        </div>
    );
}

// Export to global scope
window.AudioRecorder = AudioRecorder;
