import React, { useState, useEffect, useRef, useCallback } from 'react';
import { Track, RoomEvent } from 'livekit-client';
import { useVoice } from '../contexts/VoiceContext';
import ScreenShareModal from './ScreenShareModal';
import Avatar from './Avatar';
import { VideoRenderer, findTrackPubs, useParticipantTrack } from '../utils/streamUtils.jsx';

// Icons
import muteIcon from '../assets/icons/mute.svg';
import mutedIcon from '../assets/icons/muted.svg';
import cameraIcon from '../assets/icons/camera.svg';
import screenIcon from '../assets/icons/screen.svg';
import disconnectIcon from '../assets/icons/disconnect.svg';
import personalMuteIcon from '../assets/icons/personal_mute.svg';
import serverMuteIcon from '../assets/icons/server_mute.svg';
import screenShareStartSound from '../assets/sounds/screenshare_start.mp3';
import screenShareStopSound from '../assets/sounds/screenshare_stop.mp3';
import ColoredIcon from './ColoredIcon';

const SERVER_MUTE_RED = 'hsl(1.343, 84.81%, 69.02%)';

const getInitials = (name) => (name || '?').substring(0, 1).toUpperCase();

const getUserColor = (username) => {
    const colors = ['#5865F2', '#EDA843', '#3BA55D', '#FAA81A', '#EB459E'];
    let hash = 0;
    for (let i = 0; i < username.length; i++) {
        hash = username.charCodeAt(i) + ((hash << 5) - hash);
    }
    return colors[Math.abs(hash) % colors.length];
};

// Style constants
const LIVE_BADGE_STYLE = {
    backgroundColor: '#ed4245', borderRadius: '4px', padding: '2px 6px',
    color: 'white', fontSize: '11px', fontWeight: 'bold',
    textTransform: 'uppercase', letterSpacing: '0.5px',
};
const WATCH_STREAM_BUTTON_STYLE = {
    backgroundColor: 'rgba(0,0,0,0.6)', color: 'white', border: 'none',
    padding: '10px 20px', borderRadius: '4px', fontWeight: 'bold',
    fontSize: '14px', cursor: 'pointer',
};
const THUMBNAIL_SIZE = { width: 120, height: 68 };
const BOTTOM_BAR_HEIGHT = 140;

// --- Components ---

const ParticipantTile = ({ participant, username, avatarUrl }) => {
    const cameraTrack = useParticipantTrack(participant, 'camera');
    const { isPersonallyMuted, voiceStates } = useVoice();
    const isMicEnabled = participant.isMicrophoneEnabled;
    const isPersonalMuted = isPersonallyMuted(participant.identity);
    const displayName = username || participant.identity;

    // Look up server mute from voiceStates
    let isServerMutedUser = false;
    for (const users of Object.values(voiceStates)) {
        const u = users.find(u => u.userId === participant.identity);
        if (u) { isServerMutedUser = !!u.isServerMuted; break; }
    }

    return (
        <div style={{
            backgroundColor: '#202225',
            borderRadius: '8px',
            overflow: 'hidden',
            position: 'relative',
            display: 'flex',
            width: '100%',
            height: '100%',
            aspectRatio: '16/9',
        }}>
            {cameraTrack ? (
                <VideoRenderer track={cameraTrack} />
            ) : (
                <div style={{
                    width: '100%',
                    height: '100%',
                    backgroundColor: '#2f3136',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    flexDirection: 'column'
                }}>
                    <Avatar
                        username={displayName}
                        avatarUrl={avatarUrl}
                        size={80}
                        style={{ boxShadow: '0 4px 10px rgba(0,0,0,0.3)' }}
                    />
                </div>
            )}

            <div style={{
                position: 'absolute',
                bottom: '10px',
                left: '10px',
                backgroundColor: 'rgba(0, 0, 0, 0.6)',
                padding: '4px 8px',
                borderRadius: '4px',
                color: 'white',
                fontSize: '14px',
                display: 'flex',
                alignItems: 'center',
                gap: '6px'
            }}>
                {isServerMutedUser ? (
                    <ColoredIcon src={serverMuteIcon} color={SERVER_MUTE_RED} size="16px" />
                ) : isPersonalMuted ? (
                    <ColoredIcon src={personalMuteIcon} color="white" size="16px" />
                ) : isMicEnabled ? '\u{1F3A4}' : '\u{1F507}'}
                {displayName}
            </div>
        </div>
    );
};

