import { __rest } from "tslib";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Alert, AlertTitle, Box, Button, CircularProgress, Stack, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';
import { useThemeProps } from '@mui/system';
import { Link, SCPreferences, useSCFetchLiveStream, useSCPreferences, useSCUser } from '@selfcommunity/react-core';
import { SCFeatureName, SCLiveStreamConnectionDetailsErrorType } from '@selfcommunity/types';
import classNames from 'classnames';
import { FormattedMessage, useIntl } from 'react-intl';
import { PREFIX } from './constants';
import { useCallback, useMemo, useState } from 'react';
import LiveStreamVideoConference from './LiveStreamVideoConference';
import '@livekit/components-styles';
import { LiveStreamService } from '@selfcommunity/api-services';
import { camelCase, Logger } from '@selfcommunity/utils';
import { SCOPE_SC_UI } from '../../constants/Errors';
import { PreJoin } from './LiveStreamVideoConference/PreJoin';
import { LiveStreamContext } from './LiveStreamVideoConference/LiveStreamProvider';
import { useSnackbar } from 'notistack';
import DialogContent from '@mui/material/DialogContent';
import BaseDialog from '../../shared/BaseDialog';
const classes = {
    root: `${PREFIX}-root`,
    content: `${PREFIX}-content`,
    title: `${PREFIX}-title`,
    description: `${PREFIX}-description`,
    endConferenceWrap: `${PREFIX}-end-conference-wrap`,
    btnBackHome: `${PREFIX}-btn-back-home`,
    startPrejoinContent: `${PREFIX}-start-prejoin-content`,
    preJoin: `${PREFIX}-prejoin`,
    preJoinLoading: `${PREFIX}-prejoin-loading`,
    prejoinLoader: `${PREFIX}-prejoin-loader`,
    endPrejoinContent: `${PREFIX}-end-prejoin-content`,
    conference: `${PREFIX}-conference`,
    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 }) => ({}));
/**
 *> API documentation for the Community-JS LiveStreamRoom component. Learn about the available props and the CSS API.
 *
 #### Import
 ```jsx
 import {LiveStreamRoom} from '@selfcommunity/react-ui';
 ```

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

 #### CSS

 |Rule Name|Global class|Description|
 |---|---|---|
 |root|.SCLiveStreamRoom-root|Styles applied to the root element.|
 |title|.SCLiveStreamRoom-title|Styles applied to the title element.|
 |description|.SCLiveStreamRoom-description|Styles applied to the description element.|
 |content|.SCLiveStreamRoom-content|Styles applied to the content.|
 |prejoin|.SCLiveStreamRoom-prejoin|Styles applied to the prejoin.|
 |conference|.SCLiveStreamRoom-conference|Styles applied to the conference.|
 |error|.SCLiveStreamRoom-error|Styles applied to the error elements.|

 * @param inProps
 */
