class WebinarManager {
    constructor() {
        // Initialize properties
        this.authToken = localStorage.getItem('authToken');
        this.socket = null;
        this.socketInitialized = false;
        this.webinarId = null;
        this.companyId = null;
        this.isPresenter = false;
        this.mediasoupClient = window.mediasoupClient || null;
        this.sendTransport = null;
        this.recvTransport = null;
        this.producers = new Map();
        this.consumers = new Map();
        this.participants = new Map();
        this.currentTab = 'live';
        this.sessionCheckInterval = null;
        this.sessionMonitor = null;
        this.lastActivity = null;
        this.currentPresentation = null;
        this.videoStream = null;
        this.videoProducer = null;
        this.audioProducer = null;
        this.screenProducer = null;
        this.isAdmin = false;
        this.isRedirecting = false; // Prevent multiple redirects

        // Bind methods
        this.handleWebinarStarted = this.handleWebinarStarted.bind(this);
        this.handleNewProducer = this.handleNewProducer.bind(this);
        this.handleProducerClosed = this.handleProducerClosed.bind(this);
        this.handleChatMessage = this.handleChatMessage.bind(this);
        this.handleMuteRequest = this.handleMuteRequest.bind(this);
        this.handlePresentationStarted = this.handlePresentationStarted.bind(this);
        this.handlePresentationEnded = this.handlePresentationEnded.bind(this);
        this.handleParticipantJoined = this.handleParticipantJoined.bind(this);
        this.handleParticipantLeft = this.handleParticipantLeft.bind(this);
        this.handleWebinarStatus = this.handleWebinarStatus.bind(this);
        this.activityHandler = this.activityHandler.bind(this);

        this.initializeWithAuth();
    }

    // ===== Core Methods =====
    // async initializeWithAuth() {
    //     console.log('Initializing with auth...');
    //     try {
    //         if (!this.authToken) {
    //             console.log('No authToken, checking session...');
    //             await this.checkSession();
    //             return;
    //         }

    //         console.log('Verifying session...');
    //         const sessionValid = await this.verifySession();
    //         if (!sessionValid) {
    //             console.log('Session invalid, handling auth failure...');
    //             this.handleAuthFailure();
    //             return;
    //         }

    //         console.log('Session valid, initializing socket...');
    //         await this.initializeSocket();
    //         console.log('Initializing current user...');
    //         await this.getCurrentUser();
    //         await this.initializePage();
    //     } catch (error) {
    //         console.error('Initialization error:', error.message);
    //         this.handleAuthFailure();
    //     }
    // }
    async initializeWithAuth() {
  console.log('Initializing with auth...');
  try {
    const sessionValid = await this.verifySession();
    if (!sessionValid) {
      console.log('Session invalid, handling auth failure...');
      this.handleAuthFailure();
      return;
    }

    // Only initialize socket AFTER companyId is known
    console.log('Session valid, initializing socket...');
    await this.getCurrentUser(); // ensure companyId is set
    await this.initializeSocket();
    console.log('Initializing page...');
    await this.initializePage();
  } catch (error) {
    console.error('Initialization error:', error.message);
    this.handleAuthFailure();
  }
}


