// ~/components/webrtc-connection-manager.tsx
import { useEffect, useRef } from 'react'; // Removed useState
import { useActiveVoiceChannelStore } from '~/store/active-voice-channel';
import { useGatewayWebSocketStore } from '~/store/gateway-websocket';
import { useWebRTCStore } from '~/store/webrtc'; // Ensure WebRTCStatus is exported

export function WebRTCConnectionManager() {
    console.log('WebRTC Manager: Mounting component.');

    const {
        serverId: activeServerId,
        channelId: activeChannelId,
        isVoiceActive,
    } = useActiveVoiceChannelStore(state => ({
        serverId: state.serverId,
        channelId: state.channelId,
        isVoiceActive: state.isVoiceActive,
    }));

    const gatewayStatus = useGatewayWebSocketStore((state) => state.status);

    const {
        joinVoiceChannel,
        leaveVoiceChannel,
        status: webRTCStatus,
        currentChannelId: rtcCurrentChannelId,
    } = useWebRTCStore((state) => ({
        joinVoiceChannel: state.joinVoiceChannel,
        leaveVoiceChannel: state.leaveVoiceChannel,
        status: state.status,
        currentChannelId: state.currentChannelId,
    }));

    // Use useRef for the stream to avoid re-triggering effect on set
    const mediaStreamRef = useRef<MediaStream | null>(null);
    // Use useRef for an operation lock to prevent re-entrancy
    const operationLockRef = useRef<boolean>(false);

    useEffect(() => {
        console.log('WebRTC Manager: Effect triggered', {
            activeServerId,
            activeChannelId,
            isVoiceActive,
            gatewayStatus,
            webRTCStatus,
            rtcCurrentChannelId,
            operationLock: operationLockRef.current,
        });

        const manageWebRTCConnection = async () => {
            if (operationLockRef.current) {
                console.debug('WebRTC Manager: Operation in progress, skipping.');
                return;
            }

            const isConnectedToSomeChannel =
                webRTCStatus !== "IDLE" &&
                webRTCStatus !== "DISCONNECTED" &&
                webRTCStatus !== "FAILED";

            // --- Condition to JOIN/SWITCH voice ---
            if (isVoiceActive && activeServerId && activeChannelId && gatewayStatus === 'CONNECTED') {
                // Condition 1: Not connected at all, and want to join.
                // Condition 2: Connected to a DIFFERENT channel, and want to switch.
                const needsToJoinOrSwitch =
                    !isConnectedToSomeChannel || (rtcCurrentChannelId !== activeChannelId);

                if (needsToJoinOrSwitch) {
                    operationLockRef.current = true;
                    console.log(`WebRTC Manager: Attempting to join/switch to ${activeServerId}/${activeChannelId}. Current RTC status: ${webRTCStatus}, current RTC channel: ${rtcCurrentChannelId}`);

                    // If currently connected to a different channel, leave it first.
                    if (isConnectedToSomeChannel && rtcCurrentChannelId && rtcCurrentChannelId !== activeChannelId) {
                        console.log(`WebRTC Manager: Leaving current channel ${rtcCurrentChannelId} before switching.`);
                        leaveVoiceChannel();
                        // leaveVoiceChannel will change webRTCStatus, triggering this effect again.
                        // The operationLock will be released when status becomes IDLE/DISCONNECTED.
                        // No 'return' here needed, let the status change from leave drive the next step.
                        // The lock is set, so next iteration won't try to join immediately.
                        // It will fall through to the lock release logic when state becomes IDLE.
                    } else { // Not connected or switching from a null/same channel (should be IDLE then)
                        let streamToUse = mediaStreamRef.current;

                        // Acquire media if we don't have a usable stream
                        if (!streamToUse || streamToUse.getTracks().every(t => t.readyState === 'ended')) {
                            if (streamToUse) { // Clean up old ended stream
                                streamToUse.getTracks().forEach(track => track.stop());
                            }
                            try {
                                console.log('WebRTC Manager: Acquiring new local media stream...');
                                streamToUse = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
                                mediaStreamRef.current = streamToUse;
                            } catch (err) {
                                console.error('WebRTC Manager: Failed to get user media:', err);
                                useWebRTCStore.setState({ status: "FAILED", lastError: 'Failed to get user media.' });
                                operationLockRef.current = false; // Release lock on failure
                                return; // Stop further processing for this run
                            }
                        }

                        if (streamToUse) {
                            console.log(`WebRTC Manager: Calling joinVoiceChannel for ${activeServerId}/${activeChannelId}`);
                            await joinVoiceChannel(activeServerId, activeChannelId, streamToUse);
                            // Don't release lock here immediately; let status changes from joinVoiceChannel
                            // (e.g., to CONNECTED or FAILED) handle releasing the lock.
                        } else {
                            console.error('WebRTC Manager: No media stream available to join channel.');
                            useWebRTCStore.setState({ status: "FAILED", lastError: 'Media stream unavailable.' });
                            operationLockRef.current = false; // Release lock
                        }
                    }
                }
            }
            // --- Condition to LEAVE voice ---
            else { // Not (isVoiceActive && activeServerId && activeChannelId && gatewayStatus === 'CONNECTED')
                if (isConnectedToSomeChannel) {
                    operationLockRef.current = true;
                    console.log('WebRTC Manager: Conditions met to leave active voice channel. Leaving...', { isVoiceActive, activeServerId, gatewayStatus, webRTCStatus });
                    leaveVoiceChannel();
                    // Lock will be released when status becomes IDLE/DISCONNECTED.
                }
            }

            // --- Manage operation lock based on final WebRTC state for this "cycle" ---
            // This part is crucial: if an operation was started, the lock is only released
            // when the WebRTC state settles into a terminal (IDLE, DISCONNECTED, FAILED) or successful (CONNECTED) state.
            if (operationLockRef.current) { // Only if a lock was acquired in this effect run or previous
                if (
                    webRTCStatus === "IDLE" ||
                    webRTCStatus === "DISCONNECTED" ||
                    webRTCStatus === "FAILED" ||
                    (webRTCStatus === "CONNECTED" && rtcCurrentChannelId === activeChannelId && isVoiceActive) // Successfully connected to desired channel
                ) {
                    // console.debug(`WebRTC Manager: Releasing operation lock. Status: ${webRTCStatus}`);
                    operationLockRef.current = false;
                }
            }

            // --- Release media stream if no longer needed ---
            // This should happen if WebRTC is inactive AND user doesn't want voice.
            if (
                mediaStreamRef.current &&
                (webRTCStatus === "IDLE" || webRTCStatus === "DISCONNECTED" || webRTCStatus === "FAILED") &&
                !isVoiceActive // Only if voice is explicitly deactivated
            ) {
                console.log('WebRTC Manager: Releasing local media stream as WebRTC is inactive and voice is not desired.');
                mediaStreamRef.current.getTracks().forEach(track => track.stop());
                mediaStreamRef.current = null;
            }
        };

        manageWebRTCConnection();

    }, [
        activeServerId,
        activeChannelId,
        isVoiceActive,
        gatewayStatus,
        webRTCStatus,
        rtcCurrentChannelId,
        joinVoiceChannel, // Stable from Zustand
        leaveVoiceChannel, // Stable from Zustand
    ]);

    // Cleanup on component unmount
    useEffect(() => {
        return () => {
            console.log('WebRTC Manager: Unmounting component.');
            // Ensure we attempt to leave if connection is active
            const { status: currentRtcStatus, leaveVoiceChannel: finalLeave } = useWebRTCStore.getState();
            if (currentRtcStatus !== "IDLE" && currentRtcStatus !== "DISCONNECTED") {
                console.log('WebRTC Manager: Unmounting. Leaving active voice channel.');
                finalLeave();
            }
            // Stop any tracks held by the ref
            if (mediaStreamRef.current) {
                console.log('WebRTC Manager: Unmounting. Stopping tracks from mediaStreamRef.');
                mediaStreamRef.current.getTracks().forEach(track => track.stop());
                mediaStreamRef.current = null;
            }
        };
    }, []); // Empty dependency array for unmount cleanup only

    return null;
}