export default function LiveStreamRoom(inProps) {
    var _a, _b, _c, _d, _e, _f;
    //PROPS
    const props = useThemeProps({
        props: inProps,
        name: PREFIX
    });
    const { id = `live_stream_room_object_${props.liveStreamId ? props.liveStreamId : props.liveStream ? props.liveStream.id : ''}`, liveStreamId = null, liveStream = null, className, showPrejoinTitle = true, showPrejoinDescription = false, startPrejoinContent, endPrejoinContent, presetConnectionDetails, presetPreJoinChoices, LiveStreamVideoConferenceComponentProps = { options: { codec: 'vp8', hq: false } } } = props, rest = __rest(props, ["id", "liveStreamId", "liveStream", "className", "showPrejoinTitle", "showPrejoinDescription", "startPrejoinContent", "endPrejoinContent", "presetConnectionDetails", "presetPreJoinChoices", "LiveStreamVideoConferenceComponentProps"]);
    // CONTEXT
    const scUserContext = useSCUser();
    const { preferences, features } = useSCPreferences();
    // STATE
    const { scLiveStream } = useSCFetchLiveStream({ id: liveStreamId, liveStream });
    const [preJoinChoices, setPreJoinChoices] = useState(presetPreJoinChoices);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    const preJoinDefaults = useMemo(() => {
        var _a, _b, _c;
        return {
            username: ((_a = scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) || '',
            videoEnabled: ((_b = scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.settings) === null || _b === void 0 ? void 0 : _b.disableVideo) === false,
            audioEnabled: ((_c = scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.settings) === null || _c === void 0 ? void 0 : _c.muteParticipants) === false
        };
    }, [scUserContext.user, scLiveStream]);
    const [connectionDetails, setConnectionDetails] = useState(presetConnectionDetails);
    const liveStreamEnabled = useMemo(() => preferences &&
        features &&
        features.includes(SCFeatureName.LIVE_STREAM) &&
        SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED in preferences &&
        preferences[SCPreferences.CONFIGURATIONS_LIVE_STREAM_ENABLED].value, [preferences, features]);
    // INTL
    const intl = useIntl();
    // MESSAGES
    const { enqueueSnackbar } = useSnackbar();
    // HANDLERS
    /**
     * Handle PreJoin Submit
     */
    const handlePreJoinSubmit = useCallback((values) => {
        if (scLiveStream || !loading) {
            setLoading(true);
            setError(null);
            toggleAttrDisabledPrejoinActions(true);
            LiveStreamService.join(scLiveStream.id)
                .then((data) => {
                setPreJoinChoices(values);
                setConnectionDetails(Object.assign(Object.assign({}, data), { participantName: scUserContext.user.username }));
                toggleAttrDisabledPrejoinActions(false);
                setLoading(false);
            })
                .catch((error) => {
                Logger.error(SCOPE_SC_UI, error);
                if (error.response &&
                    error.response.data &&
                    typeof error.response.data === 'object' &&
                    error.response.data.errors &&
                    error.response.data.errors.length) {
                    let _msg = intl.formatMessage({
                        id: 'ui.liveStreamRoom.connect.error.generic',
                        defaultMessage: 'ui.liveStreamRoom.connect.error.generic'
                    });
                    if (error.response.data.errors[0].code) {
                        const _error = `ui.liveStreamRoom.connect.error.${camelCase(error.response.data.errors[0].code)}`;
                        _msg = intl.formatMessage({ id: _error, defaultMessage: _error });
                        if (error.response.data.errors[0].code !== SCLiveStreamConnectionDetailsErrorType.WAITING_HOST_TO_START_LIVE_STREAM) {
                            setError(_msg);
                        }
                        else {
                            setTimeout(() => toggleAttrDisabledPrejoinActions(false), 3000);
                        }
                        enqueueSnackbar(_msg, { variant: 'error', autoHideDuration: 5000 });
                    }
                    else {
                        enqueueSnackbar(_msg, { variant: 'error' });
                        setError(_msg);
                    }
                }
                setLoading(false);
            });
        }
    }, [scUserContext.user, setPreJoinChoices, setConnectionDetails, scLiveStream, setError, loading]);
    /**
     * Handle disable controls button
     */
    const toggleAttrDisabledPrejoinActions = useCallback((disabled) => {
        const container = document.querySelector('.lk-prejoin');
        if (container) {
            const buttons = container.querySelectorAll('button.lk-button');
            buttons.forEach((button) => {
                // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                // @ts-ignore
                button.disabled = disabled;
            });
        }
    }, []);
    /**
     * Handle PreJoin Error
     */
    const handlePreJoinError = useCallback((e) => console.error(e), []);
    /**
     * User must be authenticated
     */
    if (!scLiveStream || !scUserContext.user || !liveStreamEnabled) {
        return _jsx(CircularProgress, {});
    }
    /**
     * Renders root object
     */
    return (_jsx(Root, Object.assign({ id: id, className: classNames(classes.root, className) }, rest, { children: scLiveStream.closed_at_by_host ? (_jsx(DialogRoot, Object.assign({ open: true, maxWidth: 'md', fullWidth: true }, { children: _jsxs(DialogContent, Object.assign({ className: classes.endConferenceWrap }, { children: [_jsx(Typography, Object.assign({ variant: "h5" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.conference.closed", defaultMessage: "ui.liveStreamRoom.conference.closed" }) })), _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" }) }))] })) }))) : (_jsx(Box, Object.assign({ className: classes.content, "data-lk-theme": "default" }, { children: connectionDetails === undefined || preJoinChoices === undefined ? (_jsxs(_Fragment, { children: [startPrejoinContent && _jsx(Box, Object.assign({ className: classes.startPrejoinContent }, { children: startPrejoinContent })), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title) && (_jsx(Typography, Object.assign({ component: 'div', variant: "h5", className: classes.title }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.title }))), (scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description) && (_jsx(Typography, Object.assign({ component: 'div', variant: "body1", className: classes.description }, { children: scLiveStream === null || scLiveStream === void 0 ? void 0 : scLiveStream.description }))), _jsxs(Box, Object.assign({ className: classNames(classes.preJoin, { [classes.preJoinLoading]: loading || error }) }, { children: [_jsx(LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: _jsx(PreJoin, { defaults: preJoinDefaults, onSubmit: handlePreJoinSubmit, onError: handlePreJoinError, joinLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.joinRoom', defaultMessage: 'ui.liveStreamRoom.preJoin.joinRoom' }), micLabel: intl.formatMessage({
                                        id: 'ui.liveStreamRoom.preJoin.microphone',
                                        defaultMessage: 'ui.liveStreamRoom.preJoin.microphone'
                                    }), camLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.camera', defaultMessage: 'ui.liveStreamRoom.preJoin.camera' }), userLabel: intl.formatMessage({ id: 'ui.liveStreamRoom.preJoin.username', defaultMessage: 'ui.liveStreamRoom.preJoin.username' }) }) })), loading && (_jsxs(Box, Object.assign({ className: classes.prejoinLoader }, { children: [_jsx(CircularProgress, {}), _jsx(Typography, Object.assign({ component: 'div', variant: "body2" }, { children: _jsx(FormattedMessage, { id: "ui.liveStreamRoom.connecting", defaultMessage: "ui.liveStreamRoom.connecting" }) }))] })))] })), _jsxs(Box, Object.assign({ className: classes.endPrejoinContent }, { children: [Boolean(scUserContext.user &&
                                scUserContext.user.id !== scLiveStream.host.id &&
                                scLiveStream &&
                                (((_a = scLiveStream.settings) === null || _a === void 0 ? void 0 : _a.muteParticipants) || (scLiveStream && ((_b = scLiveStream.settings) === null || _b === void 0 ? void 0 : _b.disableVideo)))) && (_jsx(Stack, Object.assign({ sx: { width: '45%' }, spacing: 1 }, { children: scLiveStream && (((_c = scLiveStream.settings) === null || _c === void 0 ? void 0 : _c.muteParticipants) || ((_d = scLiveStream.settings) === null || _d === void 0 ? void 0 : _d.disableVideo)) && (_jsxs(Alert, Object.assign({ variant: "filled", severity: "info" }, { children: [_jsx(AlertTitle, { children: _jsx("b", { children: "Info" }) }), ((_e = scLiveStream.settings) === null || _e === void 0 ? void 0 : _e.muteParticipants) && (_jsxs(_Fragment, { children: ["-", ' ', _jsx(FormattedMessage, { id: "ui.liveStreamRoom.hostDisableMicrophone", defaultMessage: "ui.liveStreamRoom.hostDisableMicrophone" }), _jsx("br", {})] })), ((_f = scLiveStream.settings) === null || _f === void 0 ? void 0 : _f.disableVideo) && (_jsxs(_Fragment, { children: ["- ", _jsx(FormattedMessage, { id: "ui.liveStreamRoom.hostDisableVideo", defaultMessage: "ui.liveStreamRoom.hostDisableVideo" })] }))] }))) }))), endPrejoinContent] }))] })) : (_jsx(Box, Object.assign({ className: classes.conference }, { children: _jsx(LiveStreamContext.Provider, Object.assign({ value: { liveStream: scLiveStream } }, { children: _jsx(LiveStreamVideoConference, Object.assign({ connectionDetails: connectionDetails, userChoices: preJoinChoices }, LiveStreamVideoConferenceComponentProps)) })) }))) }))) })));
}