    async initializeSocket() {
        if (this.socket?.connected) {
            this.socket.disconnect();
        }
        if (!this.companyId) {
            await this.getCurrentUser();
            if (!this.companyId) {
                console.error('No companyId available for socket initialization');
                this.handleAuthFailure();
                return;
            }
        }

        return new Promise((resolve, reject) => {
            console.log('Attempting to initialize socket with token:', this.authToken);
            this.socket = io('http://localhost:3000', {
                path: '/socket.io',
                reconnection: true,
                reconnectionAttempts: 3,
                reconnectionDelay: 2000,
                timeout: 10000,
                transports: ['websocket'],
                withCredentials: true,
                autoConnect: true,
                query: { companyId: this.companyId, version: '1.0.0' }
            });

            this.socket.on('connect', () => {
                    console.log('Socket connected with ID:', this.socket.id);
                    if (this.webinarId) {
                        this.socket.emit('join_webinar', this.webinarId);
                        // Log attendance
                        fetch('/api/webinars/' + this.webinarId + '/attend', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        credentials: 'include'
                        }).catch(err => console.error('Error logging attendance:', err));
                    }
                    this.socketInitialized = true;
                    resolve();
            });
            
            this.socket.on('connect_error', (err) => {
                console.error('Connection error:', err.message);
                if (err.message.includes('401')) {
                    this.handleAuthFailure();
                } else {
                    this.showNotification('Failed to connect to server', 'error');
                    reject(err);
                }
            });

            this.socket.on('disconnect', (reason) => {
                console.log('Socket disconnected:', reason);
                if (reason === 'io server disconnect') {
                    this.handleAuthFailure();
                } else {
                    this.showNotification('Connection lost - reconnecting...');
                }
            });

            this.socket.on('reconnect_failed', () => {
                this.showNotification('Failed to reconnect to server', 'error');
            });

            this.socket.on('auth_error', () => {
                this.handleAuthFailure();
            });
            this.socket.on('exhibition_ended', () => {
                    localStorage.removeItem('authToken');
                    window.location.href = '/login?message=exhibition_ended';
            });
            // Application handlers
            this.socket.on('webinar_started', this.handleWebinarStarted);
            this.socket.on('new_producer', this.handleNewProducer);
            this.socket.on('producer_closed', this.handleProducerClosed);
            this.socket.on('webinar_chat_message', this.handleChatMessage);
            this.socket.on('mute_request', this.handleMuteRequest);
            this.socket.on('presentation_started', this.handlePresentationStarted);
            this.socket.on('presentation_ended', this.handlePresentationEnded);
            this.socket.on('participant_joined', this.handleParticipantJoined);
            this.socket.on('participant_left', this.handleParticipantLeft);
            this.socket.on('webinar_status', this.handleWebinarStatus);

            // Ping/pong handling
            this.socket.on('ping', () => {
                this.socket.emit('pong', {
                    timestamp: Date.now(),
                    companyId: this.companyId
                });
            });
        });
    }

    // ===== Authentication Methods =====
    async checkSession() {
        try {
            console.log('Checking session...');
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 5000);

            const response = await fetch('/api/check-session', {
                credentials: 'include',
                signal: controller.signal
            });

            clearTimeout(timeoutId);

            console.log('Check-session response:', response.status, response.statusText);
            if (response.status === 401) {
                console.error('Session check failed: Unauthorized');
                this.handleAuthFailure();
                return;
            }

            const data = await response.json();
            console.log('Check-session data:', data);
            if (data.authenticated && data.token) {
                localStorage.setItem('authToken', data.token);
                this.authToken = data.token;
                await this.initializeSocket();
                await this.getCurrentUser();
                await this.initializePage();
            } else {
                console.error('Session check failed: Not authenticated');
                this.handleAuthFailure();
            }
        } catch (error) {
            console.error('Session check error:', error.message);
            this.handleAuthFailure();
        }
    }

    async verifySession() {
        try {
            console.log('Attempting to verify session...');
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 5000);

            const response = await fetch('/api/verify-session', {
                credentials: 'include',
                headers: {
                    'Cache-Control': 'no-cache'
                },
                signal: controller.signal
            });

            clearTimeout(timeoutId);

            console.log('Verify session response:', response.status, response.statusText);
            if (!response.ok) {
                console.error('Session verification failed:', response.status);
                return false;
            }

            const data = await response.json();
            console.log('Verify session data:', data);

            if (!data.valid) {
                console.error('Session invalid');
                return false;
            }

            this.companyId = data.companyId;
            return true;
        } catch (error) {
            console.error('Session verification error:', error.message);
            return false;
        }
    }

    handleAuthFailure() {
        if (this.isRedirecting) return;
        this.isRedirecting = true;

        this.showNotification('Session expired. Redirecting to login...', 'error');
        setTimeout(() => {
            localStorage.removeItem('authToken');
            window.location.href = '/login';
        }, 2000);

        if (this.socket) {
            this.socket.disconnect();
        }
    }

    // ===== UI Methods =====
    showNotification(message, type = 'info', duration = 3000) {
        try {
            const existing = document.querySelector('.webinar-notification');
            if (existing) existing.remove();

            const notification = document.createElement('div');
            notification.className = `webinar-notification ${type}`;
            notification.textContent = message;

            document.body.appendChild(notification);

            setTimeout(() => {
                notification.classList.add('fade-out');
                setTimeout(() => notification.remove(), 500);
            }, duration);

            notification.addEventListener('click', () => notification.remove());
        } catch (error) {
            console.error('Failed to show notification:', error);
        }
    }

    initializeEventListeners() {
        // Webinar creation form
        const webinarForm = document.getElementById('webinarForm');
        if (webinarForm) {
            webinarForm.addEventListener('submit', this.handleCreateWebinar.bind(this));
        }

        // Webinar room controls
        const toggleAudio = document.getElementById('toggleAudio');
        if (toggleAudio) {
            toggleAudio.addEventListener('click', this.toggleAudio.bind(this));
            document.getElementById('toggleVideo').addEventListener('click', this.toggleVideo.bind(this));
            document.getElementById('screenShare').addEventListener('click', this.toggleScreenShare.bind(this));
            document.getElementById('leaveBtn').addEventListener('click', this.leaveWebinar.bind(this));
            document.getElementById('sendMessage').addEventListener('click', this.sendChatMessage.bind(this));
        }

        // Participant controls
        if (document.getElementById('muteParticipantBtn')) {
            document.getElementById('muteParticipantBtn').addEventListener('click', () => {
                const participantId = selectedParticipantId;
                this.muteParticipant(participantId);
            });
        }

        // Presentation controls
        if (document.getElementById('startPresentationBtn')) {
            document.getElementById('startPresentationBtn').addEventListener('click', () => {
                const type = 'slides';
                const url = prompt('Enter presentation URL:');
                if (url) this.startPresentation(type, url);
            });
        }

        if (document.getElementById('endPresentationBtn')) {
            document.getElementById('endPresentationBtn').addEventListener('click', this.endPresentation.bind(this));
        }

        // Tab navigation
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.addEventListener('click', (e) => {
                if (!window.webinarManager) {
                    console.error('WebinarManager not ready yet');
                    return;
                }

                const tab = e.target.dataset.tab;
                this.currentTab = tab;

                document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
                document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));

                e.target.classList.add('active');
                document.getElementById(tab).classList.add('active');
                this.switchTab(this.currentTab);
                this.loadWebinars(tab);
            });
        });

        // Search and filter
        const searchBox = document.querySelector('.searchBox');
        if (searchBox) {
            searchBox.addEventListener('input', (e) => {
                this.filterWebinars(e.target.value);
            });
        }

        const filterDropdown = document.querySelector('.filter-btn');
        const filterMenu = document.querySelector('.filter-menu');
        if (filterDropdown) {
            filterDropdown.addEventListener('click', () => {
                filterMenu?.classList.toggle('show');
            });
        }

        document.addEventListener('click', (e) => {
            if (!e.target.closest('.filter-dropdown')) {
                filterMenu?.classList.remove('show');
            }
        });

        document.querySelectorAll('.filter-item').forEach(item => {
            item.addEventListener('click', () => {
                const filterType = item.dataset.filter;
                this.filterWebinars(filterType);
                filterMenu?.classList.remove('show');
                this.applyFilter(filterType);
            });
        });
    }

    switchTab(tabName) {
        try {
            document.querySelectorAll('.tab-btn').forEach(btn => {
                btn.classList.toggle('active', btn.dataset.tab === tabName);
            });

            document.querySelectorAll('.tab-content').forEach(content => {
                content.classList.toggle('active', content.id === tabName);
            });

            this.currentTab = tabName;
        } catch (error) {
            console.error('Error switching tab:', error);
            this.showNotification('Failed to switch tab', 'error');
        }
    }

    // ===== Webinar Management Methods =====
    async loadWebinars(type) {
        try {
            this.showLoader(type);

            const endpointMap = {
                'live': '/api/webinars/live',
                'upcoming': '/api/webinars/upcoming',
                'recordings': '/api/webinars/recordings'
            };

            const response = await fetch(endpointMap[type]);

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error || `HTTP Error ${response.status}`);
            }

            const webinars = await response.json();
            const filteredWebinars = this.filterWebinarsByTab(webinars, type);
            this.renderWebinars(filteredWebinars, type);
        } catch (error) {
            console.error(`Error loading ${type} webinars:`, error);
            this.showError(error.message, type);
        }
    }

    filterWebinarsByTab(webinars, tab) {
        const now = new Date();
        return webinars.filter(webinar => {
            const scheduledTime = new Date(webinar.scheduled_time);
            const endTime = new Date(scheduledTime.getTime() + webinar.duration * 60 * 1000);

            switch (tab) {
                case 'live':
                    return now >= scheduledTime && now <= endTime;
                case 'upcoming':
                    return scheduledTime > now;
                case 'recordings':
                    return endTime < now;
                default:
                    return true;
            }
        });
    }

    renderWebinars(webinars, type) {
        const grid = document.querySelector(`#${type} .webinar-grid`);
        if (!grid) return;

        grid.innerHTML = webinars.length === 0
            ? this.emptyStateHTML(type)
            : '';

        webinars.forEach(webinar => {
            const card = this.createWebinarCard(webinar, type);
            grid.appendChild(card);
        });
    }

    createWebinarCard(webinar, type) {
        const card = document.createElement('div');
        card.className = `webinar-card ${type}`;

        const isOrganizer = webinar.organizer_id === this.companyId;
        const isRegistered = webinar.is_registered;

        let dateInfo = '';
        if (type === 'upcoming' && webinar.scheduled_time) {
            const date = new Date(webinar.scheduled_time);
            dateInfo = `
                <span><i class="fas fa-calendar-alt"></i> ${date.toLocaleDateString()}</span>
                <span><i class="fas fa-clock"></i> ${date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}</span>
            `;
        }

        let countInfo = '';
        if (type === 'live') {
            countInfo = `<span><i class="fas fa-users"></i> ${webinar.participants || 0} attending</span>`;
        } else if (type === 'recordings') {
            countInfo = `<span><i class="fas fa-eye"></i> ${webinar.views || 0} views</span>`;
        } else if (type === 'upcoming') {
            countInfo = `<span><i class="fas fa-user-plus"></i> ${webinar.registrations || 0} registered</span>`;
        }

        card.innerHTML = `
            <div class="webinar-thumbnail">
                <img src="${webinar.thumbnail_url || this.getDefaultThumbnail(type)}" alt="${webinar.title}">
                ${type === 'recordings' ? '<div class="play-btn"><i class="fas fa-play"></i></div>' : ''}
            </div>
            <div class="webinar-info">
                <h3>${webinar.title}</h3>
                <div class="webinar-meta">
                    <span><i class="fas fa-user"></i> ${webinar.organizer_name}</span>
                    ${dateInfo}
                    ${countInfo}
                </div>
                <p class="webinar-desc">${webinar.description || 'No description available'}</p>
                <div class="webinar-actions">
                    ${this.getActionButtons(webinar, type)}
                </div>
            </div>
        `;

        const primaryBtn = card.querySelector('.btn-primary');
        if (primaryBtn) {
            primaryBtn.addEventListener('click', async () => {
                if (type === 'live') {
                    if (isRegistered) {
                        window.location.href = `/webinar-room.html?webinarId=${webinar.webinar_id}`;
                    } else {
                        await this.registerForWebinar(webinar.webinar_id);
                    }
                } else if (type === 'recordings') {
                    this.watchRecording(webinar.webinar_id);
                } else if (type === 'upcoming' && isOrganizer) {
                    if (confirm('Start this webinar now?')) {
                        await this.startWebinar(webinar.webinar_id);
                    }
                } else if (isRegistered) {
                    window.location.href = `/webinar-room.html?webinarId=${webinar.webinar_id}`;
                } else {
                    this.registerForWebinar(webinar.webinar_id);
                }
            });
        }

        return card;
    }

    async startWebinar(webinarId) {
        try {
            if (!this.companyId) {
                await this.getCurrentUser();
                if (!this.companyId) throw new Error('Not logged in');
            }

            const response = await fetch(`/api/webinars/${webinarId}/start`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                credentials: 'include'
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error || 'Failed to start webinar');
            }

            const result = await response.json();
            this.showNotification('Webinar started successfully!');
            this.routerRtpCapabilities = result.routerRtpCapabilities;
            window.location.href = `/webinar-room.html?webinarId=${webinarId}&presenter=true`;
        } catch (error) {
            console.error('Error starting webinar:', error);
            this.showNotification(error.message, 'error');
            this.loadWebinars(this.currentTab);
        }
    }

    async registerForWebinar(webinarId) {
        try {
            if (!this.companyId) {
                await this.getCurrentUser();
                if (!this.companyId) throw new Error('Not logged in');
            }

            const response = await fetch(`/api/webinars/${webinarId}/register`, {
                method: 'POST',
                credentials: 'include'
            });

            if (!response.ok) throw new Error('Registration failed');

            await response.json();
            this.showNotification('Successfully registered for this webinar!');
            this.loadWebinars('upcoming');
        } catch (error) {
            console.error('Registration error:', error);
            this.showNotification(error.message, 'error');
        }
    }

    // ===== Media Handling Methods =====
