import { __rest } from "tslib";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Box, Button, CircularProgress, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useThemeProps } from '@mui/system';
import { Link, SCPreferences, SCRoutes, useSCPreferences, useSCRouting, useSCUser } from '@selfcommunity/react-core';
import { SCLiveStreamViewType } from '@selfcommunity/types';
import classNames from 'classnames';
import { PREFIX } from './constants';
import { ConnectionState, formatChatMessageLinks, LayoutContextProvider, LiveKitRoom } from '@livekit/components-react';
import { useCallback, useMemo, useState } from 'react';
import { defaultUserChoices } from '@livekit/components-core';
import { defaultVideoOptions } from '../constants';
import { FormattedMessage } from 'react-intl';
import { VideoConference } from './VideoConference';
import { useLiveStream } from './LiveStreamProvider';
import DialogContent from '@mui/material/DialogContent';
import BaseDialog from '../../../shared/BaseDialog';
import { closeSnackbar } from 'notistack';
const classes = {
    root: `${PREFIX}-root`,
    logo: `${PREFIX}-logo`,
    title: `${PREFIX}-title`,
    content: `${PREFIX}-content`,
    endConferenceWrap: `${PREFIX}-end-conference-wrap`,
    btnBackHome: `${PREFIX}-btn-back-home`,
    actions: `${PREFIX}-actions`,
    error: `${PREFIX}-error`
};
const Root = styled(Box, {
    name: PREFIX,
    slot: 'Root'
})(({ theme }) => ({}));
const DialogRoot = styled(BaseDialog, {
    name: PREFIX,
    slot: 'Root',
    overridesResolver: (props, styles) => styles.dialogRoot
})(({ theme }) => ({}));
const PREFERENCES = [SCPreferences.LOGO_NAVBAR_LOGO];
/**
 *> API documentation for the Community-JS LiveStreamVideoConference component. Learn about the available props and the CSS API.
 *
 #### Import
 ```jsx
 import {LiveStreamVideoConference} from '@selfcommunity/react-ui';
 ```

 #### Component Name
 The name `LiveStreamVideoConference` can be used when providing style overrides in the theme.

 #### CSS

 |Rule Name|Global class|Description|
 |---|---|---|
 |root|.SCLiveStreamForm-root|Styles applied to the root element.|

 * @param inProps
 */
