"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useOnboardingStatePolling = void 0;
const react_1 = require("react");
const isEqual_1 = __importDefault(require("lodash/isEqual"));
const errors_1 = require("@ledgerhq/errors");
const getOnboardingStatePolling_1 = require("../../hw/getOnboardingStatePolling");
/**
 * Polls the current device onboarding state, and notify the hook consumer of
 * any allowed errors and fatal errors
 * @param getOnboardingStatePolling A polling function, by default set to live-common/hw/getOnboardingStatePolling.
 * This dependency injection is needed for LLD to have the polling working on the internal thread
 * @param device A Device object
 * @param pollingPeriodMs The period in ms after which the device onboarding state is fetched again
 * @param stopPolling Flag to stop or continue the polling
 * @returns An object containing:
 * - onboardingState: the device state during the onboarding
 * - allowedError: any error that is allowed and does not stop the polling
 * - fatalError: any error that is fatal and stops the polling
 * - lockedDevice: a boolean set to true if the device is currently locked, false otherwise
 * - resetStates: a function to reset the values of: onboardingState, allowedError, fatalError and lockedDevice
 */
const useOnboardingStatePolling = ({ getOnboardingStatePolling = getOnboardingStatePolling_1.getOnboardingStatePolling, device, pollingPeriodMs, stopPolling = false, allowedErrorChecks = [], }) => {
    const [onboardingState, setOnboardingState] = (0, react_1.useState)(null);
    const [allowedError, setAllowedError] = (0, react_1.useState)(null);
    const [fatalError, setFatalError] = (0, react_1.useState)(null);
    const [lockedDevice, setLockedDevice] = (0, react_1.useState)(false);
    (0, react_1.useEffect)(() => {
        let onboardingStatePollingSubscription;
        // If stopPolling is updated and set to true, the useEffect hook will call its
        // cleanup function (return) and the polling won't restart with the below condition
        if (device && !stopPolling) {
            onboardingStatePollingSubscription = getOnboardingStatePolling({
                deviceId: device.deviceId,
                deviceName: device.deviceName ?? null,
                pollingPeriodMs,
                allowedErrorChecks,
            }).subscribe({
                next: (onboardingStatePollingResult) => {
                    if (onboardingStatePollingResult) {
                        setFatalError(null);
                        setLockedDevice(onboardingStatePollingResult.lockedDevice);
                        // Only updates if the new allowedError is different
                        setAllowedError(prevAllowedError => getNewAllowedErrorIfChanged(prevAllowedError, onboardingStatePollingResult.allowedError));
                        // Does not update the onboarding state if an allowed error occurred
                        if (!onboardingStatePollingResult.allowedError) {
                            // Only updates if the new onboardingState is different
                            setOnboardingState(prevOnboardingState => getNewOnboardingStateIfChanged(prevOnboardingState, onboardingStatePollingResult.onboardingState));
                        }
                    }
                },
                error: error => {
                    setAllowedError(null);
                    setLockedDevice(false);
                    setFatalError(error instanceof Error
                        ? error
                        : new errors_1.DeviceOnboardingStatePollingError(`Error from: ${error?.name ?? error} ${error?.message}`));
                },
            });
        }
        return () => {
            onboardingStatePollingSubscription?.unsubscribe();
        };
    }, [
        device,
        pollingPeriodMs,
        setOnboardingState,
        setAllowedError,
        setFatalError,
        stopPolling,
        getOnboardingStatePolling,
    ]);
    const resetStates = (0, react_1.useCallback)(() => {
        setOnboardingState(null);
        setAllowedError(null);
        setFatalError(null);
        setLockedDevice(false);
    }, []);
    return { onboardingState, allowedError, fatalError, lockedDevice, resetStates };
};
exports.useOnboardingStatePolling = useOnboardingStatePolling;
const getNewOnboardingStateIfChanged = (prevOnboardingState, newOnboardingState) => {
    return (0, isEqual_1.default)(prevOnboardingState, newOnboardingState)
        ? prevOnboardingState
        : newOnboardingState;
};
const getNewAllowedErrorIfChanged = (prevError, newError) => {
    // Only interested if the errors are instances of the same Error class
    return prevError?.constructor === newError?.constructor ? prevError : newError;
};
//# sourceMappingURL=useOnboardingStatePolling.js.map