// 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 React, { useEffect, useRef } from 'react';
import { IconButton } from '@fluentui/react';
import { concatStyleSets, DefaultButton, FocusZone, mergeStyles, Stack, Text, TextField, useTheme } from '@fluentui/react';
import { useState } from 'react';
import { useLocale } from '../../localization';
import { buttonStyles, containerStyles, iconButtonStyles, digitStyles, letterStyles, textFieldStyles } from '../styles/Dialpad.styles';
import { _formatPhoneNumber } from '../utils/formatPhoneNumber';
import useLongPress from '../utils/useLongPress';
import { dtmfFrequencies, Tone } from './DTMFToneGenerator';
const dialPadButtonsDefault = [[{
            digit: '1'
        }, {
            digit: '2',
            letter: 'ABC'
        }, {
            digit: '3',
            letter: 'DEF'
        }], [{
            digit: '4',
            letter: 'GHI'
        }, {
            digit: '5',
            letter: 'JKL'
        }, {
            digit: '6',
            letter: 'MNO'
        }], [{
            digit: '7',
            letter: 'PQRS'
        }, {
            digit: '8',
            letter: 'TUV'
        }, {
            digit: '9',
            letter: 'WXYZ'
        }], [{
            digit: '*'
        }, {
            digit: '0',
            letter: '+'
        }, {
            digit: '#'
        }]];