const StreamPreviewTile = ({ participant, username, onWatchStream }) => {
    const displayName = username || participant.identity;
    const [hover, setHover] = useState(false);

    return (
        <div
            style={{
                backgroundColor: '#202225',
                borderRadius: '8px',
                overflow: 'hidden',
                position: 'relative',
                display: 'flex',
                width: '100%',
                height: '100%',
                aspectRatio: '16/9',
                cursor: 'pointer',
            }}
            onClick={onWatchStream}
            onMouseEnter={() => setHover(true)}
            onMouseLeave={() => setHover(false)}
        >
            {/* Static preview — no video subscription */}
            <div style={{
                width: '100%', height: '100%', backgroundColor: '#2f3136',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
                <ColoredIcon src={screenIcon} color="#72767d" size="48px" />
            </div>

            {/* Overlay */}
            <div style={{
                position: 'absolute', inset: 0,
                backgroundColor: hover ? 'rgba(0,0,0,0.6)' : 'rgba(0,0,0,0.5)',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexDirection: 'column', gap: '8px',
                transition: 'background-color 0.15s',
            }}>
                <button
                    style={{
                        ...WATCH_STREAM_BUTTON_STYLE,
                        transform: hover ? 'scale(1.05)' : 'scale(1)',
                        transition: 'transform 0.15s',
                    }}
                    onClick={(e) => { e.stopPropagation(); onWatchStream(); }}
                >
                    Watch Stream
                </button>
            </div>

            {/* Bottom label */}
            <div style={{
                position: 'absolute', bottom: '10px', left: '10px',
                display: 'flex', alignItems: 'center', gap: '6px', zIndex: 2,
            }}>
                <div style={{
                    backgroundColor: 'rgba(0,0,0,0.6)', padding: '4px 8px',
                    borderRadius: '4px', color: 'white', fontSize: '14px',
                    display: 'flex', alignItems: 'center', gap: '6px',
                }}>
                    {displayName}
                    <span style={LIVE_BADGE_STYLE}>LIVE</span>
                </div>
            </div>
        </div>
    );
};

const ParticipantThumbnail = ({ participant, username, avatarUrl, isStreamer, isMuted }) => {
    const cameraTrack = useParticipantTrack(participant, 'camera');
    const { isPersonallyMuted, voiceStates } = useVoice();
    const isPersonalMuted = isPersonallyMuted(participant.identity);
    const displayName = username || participant.identity;

    // Look up server mute from voiceStates
    let isServerMutedUser = false;
    for (const users of Object.values(voiceStates)) {
        const u = users.find(u => u.userId === participant.identity);
        if (u) { isServerMutedUser = !!u.isServerMuted; break; }
    }

    return (
        <div style={{
            width: THUMBNAIL_SIZE.width,
            height: THUMBNAIL_SIZE.height,
            borderRadius: '6px',
            overflow: 'hidden',
            position: 'relative',
            backgroundColor: '#2f3136',
            flexShrink: 0,
        }}>
            {cameraTrack ? (
                <VideoRenderer track={cameraTrack} style={{ objectFit: 'cover' }} />
            ) : (
                <div style={{
                    width: '100%', height: '100%',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                }}>
                    <Avatar username={displayName} avatarUrl={avatarUrl} size={32} />
                </div>
            )}

            {/* Bottom label */}
            <div style={{
                position: 'absolute', bottom: '2px', left: '2px', right: '2px',
                display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '3px',
            }}>
                <span style={{
                    backgroundColor: 'rgba(0,0,0,0.7)', padding: '1px 4px',
                    borderRadius: '3px', color: 'white', fontSize: '10px',
                    maxWidth: '100%', overflow: 'hidden', textOverflow: 'ellipsis',
                    whiteSpace: 'nowrap', display: 'flex', alignItems: 'center', gap: '3px',
                }}>
                    {isServerMutedUser ? (
                        <ColoredIcon src={serverMuteIcon} color={SERVER_MUTE_RED} size="12px" />
                    ) : isPersonalMuted ? (
                        <ColoredIcon src={personalMuteIcon} color="white" size="12px" />
                    ) : isMuted ? (
                        <span style={{ fontSize: '9px' }}>{'\u{1F507}'}</span>
                    ) : null}
                    {displayName}
                    {isStreamer && <span style={{ ...LIVE_BADGE_STYLE, fontSize: '8px', padding: '1px 3px' }}>LIVE</span>}
                </span>
            </div>
        </div>
    );
};

// Inline SVG icons for volume control
const SpeakerIcon = ({ volume, muted }) => {
    if (muted || volume === 0) {
        return (
            <svg width="20" height="20" viewBox="0 0 24 24" fill="white">
                <path d="M11 5L6 9H2v6h4l5 4V5z" />
                <line x1="23" y1="9" x2="17" y2="15" stroke="white" strokeWidth="2" strokeLinecap="round" />
                <line x1="17" y1="9" x2="23" y2="15" stroke="white" strokeWidth="2" strokeLinecap="round" />
            </svg>
        );
    }
    if (volume < 50) {
        return (
            <svg width="20" height="20" viewBox="0 0 24 24" fill="white">
                <path d="M11 5L6 9H2v6h4l5 4V5z" />
                <path d="M15.54 8.46a5 5 0 010 7.07" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" />
            </svg>
        );
    }
    return (
        <svg width="20" height="20" viewBox="0 0 24 24" fill="white">
            <path d="M11 5L6 9H2v6h4l5 4V5z" />
            <path d="M15.54 8.46a5 5 0 010 7.07" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" />
            <path d="M19.07 4.93a10 10 0 010 14.14" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" />
        </svg>
    );
};

// Inline SVG icons for fullscreen
const ExpandIcon = () => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="white">
        <path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" />
    </svg>
);

const CompressIcon = () => (
    <svg width="18" height="18" viewBox="0 0 24 24" fill="white">
        <path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z" />
    </svg>
);

const FocusedStreamView = ({
    streamParticipant,
    streamerUsername,
    allParticipants,
    getUsername,
    getAvatarUrl,
    participantsCollapsed,
    onToggleCollapse,
    onStopWatching,
    streamingIdentities,
    voiceUsers,
    isTabVisible,
    isFullscreen,
    onToggleFullscreen,
    localIdentity,
}) => {
    const screenTrack = useParticipantTrack(streamParticipant, 'screenshare');
    const [barHover, setBarHover] = useState(false);
    const [bottomEdgeHover, setBottomEdgeHover] = useState(false);

    // Volume control state
    const { getUserVolume, setUserVolume, togglePersonalMute, isPersonallyMuted } = useVoice();
    const streamerId = streamParticipant.identity;
    const isSelf = streamerId === localIdentity;
    const isMutedByMe = isPersonallyMuted(streamerId);
    const userVolume = getUserVolume(streamerId);
    const [volumeExpanded, setVolumeExpanded] = useState(false);
    const volumeHideTimeout = useRef(null);

    const handleVolumeMouseEnter = () => {
        if (volumeHideTimeout.current) clearTimeout(volumeHideTimeout.current);
        setVolumeExpanded(true);
    };
    const handleVolumeMouseLeave = () => {
        volumeHideTimeout.current = setTimeout(() => setVolumeExpanded(false), 1500);
    };
    useEffect(() => () => { if (volumeHideTimeout.current) clearTimeout(volumeHideTimeout.current); }, []);

    const sliderPercent = (userVolume / 200) * 100;

    // Auto-exit if stream track disappears
    useEffect(() => {
        if (!streamParticipant) {
            onStopWatching();
            return;
        }

        const checkTrack = () => {
            const { screenSharePub } = findTrackPubs(streamParticipant);
            if (!screenSharePub || !screenSharePub.track) {
                onStopWatching();
            }
        };

        // Give a brief grace period for track to appear
        const timeout = setTimeout(checkTrack, 3000);

        streamParticipant.on(RoomEvent.TrackUnpublished, checkTrack);
        streamParticipant.on('localTrackUnpublished', checkTrack);

        return () => {
            clearTimeout(timeout);
            streamParticipant.off(RoomEvent.TrackUnpublished, checkTrack);
            streamParticipant.off('localTrackUnpublished', checkTrack);
        };
    }, [streamParticipant, onStopWatching]);

    return (
        <div style={{ display: 'flex', flexDirection: 'column', flex: 1, position: 'relative' }}>
            {/* Stream area */}
            <div style={{
                flex: 1,
                position: 'relative',
                backgroundColor: 'black',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                overflow: 'hidden',
            }}>
                {screenTrack && isTabVisible ? (
                    <VideoRenderer track={screenTrack} style={{ objectFit: 'contain' }} />
                ) : screenTrack && !isTabVisible ? (
                    <div style={{
                        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px',
                        color: '#72767d',
                    }}>
                        <ColoredIcon src={screenIcon} color="#72767d" size="48px" />
                        <span style={{ fontSize: '14px' }}>Stream paused</span>
                    </div>
                ) : (
                    <div style={{
                        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '8px',
                        color: '#72767d',
                    }}>
                        <div style={{
                            width: '48px', height: '48px', borderRadius: '50%',
                            border: '3px solid #72767d', display: 'flex',
                            alignItems: 'center', justifyContent: 'center',
                            animation: 'spin 1s linear infinite',
                        }}>
                            <div style={{ width: '6px', height: '6px', borderRadius: '50%', backgroundColor: '#72767d' }} />
                        </div>
                        <span style={{ fontSize: '14px' }}>Loading stream...</span>
                    </div>
                )}

                {/* Top-left: streamer info */}
                <div style={{
                    position: 'absolute', top: '12px', left: '12px',
                    display: 'flex', alignItems: 'center', gap: '8px',
                    backgroundColor: 'rgba(0,0,0,0.6)', padding: '6px 10px',
                    borderRadius: '6px',
                }}>
                    <span style={{ color: 'white', fontSize: '14px', fontWeight: '500' }}>
                        {streamerUsername}
                    </span>
                    <span style={LIVE_BADGE_STYLE}>LIVE</span>
                </div>

                {/* Top-right: button group (fullscreen + close) */}
                <div style={{
                    position: 'absolute', top: '12px', right: '12px',
                    display: 'flex', gap: '8px',
                }}>
                    <button
                        onClick={onToggleFullscreen}
                        title={isFullscreen ? "Exit Fullscreen" : "Fullscreen"}
                        style={{
                            width: '32px', height: '32px', borderRadius: '50%',
                            backgroundColor: 'rgba(0,0,0,0.6)', border: 'none',
                            color: 'white', cursor: 'pointer',
                            display: 'flex', alignItems: 'center', justifyContent: 'center',
                            transition: 'background-color 0.15s',
                        }}
                        onMouseEnter={e => e.currentTarget.style.backgroundColor = 'rgba(0,0,0,0.8)'}
                        onMouseLeave={e => e.currentTarget.style.backgroundColor = 'rgba(0,0,0,0.6)'}
                    >
                        {isFullscreen ? <CompressIcon /> : <ExpandIcon />}
                    </button>
                    <button
                        onClick={onStopWatching}
                        title="Stop Watching"
                        style={{
                            width: '32px', height: '32px', borderRadius: '50%',
                            backgroundColor: 'rgba(0,0,0,0.6)', border: 'none',
                            color: 'white', fontSize: '18px', cursor: 'pointer',
                            display: 'flex', alignItems: 'center', justifyContent: 'center',
                            transition: 'background-color 0.15s',
                        }}
                        onMouseEnter={e => e.currentTarget.style.backgroundColor = 'rgba(0,0,0,0.8)'}
                        onMouseLeave={e => e.currentTarget.style.backgroundColor = 'rgba(0,0,0,0.6)'}
                    >
                        ✕
                    </button>
                </div>

                {/* Bottom-left: volume control (hidden when watching own stream) */}
                {!isSelf && (
                    <div
                        onMouseEnter={handleVolumeMouseEnter}
                        onMouseLeave={handleVolumeMouseLeave}
                        style={{
                            position: 'absolute', bottom: '12px', left: '12px',
                            display: 'flex', alignItems: 'center', gap: '8px',
                            backgroundColor: 'rgba(0,0,0,0.6)',
                            padding: '6px 10px',
                            borderRadius: '6px',
                            transition: 'width 0.2s ease',
                        }}
                    >
                        <button
                            onClick={() => togglePersonalMute(streamerId)}
                            title={isMutedByMe ? "Unmute" : "Mute"}
                            style={{
                                background: 'none', border: 'none', cursor: 'pointer',
                                padding: 0, display: 'flex', alignItems: 'center',
                                opacity: isMutedByMe ? 0.6 : 1,
                            }}
                        >
                            <SpeakerIcon volume={userVolume} muted={isMutedByMe} />
                        </button>
                        {volumeExpanded && (
                            <>
                                <input
                                    type="range"
                                    min="0"
                                    max="200"
                                    value={isMutedByMe ? 0 : userVolume}
                                    onChange={(e) => setUserVolume(streamerId, Number(e.target.value))}
                                    onMouseDown={(e) => e.stopPropagation()}
                                    className="context-menu-volume-slider"
                                    style={{
                                        width: '100px',
                                        background: `linear-gradient(to right, hsl(235, 86%, 65%) ${isMutedByMe ? 0 : sliderPercent}%, rgba(255,255,255,0.2) ${isMutedByMe ? 0 : sliderPercent}%)`,
                                    }}
                                />
                                <span style={{ color: 'white', fontSize: '12px', minWidth: '32px', textAlign: 'right' }}>
                                    {isMutedByMe ? 0 : userVolume}%
                                </span>
                            </>
                        )}
                    </div>
                )}
            </div>

            {/* Bottom participants bar */}
            <div
                style={{ position: 'relative' }}
                onMouseEnter={() => setBarHover(true)}
                onMouseLeave={() => setBarHover(false)}
            >
                {/* Collapse/expand toggle */}
                {!participantsCollapsed && barHover && (
                    <button
                        onClick={onToggleCollapse}
                        title="Collapse participants"
                        style={{
                            position: 'absolute', top: '-16px', left: '50%',
                            transform: 'translateX(-50%)', zIndex: 10,
                            width: '32px', height: '16px', borderRadius: '8px 8px 0 0',
                            backgroundColor: 'rgba(47,49,54,0.9)', border: 'none',
                            color: '#b9bbbe', fontSize: '12px', cursor: 'pointer',
                            display: 'flex', alignItems: 'center', justifyContent: 'center',
                        }}
                    >
                        ▼
                    </button>
                )}

                <div style={{
                    height: participantsCollapsed ? 0 : BOTTOM_BAR_HEIGHT,
                    overflow: 'hidden',
                    transition: 'height 0.25s ease',
                }}>
                    <div style={{
                        height: BOTTOM_BAR_HEIGHT,
                        display: 'flex',
                        alignItems: 'center',
                        padding: '0 16px',
                        gap: '8px',
                        overflowX: 'auto',
                        overflowY: 'hidden',
                    }}>
                        {allParticipants.map(p => {
                            const uname = getUsername(p.identity);
                            const user = voiceUsers?.find(u => u.userId === p.identity);
                            return (
                                <ParticipantThumbnail
                                    key={p.identity}
                                    participant={p}
                                    username={uname}
                                    avatarUrl={getAvatarUrl(p.identity)}
                                    isStreamer={streamingIdentities.has(p.identity)}
                                    isMuted={user ? user.isMuted : !p.isMicrophoneEnabled}
                                />
                            );
                        })}
                    </div>
                </div>
            </div>

            {/* Expand trigger when collapsed */}
            {participantsCollapsed && (
                <div
                    onMouseEnter={() => setBottomEdgeHover(true)}
                    onMouseLeave={() => setBottomEdgeHover(false)}
                    style={{
                        position: 'absolute', bottom: 0, left: 0, right: 0,
                        height: '24px', zIndex: 10,
                        display: 'flex', alignItems: 'flex-end', justifyContent: 'center',
                    }}
                >
                    {bottomEdgeHover && (
                        <button
                            onClick={onToggleCollapse}
                            title="Show participants"
                            style={{
                                width: '32px', height: '16px', borderRadius: '8px 8px 0 0',
                                backgroundColor: 'rgba(47,49,54,0.9)', border: 'none',
                                color: '#b9bbbe', fontSize: '12px', cursor: 'pointer',
                                display: 'flex', alignItems: 'center', justifyContent: 'center',
                                marginBottom: '0',
                            }}
                        >
                            ▲
                        </button>
                    )}
                </div>
            )}
        </div>
    );
};

// --- Main Component ---

const VoiceStage = ({ room, channelId, voiceStates, channelName }) => {
    const [participants, setParticipants] = useState([]);
    const { isMuted, toggleMute, disconnectVoice, setScreenSharing, connectToVoice, watchingStreamOf, setWatchingStreamOf, isReceivingScreenShareAudio } = useVoice();
    const [isScreenShareModalOpen, setIsScreenShareModalOpen] = useState(false);
    const [isScreenShareActive, setIsScreenShareActive] = useState(false);
    const screenShareAudioTrackRef = useRef(null);

    const [participantsCollapsed, setParticipantsCollapsed] = useState(false);

    // Fullscreen support
    const stageContainerRef = useRef(null);
    const [isFullscreen, setIsFullscreen] = useState(false);

    useEffect(() => {
        const handleFullscreenChange = () => {
            setIsFullscreen(!!document.fullscreenElement);
        };
        document.addEventListener('fullscreenchange', handleFullscreenChange);
        return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);
    }, []);

    const toggleFullscreen = useCallback(() => {
        if (!stageContainerRef.current) return;
        if (document.fullscreenElement) {
            document.exitFullscreen().catch(console.error);
        } else {
            stageContainerRef.current.requestFullscreen().catch(console.error);
        }
    }, []);

    const isReceivingScreenShareAudioRef = useRef(false);
    useEffect(() => { isReceivingScreenShareAudioRef.current = isReceivingScreenShareAudio; }, [isReceivingScreenShareAudio]);

    useEffect(() => {
        if (!room) return;

        const updateParticipants = () => {
             const remote = Array.from(room.remoteParticipants.values());
             const local = [room.localParticipant];
             setParticipants([...local, ...remote]);
             setIsScreenShareActive(room.localParticipant.isScreenShareEnabled);
        };

        updateParticipants();

        room.on(RoomEvent.ParticipantConnected, updateParticipants);
        room.on(RoomEvent.ParticipantDisconnected, updateParticipants);
        room.localParticipant.on('localTrackPublished', updateParticipants);
        room.localParticipant.on('localTrackUnpublished', (pub) => {
             if ((pub.source === Track.Source.ScreenShare || pub.source === 'screen_share') && !isReceivingScreenShareAudioRef.current) {
                 new Audio(screenShareStopSound).play();
             }
             updateParticipants();
        });

        return () => {
            room.off(RoomEvent.ParticipantConnected, updateParticipants);
            room.off(RoomEvent.ParticipantDisconnected, updateParticipants);
            room.localParticipant.off('localTrackPublished', updateParticipants);
            room.localParticipant.off('localTrackUnpublished', updateParticipants);
        };
    }, [room]);

    // Reset collapsed state and exit fullscreen when room disconnects
    useEffect(() => {
        if (!room) {
            setParticipantsCollapsed(false);
            if (document.fullscreenElement) document.exitFullscreen().catch(console.error);
        }
    }, [room]);

    // Derive streaming identities from voiceStates
    const voiceUsers = voiceStates?.[channelId] || [];
    const streamingIdentities = new Set(
        voiceUsers.filter(u => u.isScreenSharing).map(u => u.userId)
    );

    const handleStopWatching = useCallback(() => {
        if (document.fullscreenElement) document.exitFullscreen().catch(console.error);
        setWatchingStreamOf(null);
        setParticipantsCollapsed(false);
    }, []);

    // Screen Share Handler
    const handleScreenShareSelect = async (selection) => {
        if (!room) return;
        try {
            if (room.localParticipant.isScreenShareEnabled) {
                await room.localParticipant.setScreenShareEnabled(false);
            }
            let stream;
            if (selection.type === 'device') {
                 stream = await navigator.mediaDevices.getUserMedia({
                     video: { deviceId: { exact: selection.deviceId } },
                     audio: false
                 });
            } else {
                 // Try with audio if requested, fall back to video-only if it fails
                 const audioConstraint = selection.shareAudio ? {
                     mandatory: {
                         chromeMediaSource: 'desktop',
                         chromeMediaSourceId: selection.sourceId
                     }
                 } : false;
                 try {
                     stream = await navigator.mediaDevices.getUserMedia({
                         audio: audioConstraint,
                         video: {
                             mandatory: {
                                 chromeMediaSource: 'desktop',
                                 chromeMediaSourceId: selection.sourceId,
                                 minWidth: 1280,
                                 maxWidth: 1920,
                                 minHeight: 720,
                                 maxHeight: 1080,
                                 maxFrameRate: 30
                             }
                         }
                     });
                 } catch (audioErr) {
                     // Audio capture failed (e.g. macOS/Linux) — retry video-only
                     if (selection.shareAudio) {
                         console.warn("Audio capture failed, falling back to video-only:", audioErr.message);
                         stream = await navigator.mediaDevices.getUserMedia({
                             audio: false,
                             video: {
                                 mandatory: {
                                     chromeMediaSource: 'desktop',
                                     chromeMediaSourceId: selection.sourceId,
                                     minWidth: 1280,
                                     maxWidth: 1920,
                                     minHeight: 720,
                                     maxHeight: 1080,
                                     maxFrameRate: 30
                                 }
                             }
                         });
                     } else {
                         throw audioErr;
                     }
                 }
            }
            const track = stream.getVideoTracks()[0];
            if (track) {
                if (!isReceivingScreenShareAudio) new Audio(screenShareStartSound).play();
                await room.localParticipant.publishTrack(track, {
                    name: 'screen_share',
                    source: Track.Source.ScreenShare
                });

                // Publish audio track if present (system audio from desktop capture)
                const audioTrack = stream.getAudioTracks()[0];
                if (audioTrack) {
                    await room.localParticipant.publishTrack(audioTrack, {
                        name: 'screen_share_audio',
                        source: Track.Source.ScreenShareAudio
                    });
                    screenShareAudioTrackRef.current = audioTrack;
                }

                setScreenSharing(true);

                track.onended = () => {
                     // Clean up audio track when video track ends
                     if (screenShareAudioTrackRef.current) {
                         screenShareAudioTrackRef.current.stop();
                         room.localParticipant.unpublishTrack(screenShareAudioTrackRef.current);
                         screenShareAudioTrackRef.current = null;
                     }
                     setScreenSharing(false);
                     room.localParticipant.setScreenShareEnabled(false).catch(console.error);
                };
            }
        } catch (err) {
            console.error("Error sharing screen:", err);
            alert("Failed to share screen: " + err.message);
        }
    };

    const handleScreenShareClick = () => {
        if (isScreenShareActive) {
            // Clean up audio track before stopping screen share
            if (screenShareAudioTrackRef.current) {
                screenShareAudioTrackRef.current.stop();
                room.localParticipant.unpublishTrack(screenShareAudioTrackRef.current);
                screenShareAudioTrackRef.current = null;
            }
            room.localParticipant.setScreenShareEnabled(false);
            setScreenSharing(false);
        } else {
            setIsScreenShareModalOpen(true);
        }
    };

    const getUsername = (identity) => {
        const user = voiceUsers.find(u => u.userId === identity);
        return user ? user.username : identity;
    };

    const getAvatarUrl = (identity) => {
        const user = voiceUsers.find(u => u.userId === identity);
        return user?.avatarUrl || null;
    };

    // Pause local stream preview when tab is not visible to save CPU/GPU
    const [isTabVisible, setIsTabVisible] = useState(!document.hidden);
    useEffect(() => {
        const handler = () => setIsTabVisible(!document.hidden);
        document.addEventListener('visibilitychange', handler);
        return () => document.removeEventListener('visibilitychange', handler);
    }, []);

    // F key shortcut to toggle fullscreen when watching a stream
    useEffect(() => {
        if (!watchingStreamOf) return;
        const handleKeyDown = (e) => {
            if (e.key === 'f' || e.key === 'F') {
                const tag = e.target.tagName;
                if (tag === 'INPUT' || tag === 'TEXTAREA' || e.target.isContentEditable) return;
                e.preventDefault();
                toggleFullscreen();
            }
        };
        document.addEventListener('keydown', handleKeyDown);
        return () => document.removeEventListener('keydown', handleKeyDown);
    }, [watchingStreamOf, toggleFullscreen]);

    if (!room) {
        return (
            <div style={{
                flex: 1,
                display: 'flex',
                flexDirection: 'column',
                alignItems: 'center',
                justifyContent: 'center',
                backgroundColor: '#1a1b1e',
                width: '100%',
                height: '100%',
                position: 'relative',
                overflow: 'hidden'
            }}>
                <div style={{
                    position: 'absolute',
                    top: '50%',
                    left: '50%',
                    transform: 'translate(-50%, -50%)',
                    width: '100%',
                    height: '100%',
                    background: 'radial-gradient(circle at center, #2f3136 0%, #000000 100%)',
                    opacity: 0.8,
                    zIndex: 0
                }} />

                <div style={{ zIndex: 1, textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
                     <h2 style={{
                         color: 'white',
                         fontSize: '24px',
                         fontWeight: 'bold',
                         marginBottom: '8px'
                     }}>
                         {channelName || 'Voice Channel'}
                     </h2>
                     <p style={{
                         color: '#b9bbbe',
                         fontSize: '14px',
                         marginBottom: '24px'
                     }}>
                         No one is currently in voice
                     </p>
                     <button
                         onClick={() => connectToVoice(channelId, channelName, localStorage.getItem('userId'))}
                         style={{
                             backgroundColor: 'white',
                             color: 'black',
                             border: 'none',
                             borderRadius: '24px',
                             padding: '10px 24px',
                             fontSize: '14px',
                             fontWeight: '600',
                             cursor: 'pointer',
                             transition: 'transform 0.1s',
                             boxShadow: '0 2px 4px rgba(0,0,0,0.2)'
                         }}
                         onMouseEnter={e => e.target.style.transform = 'scale(1.05)'}
                         onMouseLeave={e => e.target.style.transform = 'scale(1)'}
                     >
                         Join Voice
                     </button>
                </div>
            </div>
        );
    }

    const isCameraOn = room.localParticipant.isCameraEnabled;
    const isScreenShareOn = isScreenShareActive;

    // Find the participant being watched
    const watchedParticipant = watchingStreamOf
        ? participants.find(p => p.identity === watchingStreamOf)
        : null;

    return (
        <div ref={stageContainerRef} style={{ display: 'flex', flexDirection: 'column', height: '100%', flex: 1, backgroundColor: 'black', width: '100%' }}>
            {watchingStreamOf && watchedParticipant ? (
                /* Focused/Fullscreen View */
                <FocusedStreamView
                    streamParticipant={watchedParticipant}
                    streamerUsername={getUsername(watchingStreamOf)}
                    allParticipants={participants}
                    getUsername={getUsername}
                    getAvatarUrl={getAvatarUrl}
                    participantsCollapsed={participantsCollapsed}
                    onToggleCollapse={() => setParticipantsCollapsed(c => !c)}
                    onStopWatching={handleStopWatching}
                    streamingIdentities={streamingIdentities}
                    voiceUsers={voiceUsers}
                    isTabVisible={isTabVisible}
                    isFullscreen={isFullscreen}
                    onToggleFullscreen={toggleFullscreen}
                    localIdentity={room.localParticipant.identity}
                />
            ) : (
                /* Grid View */
                <div style={{
                    flex: 1,
                    padding: '16px',
                    display: 'grid',
                    gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))',
                    gap: '16px',
                    overflowY: 'auto',
                    alignContent: 'start'
                }}>
                    {participants.map(p => {
                        const isStreaming = streamingIdentities.has(p.identity);
                        return (
                            <React.Fragment key={p.identity}>
                                <ParticipantTile
                                    participant={p}
                                    username={getUsername(p.identity)}
                                    avatarUrl={getAvatarUrl(p.identity)}
                                />
                                {isStreaming && (
                                    <StreamPreviewTile
                                        key={`stream-${p.identity}`}
                                        participant={p}
                                        username={getUsername(p.identity)}
                                        onWatchStream={() => setWatchingStreamOf(p.identity)}
                                    />
                                )}
                            </React.Fragment>
                        );
                    })}
                </div>
            )}

            {/* Controls */}
            <div style={{
                height: '80px',
                backgroundColor: 'black',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                paddingBottom: '20px'
            }}>
                <div style={{
                    display: 'flex',
                    gap: '16px',
                    padding: '8px 16px',
                    backgroundColor: '#2f3136',
                    borderRadius: '32px'
                }}>
                    <button
                        onClick={toggleMute}
                        title={isMuted ? "Unmute" : "Mute"}
                        style={{
                            width: '56px', height: '56px', borderRadius: '50%',
                            backgroundColor: isMuted ? 'white' : '#202225',
                            border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center'
                        }}
                    >
                         <ColoredIcon src={isMuted ? mutedIcon : muteIcon} color={isMuted ? 'black' : 'white'} size="24px" />
                    </button>

                    <button
                         onClick={() => room.localParticipant.setCameraEnabled(!isCameraOn)}
                         title="Toggle Camera"
                         style={{
                            width: '56px', height: '56px', borderRadius: '50%',
                            backgroundColor: isCameraOn ? 'white' : '#202225',
                            border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center'
                        }}
                    >
                        <ColoredIcon src={cameraIcon} color={isCameraOn ? 'black' : 'white'} size="24px" />
                    </button>

                    <button
                         onClick={handleScreenShareClick}
                         title="Share Screen"
                         style={{
                            width: '56px', height: '56px', borderRadius: '50%',
                            backgroundColor: isScreenShareOn ? 'white' : '#202225',
                            border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center'
                        }}
                    >
                        <ColoredIcon src={screenIcon} color={isScreenShareOn ? 'black' : 'white'} size="24px" />
                    </button>

                    <button
                         onClick={disconnectVoice}
                         title="Disconnect"
                         style={{
                            width: '56px', height: '56px', borderRadius: '50%',
                            backgroundColor: '#ED4245',
                            border: 'none', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center'
                        }}
                    >
                        <ColoredIcon src={disconnectIcon} color="white" size="24px" />
                    </button>
                </div>
            </div>

            {isScreenShareModalOpen && (
                 <ScreenShareModal
                    onClose={() => setIsScreenShareModalOpen(false)}
                    onSelectSource={handleScreenShareSelect}
                />
            )}
        </div>
    );
};

export default VoiceStage;
