import { useLingui } from '../../../../../../node_modules/@lingui/react/dist/index.mjs';
import React__default, { useRef, useState, useLayoutEffect } from 'react';
import Button from '../../components/atoms/Button.mjs';
import CodeContainer from '../../components/atoms/CodeContainer.mjs';
import Column from '../../components/atoms/Column.mjs';
import { errorToast } from '../../components/atoms/Toast.mjs';
import Typography from '../../components/atoms/Typography.mjs';
import VerticalTransition, { useTimedBoolean } from '../../components/atoms/VerticalTransition.mjs';
import ButtonColumn from '../../components/molecules/ButtonColumn.mjs';
import TextColumn from '../../components/molecules/TextColumn.mjs';
import { useGlobalReducer } from '../GlobalContextProvider.mjs';
import { AppScreens } from '../types/AppScreens.mjs';
import modules_f9925f51 from './TOTPEnrollManualScreen.module.css.mjs';

const CHUNK_SIZE = 4;
const TOTPEnrollManualScreen = ()=>{
    const [state, dispatch] = useGlobalReducer();
    const { i18n: $__i18n, _: $__ } = useLingui();
    const [copied, setCopied] = useTimedBoolean(3);
    // This screen should only be shown if TOTP enrollment is available
    const { secret } = state.mfa.totp.enrollment;
    const displaySecret = secret.toLowerCase();
    const secretChunked = displaySecret.split(new RegExp(`(.{${CHUNK_SIZE}})`, 'g')).filter(Boolean);
    const { codeRef, columnCount } = useColumnCount(secretChunked.length);
    const handleBack = ()=>dispatch({
            type: 'navigate_back'
        });
    const handleContinue = ()=>{
        dispatch({
            type: 'transition',
            history: 'push',
            screen: AppScreens.TOTPEntry
        });
    };
    const handleCodeCopy = async ()=>{
        try {
            await navigator.clipboard.writeText(displaySecret);
            setCopied(true);
        } catch  {
            errorToast({
                message: $__i18n._({
                    id: "mfa.totpEnrollment.toast.copyFailed",
                    message: "Couldn't copy code to clipboard"
                })
            });
            // Select all text instead as fallback
            const selection = window.getSelection();
            if (codeRef.current && selection) {
                selection.empty();
                const range = document.createRange();
                range.selectNodeContents(codeRef.current);
                selection.addRange(range);
            }
        }
    };
    return /*#__PURE__*/ React__default.createElement(Column, {
        gap: 6
    }, /*#__PURE__*/ React__default.createElement(TextColumn, {
        header: $__i18n._({
            id: "mfa.totpEnrollment.title",
            message: "Having trouble scanning the QR code?"
        }),
        body: $__i18n._({
            id: "mfa.totpEnrollment.content",
            message: "Click to copy the code below. Enter into your authenticator app to link your account."
        })
    }), /*#__PURE__*/ React__default.createElement(CodeContainer, {
        className: modules_f9925f51.codeContainer,
        onClick: handleCodeCopy
    }, /*#__PURE__*/ React__default.createElement(Typography, {
        ref: codeRef,
        className: modules_f9925f51.code,
        style: {
            '--st-column-count': columnCount,
            '--st-chunk-size': CHUNK_SIZE + 'ch'
        },
        font: "mono"
    }, secretChunked.map((part, i)=>/*#__PURE__*/ React__default.createElement("span", {
            key: i
        }, part)))), /*#__PURE__*/ React__default.createElement(ButtonColumn, null, /*#__PURE__*/ React__default.createElement(Button, {
        variant: "primary",
        onClick: handleCodeCopy
    }, /*#__PURE__*/ React__default.createElement(VerticalTransition, {
        primary: $__i18n._({
            id: "mfa.totpEnrollment.copyCode.label",
            message: "Copy to clipboard"
        }),
        secondary: $__i18n._({
            id: "mfa.totpEnrollment.copyCode.codeCopied",
            message: "Copied!"
        }),
        triggered: copied
    })), /*#__PURE__*/ React__default.createElement(Button, {
        variant: "outline",
        onClick: handleContinue
    }, $__i18n._({
        id: "button.continue",
        message: "Continue"
    })), /*#__PURE__*/ React__default.createElement(Button, {
        variant: "ghost",
        onClick: handleBack
    }, $__i18n._({
        id: "button.totpQrRetry",
        message: "Try to scan the QR code again"
    }))));
};
// Balance out the rows - this is fairly complex, but there's not any way to really do this in CSS only
// so instead we read the width of the container and the chunks below it, then use that to calculate
// first the number of rows, then how many chunks can evenly fit per row
function useColumnCount(chunksCount) {
    const codeRef = useRef(null);
    const [columnCount, setColumnCount] = useState();
    useLayoutEffect(()=>{
        const updateRowCount = ()=>{
            if (!codeRef.current) return;
            // Get the width of the container and inner spans
            const containerWidth = codeRef.current.clientWidth;
            const spanWidth = Math.max(...Array.from(codeRef.current.querySelectorAll('span')).map((elem)=>elem.clientWidth));
            // Find the number of columns to display. First compute the raw number
            // Note we don't check how many rows are currently rendered because this number is already affected by
            // the current row count.
            const fittedColumns = Math.floor(containerWidth / spanWidth);
            // Then account for gaps (1ch each, so 1/CHUNK_SIZE per gap)
            const fittedColumnsWithGaps = fittedColumns - Math.floor(fittedColumns / CHUNK_SIZE);
            // Number of rows is count / columns
            const rows = Math.ceil(chunksCount / fittedColumnsWithGaps);
            // And finally the closest even column count is count / rows
            const evenColumns = Math.ceil(chunksCount / rows);
            setColumnCount(evenColumns);
        };
        updateRowCount();
        if (!window.ResizeObserver || !codeRef.current) return;
        const observer = new ResizeObserver(updateRowCount);
        observer.observe(codeRef.current);
        return ()=>observer.disconnect();
    }, [
        chunksCount
    ]);
    return {
        codeRef,
        columnCount
    };
}

export { TOTPEnrollManualScreen };
//# sourceMappingURL=TOTPEnrollManualScreen.mjs.map
