// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { Dropdown, Label, mergeStyles, Stack } from '@fluentui/react';
import { DefaultButton } from '@fluentui/react';
import { useEffect } from 'react';
import { useTheme } from "../../../../../react-components/src";
import React from 'react';
import { CallCompositeIcon } from '../../common/icons';
import { useLocale } from '../../localization';
import { deviceSelectionContainerStyles, dropDownStyles, dropDownTitleIconStyles, mainStackTokens, optionIconStyles, soundStackTokens } from '../styles/LocalDeviceSettings.styles';
import { useAdapter } from '../adapter/CallAdapterProvider';
import { ConfigurationPageCameraDropdown } from './ConfigurationPageCameraDropdown';
import { ConfigurationPageMicDropdown } from './ConfigurationPageMicDropdown';
import { cameraAndVideoEffectsContainerStyleDesktop } from '../styles/CallConfiguration.styles';
import { effectsButtonStyles } from '../styles/CallConfiguration.styles';
import { useSelector } from '../hooks/useSelector';
import { getRole, getVideoEffectsDependency } from '../selectors/baseSelectors';
import { getEnvironmentInfo } from '../selectors/baseSelectors';
import { _isSafari } from '../utils';
import { useId } from '@fluentui/react-hooks';
const getDropDownList = (list) => {
    // Remove duplicates
    const noDuplicates = new Map();
    for (const item of list) {
        noDuplicates.set(item.id, item);
    }
    const dropdownList = [];
    for (const item of noDuplicates.values()) {
        dropdownList.push({
            key: item.id,
            text: item.name === '' ? item.deviceType : item.name
        });
    }
    return dropdownList;
};
const getOptionIcon = (type) => {
    if (type === 'Camera') {
        return React.createElement(CallCompositeIcon, { iconName: "LocalDeviceSettingsCamera", className: optionIconStyles });
    }
    else if (type === 'Microphone') {
        return React.createElement(CallCompositeIcon, { iconName: "LocalDeviceSettingsMic", className: optionIconStyles });
    }
    else if (type === 'Speaker') {
        return React.createElement(CallCompositeIcon, { iconName: "LocalDeviceSettingsSpeaker", className: optionIconStyles });
    }
    else {
        return undefined;
    }
};
const onRenderTitle = (iconType, props) => {
    var _a;
    return props ? React.createElement("div", { className: dropDownTitleIconStyles },
        getOptionIcon(iconType),
        React.createElement("span", null, (_a = props[0]) === null || _a === void 0 ? void 0 : _a.text)) : React.createElement(React.Fragment, null);
};
const localVideoViewOptions = {
    scalingMode: 'Crop',
    isMirrored: true
};
/**
 * @private
 */
