import { r as registerInstance, d as createEvent, h, a as Host, g as getElement } from './index-55463a54.js';
import { e as defaultIconPack, i as useLanguage, c as createDefaultConfig, f as defaultOverrides, u as uiStore, b as createPeerStore } from './ui-store-76bb0e8e.js';
import { d as deepMerge, p as provideRtkDesignSystem } from './merge-86cf8b27.js';

const rtkUiProviderCss = ":host{line-height:initial;font-family:var(--rtk-font-family, sans-serif);font-feature-settings:normal;font-variation-settings:normal}p{margin:var(--rtk-space-0, 0px);padding:var(--rtk-space-0, 0px)}:host{box-sizing:border-box;display:flex;flex-direction:column;--tw-bg-opacity:1;background-color:rgba(var(--rtk-colors-background-1000, 8 8 8) / var(--tw-bg-opacity));color:rgb(var(--rtk-colors-text-900, 255 255 255 / 0.88));overflow:hidden;position:fixed;top:var(--rtk-space-0, 0px);right:var(--rtk-space-0, 0px);bottom:var(--rtk-space-0, 0px);left:var(--rtk-space-0, 0px);height:100%;width:100%}:host([mode='fill']){position:relative}";
const RtkUiProviderStyle0 = rtkUiProviderCss;

