"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAction = void 0;
const logs_1 = require("@ledgerhq/logs");
const react_1 = require("react");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const account_1 = require("../../account");
const app_1 = require("./app");
const mapResult = ({ initSwapResult, initSwapError, swapId, }) => initSwapResult
    ? {
        initSwapResult,
    }
    : initSwapError
        ? {
            initSwapError,
            swapId,
        }
        : null;
const initialState = {
    initSwapResult: null,
    initSwapError: null,
    swapId: undefined,
    initSwapRequested: false,
    isLoading: true,
    freezeReduxDevice: false,
};
const reducer = (state, e) => {
    switch (e.type) {
        case "init-swap":
            return { ...state, freezeReduxDevice: true };
        case "init-swap-error":
            return {
                ...state,
                initSwapError: e.error,
                swapId: e.swapId,
                isLoading: false,
            };
        case "init-swap-requested":
            return {
                ...state,
                initSwapRequested: true,
                isLoading: false,
                amountExpectedTo: e.amountExpectedTo,
                estimatedFees: e.estimatedFees,
            };
        case "init-swap-result":
            return {
                ...state,
                initSwapResult: e.initSwapResult,
                isLoading: false,
            };
    }
};
function useFrozenValue(value, frozen) {
    const [state, setState] = (0, react_1.useState)(value);
    (0, react_1.useEffect)(() => {
        if (!frozen) {
            setState(value);
        }
    }, [value, frozen]);
    return state;
}
const createAction = (connectAppExec, initSwapExec) => {
    const useHook = (reduxDevice, initSwapRequest) => {
        const [state, setState] = (0, react_1.useState)(initialState);
        const reduxDeviceFrozen = useFrozenValue(reduxDevice, state.freezeReduxDevice);
        const { exchange, exchangeRate, transaction, requireLatestFirmware } = initSwapRequest;
        const { fromAccount, fromParentAccount, toAccount, toParentAccount } = exchange;
        const mainFromAccount = (0, account_1.getMainAccount)(fromAccount, fromParentAccount);
        const maintoAccount = (0, account_1.getMainAccount)(toAccount, toParentAccount);
        const request = (0, react_1.useMemo)(() => {
            return {
                appName: "Exchange",
                dependencies: [
                    {
                        account: mainFromAccount,
                    },
                    {
                        account: maintoAccount,
                    },
                ],
                requireLatestFirmware,
            };
        }, [mainFromAccount, maintoAccount, requireLatestFirmware]);
        const appState = (0, app_1.createAction)(connectAppExec).useHook(reduxDeviceFrozen, request);
        const { device, opened, error } = appState;
        const hasError = error || state.error;
        (0, react_1.useEffect)(() => {
            if (!opened || !device) {
                setState({ ...initialState, isLoading: !!device });
                return;
            }
            const sub = (0, rxjs_1.concat)((0, rxjs_1.of)({
                type: "init-swap",
            }), initSwapExec({
                exchange,
                exchangeRate,
                transaction,
                deviceId: device.deviceId,
            }))
                .pipe((0, operators_1.tap)(e => {
                (0, logs_1.log)("actions-initSwap-event", e.type, e);
            }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)({
                type: "init-swap-error",
                error,
            })), (0, operators_1.scan)(reducer, { ...initialState, isLoading: !hasError }))
                .subscribe(setState);
            return () => {
                sub.unsubscribe();
            };
        }, [exchange, exchangeRate, transaction, device, opened, hasError]);
        return {
            ...appState,
            ...state,
        };
    };
    return {
        useHook,
        mapResult,
    };
};
exports.createAction = createAction;
//# sourceMappingURL=initSwap.js.map