"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAction = void 0;
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const react_1 = require("react");
const logs_1 = require("@ledgerhq/logs");
const app_1 = require("./app");
const account_1 = require("../../account");
const types_1 = require("../../exchange/types");
const isIntegrationTestEnv_1 = require("../../exchange/swap/utils/isIntegrationTestEnv");
const mapResult = ({ startExchangeResult, startExchangeError, }) => startExchangeResult
    ? {
        startExchangeResult,
    }
    : startExchangeError
        ? {
            startExchangeError,
        }
        : null;
const initialState = {
    startExchangeResult: null,
    startExchangeError: null,
    freezeReduxDevice: false,
    isLoading: false,
};
const reducer = (state, e) => {
    switch (e.type) {
        case "start-exchange":
            return { ...state, freezeReduxDevice: true };
        case "start-exchange-error":
            return { ...state, startExchangeError: e.startExchangeError, isLoading: false };
        case "start-exchange-result":
            return {
                ...state,
                startExchangeResult: {
                    nonce: e.startExchangeResult.nonce,
                    device: e.startExchangeResult.device,
                },
                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, startExchangeExec) => {
    const useHook = (reduxDevice, startExchangeRequest) => {
        const [state, setState] = (0, react_1.useState)(initialState);
        const reduxDeviceFrozen = useFrozenValue(reduxDevice, state.freezeReduxDevice);
        const { exchangeType, provider, exchange } = startExchangeRequest;
        const requireLatestFirmware = true;
        const mainFromAccount = exchange
            ? (0, account_1.getMainAccount)(exchange.fromAccount, exchange.fromParentAccount)
            : null;
        const mainToAccount = exchange && (0, types_1.isExchangeSwap)(exchange)
            ? (0, account_1.getMainAccount)(exchange.toAccount, exchange.toParentAccount)
            : null;
        const request = (0, react_1.useMemo)(() => {
            if ((0, isIntegrationTestEnv_1.isSwapDisableAppsInstall)()) {
                return {
                    appName: "Exchange",
                };
            }
            const dependencies = [];
            if (mainFromAccount) {
                dependencies.push({ appName: mainFromAccount?.currency?.managerAppName });
            }
            if (mainToAccount) {
                dependencies.push({ appName: mainToAccount?.currency?.managerAppName });
            }
            const shouldAddEthApp = (mainFromAccount?.currency?.family === "evm" ||
                mainToAccount?.currency?.family === "evm") &&
                mainFromAccount?.currency?.managerAppName !== "Ethereum" &&
                mainToAccount?.currency?.managerAppName !== "Ethereum";
            // Check if we should add ETH app, for cases like when we want AVAX to use the ETH app.
            if (shouldAddEthApp) {
                dependencies.push({
                    appName: "Ethereum",
                });
            }
            return {
                appName: "Exchange",
                dependencies,
                requireLatestFirmware,
            };
        }, [mainFromAccount, mainToAccount, requireLatestFirmware]);
        const appState = (0, app_1.createAction)(connectAppExec).useHook(reduxDeviceFrozen, request);
        const { device, opened, error, appAndVersion } = appState;
        const hasError = error || state.error;
        (0, react_1.useEffect)(() => {
            if (!opened || !device) {
                // isLoading should be false until we have a device to show the correct animation
                setState({ ...initialState, isLoading: device ? !hasError : false });
                return;
            }
            const sub = (0, rxjs_1.concat)((0, rxjs_1.of)({
                type: "start-exchange",
            }), startExchangeExec({
                device,
                exchangeType,
                provider,
                appVersion: appAndVersion?.version,
            }))
                .pipe((0, operators_1.tap)(e => {
                (0, logs_1.log)("actions-startExchange-event", JSON.stringify(e));
            }), (0, operators_1.scan)(reducer, initialState))
                .subscribe(setState);
            return () => {
                sub.unsubscribe();
            };
        }, [exchange, device, opened, exchangeType, hasError, appAndVersion, provider]);
        return {
            ...appState,
            ...state,
        };
    };
    return {
        useHook,
        mapResult,
    };
};
exports.createAction = createAction;
//# sourceMappingURL=startExchange.js.map