export default function LiveStreamVideoConference(inProps) {
    //PROPS
    const props = useThemeProps({
        props: inProps,
        name: PREFIX
    });
    const { className, handleOnLeaveRoom, userChoices = defaultUserChoices, connectionDetails = {}, LiveKitRoomComponentProps = {
    /* simulateParticipants: true */
    }, VideoConferenceComponentProps = {}, startConferenceEndContent, endConferenceEndContent, options = defaultVideoOptions } = props, rest = __rest(props, ["className", "handleOnLeaveRoom", "userChoices", "connectionDetails", "LiveKitRoomComponentProps", "VideoConferenceComponentProps", "startConferenceEndContent", "endConferenceEndContent", "options"]);
    // CONTEXT
    const scUserContext = useSCUser();
    const scRoutingContext = useSCRouting();
    const scPreferences = useSCPreferences();
    const { liveStream } = useLiveStream();
    // STATE
    const [liveActive, setLiveActive] = useState(true);
    const [error, setError] = useState(null);
    // PREFERENCES
    const preferences = useMemo(() => {
        const _preferences = {};
        PREFERENCES.map((p) => (_preferences[p] = p in scPreferences.preferences ? scPreferences.preferences[p].value : null));
        return _preferences;
    }, [scPreferences.preferences]);
    // PERMISSIONS
    const canUseAudio = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants))); }, [scUserContext, liveStream]);
    const canUseVideo = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableVideo))); }, [scUserContext, liveStream]);
    const canUseChat = useMemo(() => { var _a; return scUserContext.user && liveStream && liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableChat); }, [scUserContext, liveStream]);
    const canUseShareScreen = useMemo(() => { var _a; return scUserContext.user && liveStream && (liveStream.host.id === scUserContext.user.id || (liveStream && !((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.disableShareScreen))); }, [scUserContext, liveStream]);
    const speakerFocused = useMemo(() => (scUserContext.user && liveStream && liveStream.settings.view === SCLiveStreamViewType.SPEAKER ? liveStream.host : null), [scUserContext, liveStream]);
    const hideParticipantsList = useMemo(() => { var _a; return scUserContext.user && liveStream && ((_a = liveStream === null || liveStream === void 0 ? void 0 : liveStream.settings) === null || _a === void 0 ? void 0 : _a.hideParticipantsList) && liveStream.host.id !== scUserContext.user.id; }, [scUserContext, liveStream]);
    // CONNECT OPTIONS
    const connectOptions = useMemo(() => {
        return {
            autoSubscribe: true
        };
    }, []);
    // HANDLERS
    /**
     * Handle on leave
     */
    const handleOnLeave = useCallback(() => {
        setLiveActive(false);
        handleOnLeaveRoom === null || handleOnLeaveRoom === void 0 ? void 0 : handleOnLeaveRoom();
    }, [handleOnLeaveRoom]);
    /**
     * Handle on error
     */
    const handleError = useCallback((error) => {
        console.error(error);
        if (error.message !== 'Client initiated disconnect') {
            setError(`Encountered an unexpected error, check the console logs for details: ${error.message}`);
        }
        setLiveActive(false);
    }, []);
    /**
     * Handle encryption error
     */
    const handleEncryptionError = useCallback((error) => {
        console.error(error);
        setError(`Encountered an unexpected encryption error, check the console logs for details: ${error.message}`);
        setLiveActive(false);
    }, []);
    const handleBackHome = useCallback(() => {
        closeSnackbar();
    }, [closeSnackbar]);
    /**
     * User must be authenticated
     */
    if (!scUserContext.user || !connectionDetails) {
        return _jsx(CircularProgress, {});
    }
    /**
     * Renders root object
     */
    return (_jsx(Root, Object.assign({ className: classNames(classes.root, className) }, rest, { children: liveActive && !error ? (_jsx(_Fragment, { children: _jsx(LiveKitRoom, Object.assign({ connect: Boolean(liveActive), token: connectionDetails['participantToken'], serverUrl: connectionDetails['serverUrl'], connectOptions: connectOptions, video: userChoices.videoEnabled, audio: userChoices.audioEnabled, onDisconnected: handleOnLeave, onEncryptionError: handleEncryptionError, onError: handleError }, LiveKitRoomComponentProps, { children: _jsxs(LayoutContextProvider, { children: [_jsx(VideoConference, Object.assign({ chatMessageFormatter: formatChatMessageLinks }, (speakerFocused && { speakerFocused: liveStream.host }), VideoConferenceComponentProps, { disableMicrophone: !canUseAudio, disableCamera: !canUseVideo, disableChat: !canUseChat, disableShareScreen: !canUseShareScreen, hideParticipantsList: hideParticipantsList })), _jsx(ConnectionState, {})] }) })) })) : (_jsx(_Fragment, { children: error ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, error, _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : liveActive === false ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsx(DialogContent, { children: _jsxs(Box, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Link, Object.assign({ to: scRoutingContext.url(SCRoutes.HOME_ROUTE_NAME, {}), className: classes.logo }, { children: _jsx("img", { src: preferences[SCPreferences.LOGO_NAVBAR_LOGO], alt: "logo" }) })), startConferenceEndContent, _jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.conference.end", defaultMessage: "ui.liveStreamRoom.conference.end" }) })), _jsx(Button, Object.assign({ variant: "contained", color: "secondary", component: Link, to: '/', onClick: handleBackHome, className: classes.btnBackHome }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.button.backHome", defaultMessage: "ui.liveStreamRoom.button.backHome" }) })), endConferenceEndContent] })) }) }))) : (_jsx(CircularProgress, {})) })) })));
}