// async loadMediasoupClient() {
//     if (!window.mediasoupClient) {
//         const url = '/js/mediasoup-client.js';
//         try {
//             await new Promise((resolve, reject) => {
//                 if (document.querySelector(`script[src="${url}"]`)) {
//                     if (window.mediasoupClient) {
//                         this.mediasoupClient = window.mediasoupClient;
//                         resolve();
//                         return;
//                     }
//                 }
//                 const script = document.createElement('script');
//                 script.src = url;
//                 script.async = true;
//                 script.onload = () => {
//                     if (window.mediasoupClient) {
//                         this.mediasoupClient = window.mediasoupClient;
//                         resolve();
//                     } else {
//                         reject(new Error('mediasoupClient not defined after loading'));
//                     }
//                 };
//                 script.onerror = () => reject(new Error(`Failed to load mediasoup-client from ${url}`));
//                 document.head.appendChild(script);
//             });
//             console.log(`Successfully loaded mediasoup-client from ${url}`);
//         } catch (error) {
//             console.error(error.message);
//             throw new Error('Failed to load mediasoup-client');
//         }
//     } else {
//         this.mediasoupClient = window.mediasoupClient;
//         console.log('mediasoup-client already loaded');
//     }
// }
async loadMediasoupClient() {
  if (window.mediasoupClient) {
    this.mediasoupClient = window.mediasoupClient;
    console.log('mediasoup-client already loaded');
    return;
  }

  const url = '/js/mediasoup-client.js';
  try {
    // Check if script tag already exists
    if (!document.querySelector(`script[src="${url}"]`)) {
      await new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = url;
        script.async = true;
        script.onload = () => {
          if (window.mediasoupClient) {
            this.mediasoupClient = window.mediasoupClient;
            console.log(`Successfully loaded mediasoup-client from ${url}`);
            resolve();
          } else {
            reject(new Error('mediasoupClient not defined after script load'));
          }
        };
        script.onerror = () => reject(new Error(`Failed to load mediasoup-client from ${url}`));
        document.head.appendChild(script);
      });
    } else {
      // Script tag exists, wait for it to load
      await new Promise((resolve, reject) => {
        const existingScript = document.querySelector(`script[src="${url}"]`);
        if (existingScript.dataset.loaded) {
          this.mediasoupClient = window.mediasoupClient;
          resolve();
          return;
        }
        existingScript.addEventListener('load', () => {
          this.mediasoupClient = window.mediasoupClient;
          console.log(`Successfully loaded mediasoup-client from ${url}`);
          resolve();
        }, { once: true });
        existingScript.addEventListener('error', () => reject(new Error(`Failed to load mediasoup-client from ${url}`)), { once: true });
      });
    }
  } catch (error) {
    console.error(error.message);
    throw new Error('Failed to load mediasoup-client');
  }
}
async initializeMediasoup(routerRtpCapabilities) {
        try {
            if (!this.mediasoupClient) {
                await this.loadMediasoupClient();
            }

            this.device = new this.mediasoupClient.Device();
            await this.device.load({ routerRtpCapabilities });

            await this.createTransports();

            if (this.isPresenter) {
                await this.produceInitialMedia();
            }

            await this.setupConsumerTransports();
        } catch (error) {
            console.error('Mediasoup initialization error:', error);
            this.showNotification('Failed to initialize media', 'error');
            throw error;
        }
    }

    async createTransports() {
        try {
            // Create send transport
            const sendResponse = await fetch(`/api/webinars/${this.webinarId}/create-transport`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ isProducer: true })
            });

            if (!sendResponse.ok) throw new Error('Failed to create send transport');

            const sendTransportData = await sendResponse.json();
            this.sendTransport = this.device.createSendTransport(sendTransportData);

            // Create receive transport
            const recvResponse = await fetch(`/api/webinars/${this.webinarId}/create-transport`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ isProducer: false })
            });

            if (!recvResponse.ok) throw new Error('Failed to create receive transport');

            const recvTransportData = await recvResponse.json();
            this.recvTransport = this.device.createRecvTransport(recvTransportData);

            this.setupTransportListeners();
        } catch (error) {
            console.error('Transport creation error:', error);
            this.showNotification('Failed to create media connections', 'error');
            throw error;
        }
    }

    setupTransportListeners() {
        // Send transport events
        this.sendTransport.on('connect', async ({ dtlsParameters }, callback) => {
            try {
                await fetch(`/api/webinars/${this.webinarId}/connect-transport`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        transportId: this.sendTransport.id,
                        dtlsParameters,
                        isProducer: true
                    })
                });
                callback();
            } catch (error) {
                callback(error);
            }
        });

        this.sendTransport.on('produce', async ({ kind, rtpParameters }, callback) => {
            try {
                const response = await fetch(`/api/webinars/${this.webinarId}/produce`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        transportId: this.sendTransport.id,
                        kind,
                        rtpParameters
                    })
                });

                if (!response.ok) throw new Error('Failed to produce');

                const { id } = await response.json();
                callback({ id });
            } catch (error) {
                callback(error);
            }
        });

        // Receive transport events
        this.recvTransport.on('connect', async ({ dtlsParameters }, callback) => {
            try {
                await fetch(`/api/webinars/${this.webinarId}/connect-transport`, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        transportId: this.recvTransport.id,
                        dtlsParameters,
                        isProducer: false
                    })
                });
                callback();
            } catch (error) {
                callback(error);
            }
        });
    }

    async produceInitialMedia() {
        try {
            const stream = await navigator.mediaDevices.getUserMedia({
                video: true,
                audio: true
            });

            const videoTrack = stream.getVideoTracks()[0];
            const audioTrack = stream.getAudioTracks()[0];

            this.videoProducer = await this.sendTransport.produce({
                track: videoTrack,
                codecOptions: { videoGoogleStartBitrate: 1000 }
            });

            this.audioProducer = await this.sendTransport.produce({
                track: audioTrack,
                codecOptions: { opusStereo: true, opusDtx: true }
            });

            this.addLocalVideo(stream);
        } catch (error) {
            console.error('Error producing initial media:', error);
            throw error;
        }
    }

    async setupConsumerTransports() {
        try {
            const response = await fetch(`/api/webinars/${this.webinarId}/producers`);
            if (!response.ok) {
            throw new Error(`Failed to fetch producers: ${response.statusText}`);
            }
            const producers = await response.json();
            console.log('Available producers:', producers);
            for (const producer of producers) {
            if (!producer.id) {
                console.warn('Skipping producer with missing id:', producer);
                continue;
            }
            await this.consumeProducer(producer);
            }
        } catch (error) {
            console.error('Error setting up consumer transports:', error);
            this.showNotification('Failed to set up media consumers', 'error');
            throw error;
        }
    }

    async consumeProducer(producer) {
        try {
            if (!this.recvTransport) {
            throw new Error('Receive transport not initialized');
            }
            if (!producer.id || !producer.kind) {
            throw new Error(`Invalid producer: ${JSON.stringify(producer)}`);
            }

            const response = await fetch(`/api/webinars/${this.webinarId}/consume`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                producerId: producer.id,
                rtpCapabilities: this.device.rtpCapabilities,
                transportId: this.recvTransport.id,
            }),
            });

            if (!response.ok) {
            throw new Error(`Failed to consume producer: ${response.statusText}`);
            }

            const consumerData = await response.json();
            if (!consumerData.id) {
            throw new Error('Consumer response missing id');
            }

            const consumer = await this.recvTransport.consume({
            id: consumerData.id,
            producerId: consumerData.producerId,
            kind: consumerData.kind,
            rtpParameters: consumerData.rtpParameters,
            type: consumerData.type,
            appData: { producerId: consumerData.producerId },
            });

            consumer.on('close', () => {
            console.log(`Consumer ${consumer.id} closed`);
            });

            await this.socket.emit('resume_consumer', { consumerId: consumer.id });

            const stream = new MediaStream([consumer.track]);
            const remoteVideo = document.createElement('video');
            remoteVideo.srcObject = stream;
            remoteVideo.autoplay = true;
            remoteVideo.playsInline = true;
            const remoteVideosContainer = document.getElementById('remoteVideos');
            if (!remoteVideosContainer) {
            console.error('remoteVideos container not found');
            throw new Error('Remote videos container not found in DOM');
            }
            console.log('Appending video element for producer:', producer.id);
            remoteVideosContainer.appendChild(remoteVideo);

            this.consumers.set(consumer.id, consumer);
        } catch (error) {
            console.error('Error consuming producer:', error);
            this.showNotification('Failed to consume media stream', 'error');
            throw error;
        }
    }

    // ===== UI Helper Methods =====
    addLocalVideo(stream) {
        const videoElement = document.createElement('video');
        videoElement.srcObject = stream;
        videoElement.muted = true;
        videoElement.autoplay = true;
        document.getElementById('videoContainer')?.appendChild(videoElement);
    }

    addRemoteVideo(track) {
        const stream = new MediaStream([track]);
        const videoElement = document.createElement('video');
        videoElement.srcObject = stream;
        videoElement.autoplay = true;
        document.getElementById('videoContainer')?.appendChild(videoElement);
    }

    async toggleAudio() {
        try {
            if (!this.audioProducer) {
                const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
                const track = stream.getAudioTracks()[0];
                this.audioProducer = await this.sendTransport.produce({
                    track,
                    codecOptions: { opusStereo: true, opusDtx: true }
                });
            }
            this.audioProducer.track.enabled = !this.audioProducer.track.enabled;
            this.showNotification(`Microphone ${this.audioProducer.track.enabled ? 'unmuted' : 'muted'}`);
        } catch (error) {
            this.showNotification('Failed to toggle audio: ' + error.message, 'error');
        }
    }

    async toggleVideo() {
        try {
            if (!this.sendTransport) {
                await this.initializeMediasoup(this.routerRtpCapabilities);
            }

            if (!this.videoProducer) {
                const stream = await navigator.mediaDevices.getUserMedia({ video: true });
                const videoTrack = stream.getVideoTracks()[0];

                this.videoProducer = await this.sendTransport.produce({
                    track: videoTrack,
                    codecOptions: { videoGoogleStartBitrate: 1000 }
                });

                this.videoStream = stream;
                this.addLocalVideo(stream);
            }

            const newState = !this.videoProducer.track.enabled;
            this.videoProducer.track.enabled = newState;
            this.updateVideoButtonState(newState);
            this.showNotification(`Camera ${newState ? 'enabled' : 'disabled'}`);
        } catch (error) {
            console.error('Error toggling video:', error);
            this.showNotification(`Failed to toggle video: ${error.message}`, 'error');

            if (this.videoProducer && !this.videoProducer.track.enabled) {
                this.videoProducer.close();
                this.videoProducer = null;
                if (this.videoStream) {
                    this.videoStream.getTracks().forEach(track => track.stop());
                    this.videoStream = null;
                }
            }
        }
    }

    async toggleScreenShare() {
        try {
            if (this.screenProducer) {
                this.screenProducer.close();
                this.screenProducer = null;
                this.showNotification('Screen sharing stopped');
            } else {
                const stream = await navigator.mediaDevices.getDisplayMedia({
                    video: true,
                    audio: true
                });
                const track = stream.getVideoTracks()[0];
                this.screenProducer = await this.sendTransport.produce({
                    track,
                    codecOptions: { videoGoogleStartBitrate: 2000 }
                });
                this.showNotification('Screen sharing started');

                track.onended = () => {
                    this.screenProducer?.close();
                    this.screenProducer = null;
                };
            }
        } catch (error) {
            this.showNotification('Screen share failed: ' + error.message, 'error');
        }
    }

    // ===== Webinar Room Methods =====
    async setupWebinarRoom() {
        const urlParams = new URLSearchParams(window.location.search);
        this.webinarId = urlParams.get('webinarId');
        this.isPresenter = urlParams.has('presenter');

        try {
            const response = await fetch(`/api/webinars/${this.webinarId}/join`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ isPresenter: this.isPresenter })
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.error || `Join failed (HTTP ${response.status})`);
            }

            const data = await response.json();
            await this.initializeMediasoup(data.routerRtpCapabilities);
            await this.fetchParticipants();
        } catch (error) {
            console.error('Webinar setup error:', error);
            this.showNotification(`Join failed: ${error.message}`, 'error');
            if (error.message.includes('not active')) {
                setTimeout(() => this.setupWebinarRoom(), 5000);
            }
        }
    }

    async joinWebinar() {
        try {
            const urlParams = new URLSearchParams(window.location.search);
            this.webinarId = urlParams.get('webinarId');
            this.isPresenter = urlParams.has('presenter');

            await this.getCurrentUser();

            const response = await fetch(`/api/webinars/${this.webinarId}/join`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ isPresenter: this.isPresenter })
            });

            if (!response.ok) throw new Error('Failed to join webinar');

            const data = await response.json();
            this.routerRtpCapabilities = data.routerRtpCapabilities;
            await this.initializeMediasoup(data.routerRtpCapabilities);
            this.initializeEventListeners();
            this.showNotification('Joined webinar successfully');
        } catch (error) {
            console.error('Error joining webinar:', error);
            this.showNotification(`Failed to join webinar: ${error.message}`, 'error');
            setTimeout(() => window.location.href = '/webinar.html', 3000);
        }
    }

    async fetchParticipants() {
    try {
        const response = await fetch(`/api/webinars/${this.webinarId}/participants`, {
            credentials: 'include'
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.error || 'Failed to fetch participants');
        }

        const participants = await response.json();
        this.participants.clear();
        participants.forEach(participant => {
            if (!this.participants.has(participant.id)) {
                this.participants.set(participant.id, participant);
            }
        });
        this.updateParticipantsList();
    } catch (error) {
        console.error('Error fetching participants:', error);
    }
}