const LEAVE_ROOM_TIMER = 10000;
const RtkUiProvider = class {
    constructor(hostRef) {
        registerInstance(this, hostRef);
        this.statesUpdate = createEvent(this, "rtkStatesUpdate", 7);
        this.peerStore = null;
        this.providerId = 'provider-' + Math.floor(Math.random() * 100);
        /** Meeting */
        this.meeting = null;
        /** Icon pack */
        this.iconPack = defaultIconPack;
        /** Language utility */
        this.t = useLanguage();
        /** Config */
        this.config = createDefaultConfig();
        /** Fill type */
        this.mode = 'fixed';
        /** Whether to show setup screen or not */
        this.showSetupScreen = false;
        /** UI Kit Overrides */
        this.overrides = defaultOverrides;
        this.roomJoinedListener = () => {
            this.updateStates({ meeting: 'joined' });
        };
        this.waitlistedListener = () => {
            this.updateStates({ meeting: 'waiting' });
        };
        this.roomLeftListener = ({ state }) => {
            if (state === 'disconnected' || state === 'failed')
                return;
            this.updateStates({ meeting: 'ended', roomLeftState: state });
        };
        this.mediaPermissionUpdateListener = ({ kind, message }) => {
            if (['audio', 'video'].includes(kind)) {
                if ((message === 'DENIED' || message === 'SYSTEM_DENIED') &&
                    (this.peerStore || uiStore).state.states.activeDebugger !== true) {
                    const permissionModalSettings = {
                        enabled: true,
                        kind,
                    };
                    this.updateStates({ activePermissionsMessage: permissionModalSettings });
                }
            }
        };
        this.socketConnectionUpdateListener = ({ state }) => {
            if (state === 'failed') {
                setTimeout(() => {
                    this.meeting.leave('disconnected');
                }, LEAVE_ROOM_TIMER);
            }
        };
        this.handleChangingMeeting = (destinationMeetingId) => {
            const currentStates = this.peerStore.state.states;
            this.updateStates({
                activeBreakoutRoomsManager: Object.assign(Object.assign({}, currentStates.activeBreakoutRoomsManager), { destinationMeetingId }),
            });
        };
    }
    connectedCallback() {
        if (typeof window !== 'undefined') {
            this.authErrorListener = (ev) => {
                if (ev.detail.message.includes('401')) {
                    this.updateStates({ meeting: 'ended', roomLeftState: 'unauthorized' });
                }
            };
            window.addEventListener('rtkError', this.authErrorListener);
        }
        // Listen for store requests from child components
        this.setupStoreRequestListener();
        this.meetingChanged(this.meeting);
        this.iconPackChanged(this.iconPack);
        this.tChanged(this.t);
        this.configChanged(this.config);
        this.overridesChanged(this.overrides);
    }
    disconnectedCallback() {
        window.removeEventListener('rtkError', this.authErrorListener);
        // Remove event listeners
        if (this.storeRequestListener) {
            this.host.removeEventListener('rtkRequestStore', this.storeRequestListener);
        }
        if (this.stateUpdateListener) {
            this.host.removeEventListener('rtkStateUpdate', this.stateUpdateListener);
        }
        if (!this.meeting)
            return;
        this.meeting.self.removeListener('roomLeft', this.roomLeftListener);
        this.meeting.self.removeListener('roomJoined', this.roomJoinedListener);
        this.meeting.self.removeListener('waitlisted', this.waitlistedListener);
        this.meeting.self.removeListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
        this.meeting.meta.removeListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
    }
    updateStates(states) {
        // Use peer specific store if available, otherwise fall back to global store
        const targetStore = this.peerStore || uiStore;
        const newStates = Object.assign({}, targetStore.state.states);
        targetStore.state.states = deepMerge(newStates, states);
        // Emit unscoped event for backward compatibility
        this.statesUpdate.emit(targetStore.state.states);
        // Also emit a scoped event that only this meeting's components should listen to
        const scopedEvent = new CustomEvent('rtkStatesUpdate', {
            detail: targetStore.state.states,
            bubbles: true,
            composed: true,
        });
        this.host.dispatchEvent(scopedEvent);
    }
    setupStateUpdateListener() {
        // Remove existing listener if any
        if (this.stateUpdateListener) {
            this.host.removeEventListener('rtkStateUpdate', this.stateUpdateListener);
        }
        // Create new listener
        this.stateUpdateListener = (event) => {
            this.updateStates(event.detail);
        };
        // Listen for both generic events (backward compatibility) and peer-specific events
        this.host.addEventListener('rtkStateUpdate', this.stateUpdateListener);
    }
    setupStoreRequestListener() {
        // Remove existing listener if any
        if (this.storeRequestListener) {
            this.host.removeEventListener('rtkRequestStore', this.storeRequestListener);
        }
        // Listen for store requests from child components
        this.storeRequestListener = (event) => {
            if (!this.peerStore)
                return;
            // Provide the actual store object, not a wrapper
            const responseEvent = new CustomEvent('rtkProvideStore', {
                detail: { store: this.peerStore, requestId: event.detail.requestId },
            });
            document.dispatchEvent(responseEvent);
            // Stop the event from bubbling further to prevent other providers from handling it
            event.stopPropagation();
        };
        this.host.addEventListener('rtkRequestStore', this.storeRequestListener);
    }
    meetingChanged(meeting, oldMeeting) {
        if (meeting) {
            this.peerStore = createPeerStore({
                meeting,
                config: this.config,
                iconPack: this.iconPack,
                t: this.t,
                providerId: this.providerId,
                overrides: deepMerge(Object.assign({}, defaultOverrides), this.overrides),
            });
            // Notify components that peer specific store is now available
            document.dispatchEvent(new CustomEvent('rtkPeerStoreReady', {
                detail: {
                    peerId: meeting.self.id,
                },
            }));
        }
        // Setup state update listener now that we have peerId
        this.setupStateUpdateListener();
        if (meeting) {
            const targetStore = this.peerStore || uiStore;
            targetStore.state.meeting = meeting;
            /** Honor user's explicit choice for captions, but respect preset default if no explicit choice */
            const desiredActiveCaptionsState = !oldMeeting
                ? !!meeting.self.permissions.transcriptionEnabled
                : !!targetStore.state.states.activeCaptions;
            this.updateStates({
                viewType: meeting.meta.viewType,
                activeCaptions: desiredActiveCaptionsState,
            });
            meeting.self.addListener('roomJoined', this.roomJoinedListener);
            meeting.self.addListener('waitlisted', this.waitlistedListener);
            meeting.self.addListener('roomLeft', this.roomLeftListener);
            meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener);
            meeting.meta.addListener('socketConnectionUpdate', this.socketConnectionUpdateListener);
            meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting);
            if (meeting.self.roomJoined) {
                this.updateStates({ meeting: 'joined' });
            }
            else {
                if (this.showSetupScreen) {
                    this.updateStates({ meeting: 'setup' });
                }
                else {
                    meeting.join();
                }
            }
            window.removeEventListener('rtkError', this.authErrorListener);
        }
    }
    iconPackChanged(newIconPack) {
        if (this.peerStore) {
            this.peerStore.state.iconPack = newIconPack;
        }
    }
    tChanged(newT) {
        if (this.peerStore) {
            this.peerStore.state.t = newT;
        }
    }
    configChanged(config) {
        if (this.peerStore) {
            this.peerStore.state.config = config;
        }
        if ((config === null || config === void 0 ? void 0 : config.designTokens) &&
            typeof document !== 'undefined' &&
            (this.peerStore || uiStore).state.states.activeDebugger !== true) {
            provideRtkDesignSystem(document.documentElement, config.designTokens);
        }
    }
    overridesChanged(overrides) {
        if (this.peerStore) {
            this.peerStore.state.overrides = deepMerge(Object.assign({}, defaultOverrides), overrides);
        }
    }
    render() {
        // Don't render children until meeting is properly initialized
        if (!this.meeting) {
            return null;
        }
        return (h(Host, null, h("slot", null)));
    }
    get host() { return getElement(this); }
    static get watchers() { return {
        "meeting": ["meetingChanged"],
        "iconPack": ["iconPackChanged"],
        "t": ["tChanged"],
        "config": ["configChanged"],
        "overrides": ["overridesChanged"]
    }; }
};
RtkUiProvider.style = RtkUiProviderStyle0;

export { RtkUiProvider as rtk_ui_provider };