export const LocalDeviceSettings = (props) => {
    var _a;
    const theme = useTheme();
    const locale = useLocale();
    const adapter = useAdapter();
    const onResolveVideoEffectDependency = useSelector(getVideoEffectsDependency);
    const defaultPlaceHolder = locale.strings.call.defaultPlaceHolder;
    const cameraLabel = locale.strings.call.cameraLabel;
    const soundLabel = locale.strings.call.soundLabel;
    const noSpeakersLabel = locale.strings.call.noSpeakersLabel;
    const noCameraLabel = locale.strings.call.noCamerasLabel;
    const noMicLabel = locale.strings.call.noMicrophonesLabel;
    const role = useSelector(getRole);
    const cameraPermissionGranted = props.cameraPermissionGranted;
    const micPermissionGranted = props.microphonePermissionGranted;
    const roleCanUseCamera = role !== 'Consumer';
    const roleCanUseMic = role !== 'Consumer';
    // TODO: speaker permission is tied to microphone permission (when you request 'audio' permission using the SDK) its
    // actually granting access to query both microphone and speaker. However the browser popup asks you explicity for
    // 'microphone'. This needs investigation on how we want to handle this and maybe needs follow up with SDK team.
    useEffect(() => {
        if (cameraPermissionGranted) {
            adapter.queryCameras();
        }
        if (micPermissionGranted) {
            adapter.queryMicrophones();
        }
        adapter.querySpeakers();
    }, [adapter, cameraPermissionGranted, micPermissionGranted]);
    const hasCameras = props.cameras.length > 0;
    const hasMicrophones = props.microphones.length > 0;
    const hasSpeakers = props.speakers.length > 0;
    const environmentInfo = useSelector(getEnvironmentInfo);
    const isSafariWithNoSpeakers = _isSafari(environmentInfo) && !hasSpeakers;
    const cameraLabelId = useId('camera-label');
    const soundLabelId = useId('sound-label');
    const cameraGrantedDropdown = React.createElement(Dropdown, { "data-ui-id": "call-composite-local-camera-settings", "aria-labelledby": cameraLabelId, placeholder: hasCameras ? defaultPlaceHolder : noCameraLabel, options: cameraPermissionGranted ? getDropDownList(props.cameras) : [{
                key: 'deniedOrUnknown',
                text: ''
            }], styles: dropDownStyles(theme), disabled: !cameraPermissionGranted || !hasCameras, errorMessage: props.cameraPermissionGranted === undefined || props.cameraPermissionGranted ? undefined : locale.strings.call.cameraPermissionDenied, defaultSelectedKey: micPermissionGranted ? props.selectedCamera ? props.selectedCamera.id : props.cameras ? (_a = props.cameras[0]) === null || _a === void 0 ? void 0 : _a.id : '' : 'deniedOrUnknown', onChange: (event, option, index) => __awaiter(void 0, void 0, void 0, function* () {
            const camera = props.cameras[index !== null && index !== void 0 ? index : 0];
            if (camera) {
                yield props.onSelectCamera(camera, localVideoViewOptions);
            }
            else {
                console.error('No cameras available');
            }
        }), onRenderTitle: (props) => onRenderTitle('Camera', props) });
    const micGrantedDropdown = React.createElement(React.Fragment, null, roleCanUseMic && React.createElement(Dropdown, { "aria-labelledby": soundLabelId, placeholder: hasMicrophones ? defaultPlaceHolder : noMicLabel, styles: dropDownStyles(theme), disabled: !micPermissionGranted || !hasMicrophones, errorMessage: props.microphonePermissionGranted === undefined || props.microphonePermissionGranted ? undefined : locale.strings.call.microphonePermissionDenied, options: micPermissionGranted ? getDropDownList(props.microphones) : [{
                key: 'deniedOrUnknown',
                text: ''
            }], defaultSelectedKey: micPermissionGranted ? props.selectedMicrophone ? props.selectedMicrophone.id : defaultDeviceId(props.microphones) : 'deniedOrUnknown', onChange: (event, option, index) => {
            const microphone = props.microphones[index !== null && index !== void 0 ? index : 0];
            if (microphone) {
                props.onSelectMicrophone(microphone);
            }
            else {
                console.error('No microphones available');
            }
        }, onRenderTitle: (props) => onRenderTitle('Microphone', props) }));
    const speakerDropdown = React.createElement(Dropdown, { "aria-labelledby": soundLabelId, placeholder: hasSpeakers ? defaultPlaceHolder : noSpeakersLabel, styles: dropDownStyles(theme), disabled: props.speakers.length === 0, options: getDropDownList(props.speakers), defaultSelectedKey: props.selectedSpeaker ? props.selectedSpeaker.id : defaultDeviceId(props.speakers), onChange: (event, option, index) => {
            const speaker = props.speakers[index !== null && index !== void 0 ? index : 0];
            if (speaker) {
                props.onSelectSpeaker(speaker);
            }
            else {
                console.error('No speakers available');
            }
        }, onRenderTitle: (props) => onRenderTitle('Speaker', props) });
    return React.createElement(Stack, { "data-ui-id": "call-composite-device-settings", tokens: mainStackTokens, styles: deviceSelectionContainerStyles },
        roleCanUseCamera && React.createElement(Stack, null,
            React.createElement(Stack, { horizontal: true, horizontalAlign: "space-between", styles: cameraAndVideoEffectsContainerStyleDesktop },
                React.createElement(Label, { id: cameraLabelId, className: mergeStyles(dropDownStyles(theme).label) }, cameraLabel),
                onResolveVideoEffectDependency && React.createElement(DefaultButton, { iconProps: {
                        iconName: 'ConfigurationScreenVideoEffectsButton'
                    }, styles: effectsButtonStyles(theme, !cameraPermissionGranted), onClick: props.onClickVideoEffects, disabled: !cameraPermissionGranted, "data-ui-id": 'call-config-video-effects-button' }, locale.strings.call.configurationPageVideoEffectsButtonLabel)),
            React.createElement(ConfigurationPageCameraDropdown, { cameraGrantedDropdown: cameraGrantedDropdown, cameraPermissionGranted: cameraPermissionGranted !== null && cameraPermissionGranted !== void 0 ? cameraPermissionGranted : false, ariaLabelledby: cameraLabelId })),
        React.createElement(Stack, null,
            React.createElement(Label, { id: soundLabelId, className: mergeStyles(dropDownStyles(theme).label) }, soundLabel),
            React.createElement(Stack, { "data-ui-id": "call-composite-sound-settings", tokens: soundStackTokens },
                React.createElement(ConfigurationPageMicDropdown, { micGrantedDropdown: micGrantedDropdown, micPermissionGranted: micPermissionGranted !== null && micPermissionGranted !== void 0 ? micPermissionGranted : false, ariaLabelledby: soundLabelId }),
                isSafariWithNoSpeakers ? React.createElement(React.Fragment, null) : speakerDropdown)));
};
const defaultDeviceId = (devices) => {
    var _a;
    if (devices.length === 0) {
        return undefined;
    }
    const defaultDevice = devices.find(device => device.isSystemDefault);
    if (defaultDevice) {
        return defaultDevice.id;
    }
    return (_a = devices[0]) === null || _a === void 0 ? void 0 : _a.id;
};
//# sourceMappingURL=LocalDeviceSettings.js.map