/**
 * Audio Recorder Component for LocalLendables
 * Handles in-browser audio recording, playback, and management
 */

class AudioRecorder {
    constructor() {
        this.mediaRecorder = null;
        this.audioChunks = [];
        this.stream = null;
        this.isRecording = false;
        this.recordedBlob = null;
        this.maxRecordingTime = 30000; // 30 seconds max
        this.recordingTimer = null;
        this.recordingStartTime = null;
    }

    async initialize() {
        try {
            // Request microphone permission
            this.stream = await navigator.mediaDevices.getUserMedia({ 
                audio: {
                    echoCancellation: true,
                    noiseSuppression: true,
                    autoGainControl: true
                } 
            });
            return true;
        } catch (error) {
            console.error('Microphone access denied:', error);
            return false;
        }
    }

    startRecording() {
        if (!this.stream || this.isRecording) return false;

        this.audioChunks = [];
        this.recordedBlob = null;
        
        try {
            this.mediaRecorder = new MediaRecorder(this.stream, {
                mimeType: 'audio/webm;codecs=opus'
            });
            
            this.mediaRecorder.ondataavailable = (event) => {
                if (event.data.size > 0) {
                    this.audioChunks.push(event.data);
                }
            };
            
            this.mediaRecorder.onstop = () => {
                this.recordedBlob = new Blob(this.audioChunks, { type: 'audio/webm' });
                this.onRecordingComplete(this.recordedBlob);
            };
            
            this.mediaRecorder.start();
            this.isRecording = true;
            this.recordingStartTime = Date.now();
            
            // Auto-stop after max time
            this.recordingTimer = setTimeout(() => {
                this.stopRecording();
            }, this.maxRecordingTime);
            
            return true;
        } catch (error) {
            console.error('Recording start failed:', error);
            return false;
        }
    }

    stopRecording() {
        if (!this.isRecording || !this.mediaRecorder) return false;

        this.mediaRecorder.stop();
        this.isRecording = false;
        
        if (this.recordingTimer) {
            clearTimeout(this.recordingTimer);
            this.recordingTimer = null;
        }
        
        return true;
    }

    getRecordingDuration() {
        if (!this.recordingStartTime) return 0;
        return Date.now() - this.recordingStartTime;
    }

    onRecordingComplete(blob) {
        // Override this method in implementations
        console.log('Recording completed:', blob);
    }

    cleanup() {
        if (this.stream) {
            this.stream.getTracks().forEach(track => track.stop());
            this.stream = null;
        }
        if (this.recordingTimer) {
            clearTimeout(this.recordingTimer);
        }
    }

    // Utility methods for UI integration
    formatTime(ms) {
        const seconds = Math.floor(ms / 1000);
        const minutes = Math.floor(seconds / 60);
        const remainingSeconds = seconds % 60;
        return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
    }

    static isSupported() {
        return navigator.mediaDevices && 
               navigator.mediaDevices.getUserMedia && 
               window.MediaRecorder;
    }
}

// Audio Message UI Component
class AudioMessageUI {
    constructor(containerId, conversationId) {
        this.container = document.getElementById(containerId);
        this.conversationId = conversationId;
        this.recorder = new AudioRecorder();
        this.currentAudio = null;
        this.recordingTimer = null;
        this.recordingStartTime = null;
        
        this.init();
    }

    async init() {
        if (!AudioRecorder.isSupported()) {
            this.showError('Audio recording not supported in this browser');
            return;
        }

        this.createUI();
        
        // Override recorder's completion handler
        this.recorder.onRecordingComplete = (blob) => {
            this.handleRecordingComplete(blob);
        };
    }

    createUI() {
        this.container.innerHTML = `
            <div class="audio-recorder-ui">
                <div class="recording-controls">
                    <button id="recordBtn" class="btn btn-outline-primary btn-sm" title="Record Audio Message">
                        <i class="fas fa-microphone"></i> Record
                    </button>
                    <button id="stopBtn" class="btn btn-outline-danger btn-sm" style="display: none;" title="Stop Recording">
                        <i class="fas fa-stop"></i> Stop
                    </button>
                    <span id="recordingTime" class="recording-time" style="display: none;">0:00</span>
                </div>
                
                <div id="recordedAudio" class="recorded-audio" style="display: none;">
                    <div class="audio-preview">
                        <audio controls class="audio-player"></audio>
                        <div class="audio-actions">
                            <button id="sendAudioBtn" class="btn btn-success btn-sm">
                                <i class="fas fa-paper-plane"></i> Send
                            </button>
                            <button id="deleteAudioBtn" class="btn btn-outline-danger btn-sm">
                                <i class="fas fa-trash"></i> Delete
                            </button>
                        </div>
                    </div>
                </div>
                
                <div id="audioError" class="alert alert-danger" style="display: none;"></div>
            </div>
        `;

        this.bindEvents();
    }

