"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSwapTransaction = exports.useFromAmountStatusMessage = exports.selectorStateDefaultValues = void 0;
const index_1 = require("@ledgerhq/coin-framework/account/index");
const index_2 = require("@ledgerhq/coin-framework/currencies/index");
const errors_1 = require("@ledgerhq/errors");
const react_1 = require("react");
const useBridgeTransaction_1 = __importDefault(require("../../../bridge/useBridgeTransaction"));
const useFromState_1 = require("./useFromState");
const useReverseAccounts_1 = require("./useReverseAccounts");
const useToState_1 = require("./useToState");
const useUpdateMaxAmount_1 = require("./useUpdateMaxAmount");
const useProviderRates_1 = require("./v5/useProviderRates");
exports.selectorStateDefaultValues = {
    currency: undefined,
    account: undefined,
    parentAccount: undefined,
    amount: undefined,
};
const useFromAmountStatusMessage = ({ account, parentAccount, status, transaction }, 
// The order of errors/warnings here will determine the precedence
statusTypeToInclude, sponsored) => {
    const statusEntries = (0, react_1.useMemo)(() => statusTypeToInclude.map(statusType => (status.errors || status.warnings)?.[statusType]), [status.errors, status.warnings, statusTypeToInclude]);
    const currency = (0, react_1.useMemo)(() => {
        if (parentAccount) {
            return (0, index_1.getAccountCurrency)(parentAccount);
        }
        if (account) {
            return (0, index_1.getAccountCurrency)(account);
        }
        return undefined;
    }, [account, parentAccount]);
    const estimatedFees = (0, react_1.useMemo)(() => {
        return status.estimatedFees;
    }, [status]);
    return (0, react_1.useMemo)(() => {
        // don't return an error/warning if we have no transaction or if transaction.amount <= 0
        if (transaction?.amount.lte(0))
            return undefined;
        const [relevantStatus] = statusEntries
            .filter(maybeError => maybeError instanceof Error)
            .filter(errorOrWarning => !(errorOrWarning instanceof errors_1.AmountRequired));
        const isRelevantStatus = relevantStatus instanceof errors_1.NotEnoughGas;
        // Skip gas validation for sponsored transactions since gas fees are covered by sponsor
        if (isRelevantStatus && currency && estimatedFees && !sponsored) {
            const query = new URLSearchParams({
                // get account id first and set it equal to account.
                // if parent account exists then overwrite the former.
                ...(account?.id ? { account: account.id } : {}),
                ...(parentAccount?.id ? { account: parentAccount.id } : {}),
            });
            return new errors_1.NotEnoughGasSwap(undefined, {
                fees: (0, index_2.formatCurrencyUnit)((0, index_1.getFeesUnit)(currency), estimatedFees),
                ticker: currency.ticker,
                cryptoName: currency.name,
                links: [`ledgerlive://buy?${query.toString()}`],
            });
        }
        // convert to swap variation of error to display correct message to frontend.
        if (relevantStatus instanceof errors_1.FeeNotLoaded) {
            return new errors_1.NotEnoughBalanceSwap();
        }
        return relevantStatus;
    }, [
        statusEntries,
        currency,
        estimatedFees,
        transaction?.amount,
        account?.id,
        parentAccount?.id,
        sponsored,
    ]);
};
exports.useFromAmountStatusMessage = useFromAmountStatusMessage;
const useSwapTransaction = ({ accounts, setExchangeRate, defaultCurrency = exports.selectorStateDefaultValues.currency, defaultAccount = exports.selectorStateDefaultValues.account, defaultParentAccount = exports.selectorStateDefaultValues.parentAccount, onNoRates, excludeFixedRates, refreshRate, allowRefresh, isEnabled, sponsored, }) => {
    const bridgeTransaction = (0, useBridgeTransaction_1.default)(() => ({
        account: defaultAccount,
        parentAccount: defaultParentAccount,
    }));
    const { fromState, setFromAccount, setFromAmount } = (0, useFromState_1.useFromState)({
        accounts,
        defaultCurrency,
        defaultAccount,
        defaultParentAccount,
        bridgeTransaction,
    });
    const { toState, setToAccount, setToAmount, setToCurrency, targetAccounts } = (0, useToState_1.useToState)({
        accounts,
        fromCurrencyAccount: fromState.account,
    });
    const { account: fromAccount, parentAccount: fromParentAccount, currency: fromCurrency, } = fromState;
    const { account: toAccount } = toState;
    const fromAmountError = (0, exports.useFromAmountStatusMessage)(bridgeTransaction, ["gasPrice", "amount", "gasLimit"], sponsored);
    const { isSwapReversable, reverseSwap } = (0, useReverseAccounts_1.useReverseAccounts)({
        accounts,
        fromAccount,
        toAccount,
        fromParentAccount,
        fromCurrency,
        setFromAccount,
        setToAccount,
    });
    const { isMaxEnabled, toggleMax, isMaxLoading } = (0, useUpdateMaxAmount_1.useUpdateMaxAmount)({
        setFromAmount,
        account: fromAccount,
        parentAccount: fromParentAccount,
        bridge: bridgeTransaction,
    });
    const { rates, refetchRates, updateSelectedRate, countdown } = (0, useProviderRates_1.useProviderRates)({
        fromState,
        toState,
        onNoRates,
        setExchangeRate,
        countdown: refreshRate,
        allowRefresh,
        isEnabled,
    });
    const [maxAmountLowerThanBallanceError, setMaxAmountLowerThanBallanceError] = (0, react_1.useState)(undefined);
    (0, react_1.useEffect)(() => {
        const timer = setTimeout(() => {
            // libs/coin-modules/coin-evm/src/prepareTransaction.ts L47
            // returns 0 if the balance - fees is less than 0
            const error = isMaxEnabled && !isMaxLoading && fromState.amount?.eq(0)
                ? new errors_1.NotEnoughBalanceSwap()
                : undefined;
            setMaxAmountLowerThanBallanceError(error);
        }, isMaxEnabled ? 500 : 0);
        // Cleanup the timeout if the component unmounts or the dependencies change
        return () => clearTimeout(timer);
    }, [isMaxEnabled, isMaxLoading, fromState]);
    return {
        ...bridgeTransaction,
        swap: {
            to: toState,
            from: fromState,
            isMaxEnabled,
            isMaxLoading,
            isSwapReversable,
            rates: rates.value && excludeFixedRates
                ? {
                    ...rates,
                    value: rates.value.filter(v => v.tradeMethod !== "fixed"),
                }
                : rates,
            countdown,
            refetchRates,
            updateSelectedRate,
            targetAccounts,
        },
        setFromAmount,
        toggleMax,
        fromAmountError: maxAmountLowerThanBallanceError || fromAmountError,
        setToAccount,
        setToCurrency,
        setFromAccount,
        setToAmount,
        reverseSwap,
    };
};
exports.useSwapTransaction = useSwapTransaction;
//# sourceMappingURL=useSwapTransaction.js.map