updateParticipantsList() {
        const listElement = document.getElementById('participantsList');
        const countElement = document.getElementById('participantCount');

        if (!listElement || !countElement) return;

        listElement.innerHTML = '';
        countElement.textContent = this.participants.size;

        this.participants.forEach(participant => {
            const li = document.createElement('li');
            li.innerHTML = `
                <span class="participant-name">${participant.name}</span>
                ${participant.isPresenter ? '<span class="badge presenter">Presenter</span>' : ''}
            `;
            listElement.appendChild(li);
        });
}

    // ===== Chat Methods =====
    sendChatMessage() {
        const messageInput = document.getElementById('chatInput');
        const message = messageInput?.value.trim();

        if (message) {
            this.socket.emit('webinar_chat_message', {
                webinarId: this.webinarId,
                message
            });
            messageInput.value = '';
        }
    }

    // ===== Presentation Methods =====
    handlePresentationStarted(data) {
        this.endCurrentPresentation();

        const presentationContainer = document.createElement('div');
        presentationContainer.className = 'presentation-container';
        presentationContainer.id = 'presentationContainer';

        if (data.presentationType === 'slides') {
            presentationContainer.innerHTML = `
                <iframe src="${data.resourceUrl}" frameborder="0"></iframe>
                <div class="presentation-info">
                    Presentation by ${data.presenterName}
                </div>
            `;
        } else if (data.presentationType === 'video') {
            const video = document.createElement('video');
            video.src = data.resourceUrl;
            video.controls = true;
            video.autoplay = true;
            presentationContainer.appendChild(video);
        }

        document.getElementById('videoContainer')?.prepend(presentationContainer);
        this.currentPresentation = {
            type: data.presentationType,
            container: presentationContainer
        };
    }

    handlePresentationEnded() {
        this.endCurrentPresentation();
    }

    endCurrentPresentation() {
        if (this.currentPresentation) {
            const container = document.getElementById('presentationContainer');
            if (container) container.remove();
            this.currentPresentation = null;
        }
    }

    startPresentation(type, url) {
        if (!this.isModerator && !this.isPresenter) return;

        this.socket.emit('presentation_start', {
            webinarId: this.webinarId,
            presentationType: type,
            resourceUrl: url
        });
    }

    endPresentation() {
        if (!this.isModerator && !this.isPresenter) return;
        this.socket.emit('presentation_end', { webinarId: this.webinarId });
    }

    // ===== Moderator Controls =====
    handleWebinarStarted(data) {
        console.log('Webinar started event:', data);
        if (data.webinarId === this.webinarId) {
            this.showNotification('Webinar has started!');
        }
    }

    handleNewProducer(data) {
        console.log('New producer event:', data);
        if (this.webinarId && data.webinarId === this.webinarId) {
            this.consumeProducer(data.producerId)
                .catch(err => {
                    console.error('Error consuming new producer:', err);
                });
        }
    }

    handleProducerClosed(data) {
        console.log('Producer closed event:', data);
        if (this.consumers.has(data.producerId)) {
            const consumer = this.consumers.get(data.producerId);
            consumer.close();
            this.consumers.delete(data.producerId);

            const videoElement = document.querySelector(`[data-producer-id="${data.producerId}"]`);
            if (videoElement) {
                videoElement.remove();
            }
        }
    }

    handleChatMessage(data) {
        console.log('New chat message:', data);
        const chatMessages = document.getElementById('chatMessages');
        if (!data || !data.companyName || !data.message) {
            console.warn('Invalid chat message format:', data);
            return;
        }
        if (chatMessages) {
            const messageElement = document.createElement('div');
            messageElement.className = 'message';
            messageElement.innerHTML = `
                <strong>${data.companyName}:</strong>
                <span>${data.message}</span>
                <small>${new Date(data.timestamp).toLocaleTimeString()}</small>
            `;
            chatMessages.appendChild(messageElement);
            chatMessages.scrollTop = chatMessages.scrollHeight;
        }
    }

    handleMuteRequest(data) {
        if (data.participantId === this.currentParticipantId && this.audioProducer) {
            this.audioProducer.track.enabled = !data.mute;
            this.updateUIForMuteState(data.mute);
        }
    }

    handleParticipantJoined(data) {
        if (!this.participants.has(data.id)) {
            this.participants.set(data.id, data);
            this.updateParticipantsList();
        }
    }

    handleParticipantLeft(participantId) {
        this.participants.delete(participantId);
        this.updateParticipantsList();
    }

    handleWebinarStatus(data) {
        if (data.status === 'live' && this.currentTab === 'live') {
            this.loadWebinars('live');
        }
        this.showNotification(`Webinar status updated: ${data.status}`);
    }

    activityHandler() {
        if (!this.lastActivity || Date.now() - this.lastActivity > 30000) {
            this.extendSession();
        }
        this.lastActivity = Date.now();
    }

    updateUIForMuteState(muted) {
        const audioBtn = document.getElementById('toggleAudio');
        if (audioBtn) {
            audioBtn.textContent = muted ? '🔇' : '🎤';
            audioBtn.classList.toggle('muted', muted);
        }

        this.showNotification(muted ?
            'You have been muted by the moderator' :
            'You have been unmuted by the moderator');
    }

    muteParticipant(participantId, mute = true) {
        if (!this.isModerator) return;

        this.socket.emit('mute_participant', {
            webinarId: this.webinarId,
            participantId,
            mute
        });
    }

    // ===== Utility Methods =====
    getDefaultThumbnail(type) {
        const defaults = {
            'live': '/images/default-live.png',
            'upcoming': '/images/default-upcoming.jpeg',
            'recordings': '/images/default-recording.jpeg'
        };
        return defaults[type] || '/images/default-webinar.jpg';
    }

    getActionButtons(webinar, type) {
        const isOrganizer = webinar.organizer_id === this.companyId;
        const isRegistered = webinar.is_registered;

        switch(type) {
            case 'live':
                if (isOrganizer) return `<button class="btn btn-primary">Manage</button>`;
                return isRegistered
                    ? `<button class="btn btn-primary">Join Now</button>`
                    : `<button class="btn btn-primary">Register</button>`;

            case 'upcoming':
                if (isOrganizer) return `<button class="btn btn-primary">Start Now</button>`;
                return isRegistered
                    ? `<button class="btn btn-primary">Join</button>`
                    : `<button class="btn btn-primary">Register</button>`;

            case 'recordings':
                return `<button class="btn btn-primary">Watch Recording</button>`;
            default:
                return '';
        }
    }

    emptyStateHTML(type) {
        const messages = {
            'live': 'No live webinars currently available',
            'upcoming': 'No upcoming webinars scheduled',
            'recordings': 'No webinar recordings available'
        };

        return `
            <div class="empty-state">
                <i class="fas fa-calendar-times"></i>
                <p>${messages[type]}</p>
            </div>
        `;
    }

    showLoader(type) {
        const grid = document.querySelector(`#${type} .webinar-grid`);
        if (grid) {
            grid.innerHTML = `
                <div class="empty-state">
                    <i class="fas fa-spinner fa-spin"></i>
                    <p>Loading ${type} webinars...</p>
                </div>
            `;
        }
    }

    showError(message, type) {
        const grid = document.querySelector(`#${type} .webinar-grid`);
        if (grid) {
            grid.innerHTML = `
                <div class="empty-state">
                    <i class="fas fa-exclamation-triangle"></i>
                    <p>${message}</p>
                    <button class="btn btn-primary" onclick="webinarManager.loadWebinars('${type}')">
                        Try Again
                    </button>
                </div>
            `;
        }
    }

    filterWebinars(searchTerm) {
        const cards = document.querySelectorAll(`#${this.currentTab} .webinar-card`);
        const term = searchTerm.toLowerCase();

        cards.forEach(card => {
            const title = card.querySelector('h3')?.textContent.toLowerCase();
            const desc = card.querySelector('.webinar-desc')?.textContent.toLowerCase();
            const isVisible = title?.includes(term) || desc?.includes(term);
            card.style.display = isVisible ? 'block' : 'none';
        });
    }

    applyFilter(filter) {
        // Placeholder for filter logic
        console.log('Applying filter:', filter);
        this.loadWebinars(this.currentTab);
    }

    updateVideoButtonState(enabled) {
        const videoBtn = document.getElementById('toggleVideo');
        if (videoBtn) {
            videoBtn.classList.toggle('active', enabled);
            videoBtn.innerHTML = enabled
                ? '<i class="fas fa-video"></i>'
                : '<i class="fas fa-video-slash"></i>';
            videoBtn.setAttribute('data-tooltip', enabled ? 'Turn off camera' : 'Turn on camera');
        }
    }

    // ===== Session Management =====
    startPeriodicSessionChecks() {
        if (this.sessionCheckInterval) clearInterval(this.sessionCheckInterval);

        this.sessionCheckInterval = setInterval(async () => {
            await this.verifySession();
        }, 300000);
    }

    startSessionMonitor() {
        if (this.sessionMonitor) clearInterval(this.sessionMonitor);

        this.sessionMonitor = setInterval(async () => {
            const response = await fetch('/api/session-status', {
                credentials: 'include'
            });

            if (response.ok) {
                const data = await response.json();
                if (data.expiresIn < 300000) {
                    this.showNotification(`Session expires in ${Math.round(data.expiresIn/60000)} minutes`);
                }
            }
        }, 60000);
    }

    setupActivityListeners() {
        document.removeEventListener('mousemove', this.activityHandler);
        document.removeEventListener('keypress', this.activityHandler);

        this.activityHandler = () => {
            if (!this.lastActivity || Date.now() - this.lastActivity > 30000) {
                this.extendSession();
            }
            this.lastActivity = Date.now();
        };

        document.addEventListener('mousemove', this.activityHandler);
        document.addEventListener('keypress', this.activityHandler);
    }

    async extendSession() {
        try {
            await fetch('/api/touch-session', {
                method: 'POST',
                credentials: 'include'
            });
        } catch (error) {
            console.error('Session extension failed:', error);
        }
    }

    // ===== Initialization Methods =====
    async initializePage() {
        try {
            const sessionValid = await this.verifySession();
            if (!sessionValid) {
                this.handleAuthFailure();
                return;
            }

            await this.initializeSocket();
            await this.getCurrentUser();
            await this.loadWebinars(this.currentTab);

            this.startPeriodicSessionChecks();
            this.startSessionMonitor();
            this.setupActivityListeners();
            this.initializeEventListeners();
        } catch (error) {
            console.error('Page initialization error:', error);
            this.handleAuthFailure();
        }
    }

    async getCurrentUser() {
        try {
            const response = await fetch('/api/current-user', {
                credentials: 'include'
            });
            if (!response.ok) {
                throw new Error('Failed to get user');
            }

            const user = await response.json();
            this.companyId = user.companyId;
            this.isAdmin = user.isAdmin || false;
        } catch (error) {
            console.error('Error getting current user:', error);
            this.showNotification('Error getting user info', 'error');
            throw error;
        }
    }

    async handleCreateWebinar(e) {
        e.preventDefault();

        const webinarData = {
            title: document.getElementById('title').value,
            description: document.getElementById('description').value,
            scheduledTime: document.getElementById('datetime').value,
            duration: document.getElementById('duration').value,
            isPublic: document.getElementById('isPublic').checked,
            maxParticipants: 100
        };

        try {
            const response = await fetch('/api/webinars', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(webinarData)
            });

            if (!response.ok) throw new Error('Failed to create webinar');

            const result = await response.json();
            alert('Webinar created successfully!');
            window.location.href = `/webinar-room.html?webinarId=${result.webinarId}`;
        } catch (error) {
            console.error('Error creating webinar:', error);
            alert('Error creating webinar: ' + error.message);
        }
    }

    leaveWebinar() {
        try {
            if (this.videoProducer) {
                this.videoProducer.close();
                this.videoProducer = null;
            }
            if (this.audioProducer) {
                this.audioProducer.close();
                this.audioProducer = null;
            }

            if (this.sendTransport) {
                this.sendTransport.close();
                this.sendTransport = null;
            }
            if (this.recvTransport) {
                this.recvTransport.close();
                this.recvTransport = null;
            }

            if (this.videoStream) {
                this.videoStream.getTracks().forEach(track => track.stop());
                this.videoStream = null;
            }

            this.socket.emit('leave_webinar', this.webinarId);
            window.location.href = '/webinar.html';
        } catch (error) {
            console.error('Error leaving webinar:', error);
            this.showNotification('Error leaving webinar', 'error');
        }
    }

    cleanup() {
        this.producers.forEach(producer => producer.close());
        this.consumers.forEach(consumer => consumer.close());
        if (this.sendTransport) this.sendTransport.close();
        if (this.recvTransport) this.recvTransport.close();
    }

    destroy() {
        if (this.socket) {
            this.socket.disconnect();
            this.socket.removeAllListeners();
        }
        if (this.sessionCheckInterval) clearInterval(this.sessionCheckInterval);
        if (this.sessionMonitor) clearInterval(this.sessionMonitor);

        document.removeEventListener('mousemove', this.activityHandler);
        document.removeEventListener('keypress', this.activityHandler);
        this.cleanup();
    }

    watchRecording(webinarId) {
        window.open(`/webinar-recording.html?id=${webinarId}`, '_blank');
    }
}

// Initialize the webinar manager
async function initializeWebinarManager() {
    window.webinarManager = new WebinarManager();
    if (window.location.pathname.includes('webinar-room.html')) {
        await webinarManager.setupWebinarRoom();
    }
}

document.addEventListener('DOMContentLoaded', () => {
    if (window.location.pathname.includes('webinar-room.html')) {
        initializeWebinarManager();
    } else {
        window.webinarManager = new WebinarManager();
        webinarManager.initializePage();
    }

    window.addEventListener('beforeunload', () => {
        webinarManager?.destroy();
    });
    
});