    bindEvents() {
        const recordBtn = this.container.querySelector('#recordBtn');
        const stopBtn = this.container.querySelector('#stopBtn');
        const sendBtn = this.container.querySelector('#sendAudioBtn');
        const deleteBtn = this.container.querySelector('#deleteAudioBtn');

        recordBtn.addEventListener('click', () => this.startRecording());
        stopBtn.addEventListener('click', () => this.stopRecording());
        sendBtn.addEventListener('click', () => this.sendAudioMessage());
        deleteBtn.addEventListener('click', () => this.deleteRecording());
    }

    async startRecording() {
        const initialized = await this.recorder.initialize();
        if (!initialized) {
            this.showError('Microphone access required for audio messages');
            return;
        }

        const started = this.recorder.startRecording();
        if (!started) {
            this.showError('Failed to start recording');
            return;
        }

        // Update UI
        this.container.querySelector('#recordBtn').style.display = 'none';
        this.container.querySelector('#stopBtn').style.display = 'inline-block';
        this.container.querySelector('#recordingTime').style.display = 'inline-block';
        this.container.querySelector('#recordedAudio').style.display = 'none';

        // Start timer
        this.recordingStartTime = Date.now();
        this.recordingTimer = setInterval(() => {
            const elapsed = Date.now() - this.recordingStartTime;
            this.container.querySelector('#recordingTime').textContent = this.recorder.formatTime(elapsed);
        }, 100);
    }

    stopRecording() {
        const stopped = this.recorder.stopRecording();
        if (!stopped) return;

        // Clear timer
        if (this.recordingTimer) {
            clearInterval(this.recordingTimer);
            this.recordingTimer = null;
        }

        // Update UI
        this.container.querySelector('#recordBtn').style.display = 'inline-block';
        this.container.querySelector('#stopBtn').style.display = 'none';
        this.container.querySelector('#recordingTime').style.display = 'none';
    }

    handleRecordingComplete(blob) {
        const audioElement = this.container.querySelector('.audio-player');
        const audioUrl = URL.createObjectURL(blob);
        audioElement.src = audioUrl;
        
        this.currentAudio = blob;
        this.container.querySelector('#recordedAudio').style.display = 'block';
    }

    async sendAudioMessage() {
        if (!this.currentAudio) return;

        const sendBtn = this.container.querySelector('#sendAudioBtn');
        const originalText = sendBtn.innerHTML;
        sendBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sending...';
        sendBtn.disabled = true;

        try {
            const formData = new FormData();
            formData.append('audio', this.currentAudio, 'voice-message.webm');
            formData.append('messageType', 'audio');

            const response = await fetch(`/api/chat/${this.conversationId}/message`, {
                method: 'POST',
                body: formData
            });

            const result = await response.json();
            
            if (result.success) {
                this.deleteRecording();
                this.showSuccess('Voice message sent!');
                
                // Refresh chat if function exists
                if (typeof refreshChatMessages === 'function') {
                    refreshChatMessages();
                }
            } else {
                throw new Error(result.error || 'Failed to send audio message');
            }
        } catch (error) {
            console.error('Send audio error:', error);
            this.showError('Failed to send voice message');
        } finally {
            sendBtn.innerHTML = originalText;
            sendBtn.disabled = false;
        }
    }

    deleteRecording() {
        if (this.currentAudio) {
            const audioElement = this.container.querySelector('.audio-player');
            if (audioElement.src) {
                URL.revokeObjectURL(audioElement.src);
            }
            this.currentAudio = null;
        }
        
        this.container.querySelector('#recordedAudio').style.display = 'none';
        this.hideError();
    }

    showError(message) {
        const errorDiv = this.container.querySelector('#audioError');
        errorDiv.textContent = message;
        errorDiv.style.display = 'block';
    }

    hideError() {
        this.container.querySelector('#audioError').style.display = 'none';
    }

    showSuccess(message) {
        // Use existing toast system if available
        if (typeof LocalLendables !== 'undefined' && LocalLendables.showToast) {
            LocalLendables.showToast('success', message);
        } else {
            alert(message);
        }
    }

    destroy() {
        if (this.recordingTimer) {
            clearInterval(this.recordingTimer);
        }
        this.recorder.cleanup();
        this.deleteRecording();
    }
}

// Export for use in templates
window.AudioRecorder = AudioRecorder;
window.AudioMessageUI = AudioMessageUI;