const DtmfTones = ['Num1', 'Num2', 'Num3', 'Num4', 'Num5', 'Num6', 'Num7', 'Num8', 'Num9', 'Star', 'Num0', 'Pound'];
const DialpadButton = (props) => {
    var _a, _b, _c, _d;
    const theme = useTheme();
    const { digit, index, onClick, onLongPress, longPressTrigger, dtmfToneAudioContext, disableDtmfPlayback } = props;
    const [buttonPressed, setButtonPressed] = useState(false);
    const dtmfToneSound = useRef(new Tone(dtmfToneAudioContext, dtmfFrequencies[digit].f1, dtmfFrequencies[digit].f2));
    const useLongPressProps = React.useMemo(() => ({
        onClick: () => __awaiter(void 0, void 0, void 0, function* () {
            onClick(digit, index);
        }),
        onLongPress: () => __awaiter(void 0, void 0, void 0, function* () {
            onLongPress(digit, index);
        }),
        touchEventsOnly: longPressTrigger === 'touch'
    }), [digit, index, longPressTrigger, onClick, onLongPress]);
    const longPressHandlers = useLongPress(useLongPressProps);
    return React.createElement(DefaultButton, Object.assign({ "data-test-id": `dialpad-button-${props.index}`, styles: concatStyleSets(buttonStyles(theme), (_a = props.styles) === null || _a === void 0 ? void 0 : _a.button) }, longPressHandlers, { onKeyDown: e => {
            if ((e.key === 'Enter' || e.key === ' ') && !buttonPressed) {
                if (!disableDtmfPlayback) {
                    dtmfToneSound.current.play();
                }
                longPressHandlers.onKeyDown();
                setButtonPressed(true);
                return;
            }
            if (e.key === 'Tab' || e.key === 'ArrowLeft' || e.key === 'ArrowRight' || e.key === 'ArrowUp' || e.key === 'ArrowDown') {
                dtmfToneSound.current.stop();
                return;
            }
            longPressHandlers.onKeyDown();
        }, onKeyUp: e => {
            if ((e.key === 'Enter' || e.key === ' ') && buttonPressed) {
                dtmfToneSound.current.stop();
                longPressHandlers.onKeyUp();
                setButtonPressed(false);
            }
            longPressHandlers.onKeyUp();
        }, onMouseDown: () => {
            if (!disableDtmfPlayback) {
                dtmfToneSound.current.play();
            }
            longPressHandlers.onMouseDown();
        }, onMouseUp: () => {
            dtmfToneSound.current.stop();
            longPressHandlers.onMouseUp();
        }, onMouseLeave: () => {
            dtmfToneSound.current.stop();
        }, onTouchStart: () => {
            if (!disableDtmfPlayback) {
                dtmfToneSound.current.play();
            }
            longPressHandlers.onTouchStart();
        }, onTouchEnd: () => {
            dtmfToneSound.current.stop();
            longPressHandlers.onTouchEnd();
        } }),
        React.createElement(Stack, null,
            React.createElement(Text, { className: mergeStyles(digitStyles(theme), (_b = props.styles) === null || _b === void 0 ? void 0 : _b.digit) }, props.digit),
            React.createElement(Text, { className: mergeStyles(letterStyles(theme), (_c = props.styles) === null || _c === void 0 ? void 0 : _c.letter) }, (_d = props.letter) !== null && _d !== void 0 ? _d : ' ')));
};
const DialpadContainer = (props) => {
    var _a, _b;
    const theme = useTheme();
    const { onSendDtmfTone, onClickDialpadButton, textFieldValue, onChange, showDeleteButton = true, longPressTrigger = 'mouseAndTouch', disableDtmfPlayback, dialpadMode = 'dialer', dtmfAudioContext } = props;
    const dtmfToneAudioContext = useRef(dtmfAudioContext ? dtmfAudioContext : new AudioContext());
    const [plainTextValue, setPlainTextValue] = useState(textFieldValue !== null && textFieldValue !== void 0 ? textFieldValue : '');
    const plainTextValuePreviousRenderValue = useRef(plainTextValue);
    useEffect(() => {
        if (plainTextValuePreviousRenderValue.current !== plainTextValue) {
            onChange === null || onChange === void 0 ? void 0 : onChange(plainTextValue);
        }
        plainTextValuePreviousRenderValue.current = plainTextValue;
    }, [plainTextValuePreviousRenderValue, plainTextValue, onChange]);
    useEffect(() => {
        setText(textFieldValue !== null && textFieldValue !== void 0 ? textFieldValue : '');
    }, [textFieldValue]);
    const onClickDialpad = (input, index) => {
        setText(plainTextValue + input);
        const tone = DtmfTones[index];
        if (onSendDtmfTone && tone) {
            onSendDtmfTone(tone);
        }
        if (onClickDialpadButton) {
            onClickDialpadButton(input, index);
        }
    };
    const onLongPressDialpad = (input, index) => {
        if (input === '0' && index === 10) {
            setText(plainTextValue + '+');
        }
        else {
            setText(plainTextValue + input);
        }
        const tone = DtmfTones[index];
        if (onSendDtmfTone && tone) {
            onSendDtmfTone(tone);
        }
        if (onClickDialpadButton) {
            onClickDialpadButton(input, index);
        }
    };
    const setText = (input) => {
        // remove non-valid characters from input: letters,special characters excluding +, *,#
        const plainInput = sanitizeInput(input);
        setPlainTextValue(plainInput);
    };
    const deleteNumbers = () => {
        const modifiedInput = plainTextValue.substring(0, plainTextValue.length - 1);
        setText(modifiedInput);
    };
    return React.createElement(Stack, { className: mergeStyles(containerStyles(theme), (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root), "data-test-id": "dialpadContainer", "data-ui-id": "dialpadContainer", horizontalAlign: 'center' },
        dialpadMode === 'dialer' && React.createElement(TextField, { styles: concatStyleSets(textFieldStyles(theme, plainTextValue !== ''), (_b = props.styles) === null || _b === void 0 ? void 0 : _b.textField), value: textFieldValue ? textFieldValue : _formatPhoneNumber(plainTextValue), 
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            onChange: (e) => {
                setText(e.target.value);
            }, onClick: e => {
                e.preventDefault();
            }, placeholder: props.strings.placeholderText, "data-test-id": "dialpad-input", onRenderSuffix: () => {
                var _a;
                return React.createElement(React.Fragment, null, showDeleteButton && plainTextValue.length !== 0 && React.createElement(IconButton, { ariaLabel: props.strings.deleteButtonAriaLabel, onClick: deleteNumbers, styles: concatStyleSets(iconButtonStyles(theme), (_a = props.styles) === null || _a === void 0 ? void 0 : _a.deleteIcon), iconProps: {
                        iconName: 'DialpadBackspace'
                    } }));
            } }),
        React.createElement(FocusZone, null, dialPadButtonsDefault.map((rows, rowIndex) => {
            return React.createElement(Stack, { horizontal: true, key: `row_${rowIndex}`, horizontalAlign: "stretch", tokens: {
                    childrenGap: '1rem'
                } }, rows.map((button, columnIndex) => React.createElement(DialpadButton, { key: `button_${columnIndex}`, 
                /* row index = 0
                columnIndex: (0,1,2) => (0,1,2)
                row index = 1
                columnIndex: (0,1,2)=> (3,4,5)
                row index = 2
                columnIndex: (0,1,2)=> (6,7,8)
                row index = 3
                columnIndex: (0,1,2)=> (9,10,11)
                columnIndex + rowIndex*rows.length calculates the corresponding index for each button
                dialpad index:
                0 1 2
                3 4 5
                6 7 8
                9 10 11
                then use this index to locate the corresponding dtmf tones
                DtmfTones[index]
                */ index: columnIndex + rowIndex * rows.length, digit: button.digit, letter: button.letter, styles: props.styles, onClick: onClickDialpad, onLongPress: onLongPressDialpad, longPressTrigger: longPressTrigger, dtmfToneAudioContext: dtmfToneAudioContext.current, disableDtmfPlayback: disableDtmfPlayback })));
        })));
};
/**
 * A component to allow users to enter phone number through clicking on dialpad/using keyboard
 * It will return empty component for stable builds
 *
 * @public
 */
export const Dialpad = (props) => {
    const localeStrings = useLocale().strings.dialpad;
    const strings = Object.assign(Object.assign({}, localeStrings), props.strings);
    return React.createElement(DialpadContainer, Object.assign({ strings: strings }, props));
};
const sanitizeInput = (input) => {
    // remove non-valid characters from input: letters,special characters excluding +, *,#
    return input.replace(/[^\d*#+]/g, '');
};
//# sourceMappingURL=Dialpad.js.map