'use client'
import { __awaiter } from '../../../../_virtual/_tslib.js';
import { jsx } from 'react/jsx-runtime';
import { createContext, useRef, useState, useCallback, useMemo } from 'react';
import { ProviderEnum } from '@dynamic-labs/sdk-api-core';
import { DynamicError, DeferredPromise } from '@dynamic-labs/utils';
import { createProviderHook } from '../../shared/utils/functions/createProviderHook/createProviderHook.js';
import { onrampConfigurationToOnrampOption } from '../../utils/functions/onrampConfigurationToOnrampOption/onrampConfigurationToOnrampOption.js';
import { openOnrampPopup } from '../../utils/functions/openOnrampPopup.js';
import { rejectPromiseRef } from '../../utils/functions/rejectPromiseRef/rejectPromiseRef.js';
import { useWidgetContext } from '../../widgets/DynamicWidget/context/DynamicWidgetContext.js';
import '../DynamicContext/useDynamicContext/useDynamicContext.js';
import { useInternalDynamicContext } from '../DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';
import { useOnrampProviders } from './useOnrampProviders/useOnrampProviders.js';
import { getOnrampProviders } from './utils/getOnrampProviders.js';

const OnrampContext = createContext(undefined);
const OnrampContextProvider = ({ children, }) => {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const promiseRef = useRef(null);
    const [selectedOnrampProvider, setSelectedOnrampProvider] = useState();
    const [showOnramp, _setShowOnramp] = useState(false);
    const [override, setOverride] = useState(false);
    const [overrideOnrampProvider, setOverrideOnrampProvider] = useState(undefined);
    const { environmentId, network, primaryWallet, projectSettings, overrides } = useInternalDynamicContext();
    const { setDynamicWidgetView } = useWidgetContext();
    const [enabledOnrampProvidersTarget, setEnabledOnrampProvidersTarget] = useState({});
    // Manual trigger for programmatic flows (openOnramp, setEnabledOnrampProvidersTargetValue)
    const [manualFetchTriggered, setManualFetchTriggered] = useState(false);
    // Auto-fetch when onramps are configured in the dashboard so the Buy button
    // is available in the funding-methods view. When unconfigured, skip the fetch
    // to avoid wasting bandwidth on SDK mount (esp. on slow mobile connections).
    const hasOnrampsConfigured = Boolean((_c = (_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _a === void 0 ? void 0 : _a.funding) === null || _b === void 0 ? void 0 : _b.onramps) === null || _c === void 0 ? void 0 : _c.length);
    const shouldFetchOnramps = manualFetchTriggered || hasOnrampsConfigured;
    const setShowOnramp = useCallback((value) => {
        _setShowOnramp(value);
        if (!value && promiseRef.current) {
            rejectPromiseRef(promiseRef, new DynamicError('User cancelled', 'user_cancelled'));
        }
    }, []);
    const setEnabledOnrampProvidersTargetValue = useCallback(({ address, token, network, tokenAmount, chainName, currency, }) => {
        setEnabledOnrampProvidersTarget({
            address,
            chainName,
            currency,
            network,
            token,
            tokenAmount,
        });
        // Trigger fetch when target is set with specific parameters
        if (address || token || network || tokenAmount || chainName || currency) {
            setManualFetchTriggered(true);
        }
    }, []);
    const resetOverrides = useCallback(() => {
        setOverrideOnrampProvider(undefined);
        setOverride(false);
    }, []);
    const { enabledOnRamps: enabledOnrampProvidersInDashboard } = useOnrampProviders({
        environmentId,
        includeDisabled: true,
        network,
        primaryWallet,
        projectSettingsOnramps: (_e = (_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _d === void 0 ? void 0 : _d.funding) === null || _e === void 0 ? void 0 : _e.onramps,
        shouldFetch: shouldFetchOnramps,
        target: enabledOnrampProvidersTarget,
    });
    const enabledOnrampProvidersInDashboardOptions = useMemo(() => {
        const options = enabledOnrampProvidersInDashboard.map((provider) => {
            const option = onrampConfigurationToOnrampOption(provider);
            // Route Crypto.com selection to a custom UI instead of immediate popup/link
            if (option.id === ProviderEnum.CryptoDotCom) {
                option.onClick = () => setDynamicWidgetView('crypto-com-onramp');
            }
            // Route MoonPay to token selector before opening the signed widget URL
            if (option.id === ProviderEnum.MoonPay) {
                option.onClick = () => setDynamicWidgetView('moonpay-onramp');
            }
            return option;
        });
        return options;
    }, [enabledOnrampProvidersInDashboard, setDynamicWidgetView]);
    const onrampOverrides = useMemo(() => {
        const configuredOverrides = overrides === null || overrides === void 0 ? void 0 : overrides.onrampOptions;
        if (typeof configuredOverrides === 'function') {
            return configuredOverrides(enabledOnrampProvidersInDashboardOptions);
        }
        return configuredOverrides || [];
    }, [overrides === null || overrides === void 0 ? void 0 : overrides.onrampOptions, enabledOnrampProvidersInDashboardOptions]);
    const onrampEnabled = useMemo(() => {
        var _a, _b, _c;
        // If onrampOptions is explicitly defined and results in an empty array, disable onramp
        if ((overrides === null || overrides === void 0 ? void 0 : overrides.onrampOptions) !== undefined &&
            onrampOverrides.length === 0) {
            return false;
        }
        // If we have overrides with items, enable onramp
        if (onrampOverrides.length > 0) {
            return true;
        }
        // Otherwise use the original logic for dashboard providers
        return Boolean(((_c = (_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _a === void 0 ? void 0 : _a.funding) === null || _b === void 0 ? void 0 : _b.onramps) === null || _c === void 0 ? void 0 : _c.length) &&
            enabledOnrampProvidersInDashboard.length);
    }, [
        (_h = (_g = (_f = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _f === void 0 ? void 0 : _f.funding) === null || _g === void 0 ? void 0 : _g.onramps) === null || _h === void 0 ? void 0 : _h.length,
        enabledOnrampProvidersInDashboard.length,
        onrampOverrides.length,
        overrides === null || overrides === void 0 ? void 0 : overrides.onrampOptions,
    ]);
    const hasPrimaryWallet = useMemo(() => Boolean(primaryWallet), [primaryWallet]);
    const setSelectedAndShowOnramp = useCallback(({ provider, wallet, payingWithDynamic, }) => {
        var _a;
        if (hasPrimaryWallet || payingWithDynamic) {
            setSelectedOnrampProvider(provider.id);
        }
        setShowOnramp(true);
        const shouldOpenPopup = provider.openMode === 'popup' && provider.url && setShowOnramp;
        if (!shouldOpenPopup) {
            return;
        }
        return openOnrampPopup((_a = provider.url) !== null && _a !== void 0 ? _a : '', wallet, setShowOnramp, provider.id);
    }, [hasPrimaryWallet, setShowOnramp]);
    const enabledOnrampProviders = useMemo(() => {
        // If we have explicit overrides (even empty array), use them
        if ((overrides === null || overrides === void 0 ? void 0 : overrides.onrampOptions) !== undefined) {
            return onrampOverrides;
        }
        // Otherwise fall back to dashboard options
        return enabledOnrampProvidersInDashboardOptions;
    }, [
        enabledOnrampProvidersInDashboardOptions,
        onrampOverrides,
        overrides === null || overrides === void 0 ? void 0 : overrides.onrampOptions,
    ]);
    const openOnramp = useCallback((_j) => __awaiter(void 0, [_j], void 0, function* ({ onrampProvider, address, token, tokenAmount, network: networkOverride, chainName, currency, overrideOnRamp, payingWithDynamic, merchantName, }) {
        var _k, _l, _m, _o;
        if (!onrampEnabled && !overrideOnRamp && !payingWithDynamic) {
            throw new Error('Onramp is not enabled');
        }
        setOverride(false);
        if (promiseRef.current) {
            return promiseRef.current.promise;
        }
        promiseRef.current = new DeferredPromise();
        // Trigger onramp providers fetch if not already done
        if (!manualFetchTriggered) {
            setManualFetchTriggered(true);
        }
        let localOnrampProviders = enabledOnrampProvidersInDashboardOptions;
        const networkToUse = networkOverride || network;
        const shouldOverrideOnrampProviders = overrideOnRamp ||
            Boolean(address) ||
            Boolean(token) ||
            Boolean(networkOverride) ||
            Boolean(tokenAmount) ||
            Boolean(chainName) ||
            Boolean(currency) ||
            Boolean(merchantName);
        const allPayingParameters = Boolean(chainName) &&
            Boolean(networkToUse) &&
            Boolean(token) &&
            Boolean(tokenAmount) &&
            Boolean(address);
        if (payingWithDynamic && !allPayingParameters) {
            rejectPromiseRef(promiseRef, new Error('PayingWithDynamic: Missing parameters'));
            return (_k = promiseRef.current) === null || _k === void 0 ? void 0 : _k.promise;
        }
        if (shouldOverrideOnrampProviders)
            setOverride(true);
        if (shouldOverrideOnrampProviders ||
            (payingWithDynamic && allPayingParameters)) {
            localOnrampProviders = (yield getOnrampProviders({
                address,
                chainName,
                currency,
                environmentId,
                includeDisabled: overrideOnRamp,
                merchantName,
                network: networkToUse,
                primaryWallet,
                token,
                tokenAmount,
            })).map((provider) => onrampConfigurationToOnrampOption(provider));
        }
        const onrampOption = localOnrampProviders.find((p) => p.id === onrampProvider);
        if (payingWithDynamic && !onrampOption) {
            rejectPromiseRef(promiseRef, new Error('PayingWithDynamic: Onramp provider not found'));
            return (_l = promiseRef.current) === null || _l === void 0 ? void 0 : _l.promise;
        }
        if (!onrampOption) {
            rejectPromiseRef(promiseRef, new Error('Onramp provider not found'));
            return (_m = promiseRef.current) === null || _m === void 0 ? void 0 : _m.promise;
        }
        setOverrideOnrampProvider(onrampOption);
        setSelectedAndShowOnramp({ payingWithDynamic, provider: onrampOption });
        return (_o = promiseRef.current) === null || _o === void 0 ? void 0 : _o.promise;
    }), [
        enabledOnrampProvidersInDashboardOptions,
        environmentId,
        onrampEnabled,
        primaryWallet,
        network,
        setSelectedAndShowOnramp,
        manualFetchTriggered,
    ]);
    const selectedOnramp = useMemo(() => {
        let selected;
        if (override) {
            selected = overrideOnrampProvider;
        }
        else if (enabledOnrampProviders.length) {
            selected = enabledOnrampProviders.find((p) => p.id === selectedOnrampProvider);
        }
        return selected;
    }, [
        overrideOnrampProvider,
        enabledOnrampProviders,
        override,
        selectedOnrampProvider,
    ]);
    const selectOnrampProvider = useCallback(({ provider, wallet }) => {
        if (provider.onClick) {
            provider.onClick({ wallet });
            return;
        }
        resetOverrides();
        setSelectedAndShowOnramp({ provider, wallet });
    }, [setSelectedAndShowOnramp, resetOverrides]);
    const value = useMemo(() => ({
        enabledOnrampProviders,
        onrampEnabled,
        openOnramp,
        selectOnrampProvider,
        selectedOnramp,
        setEnabledOnrampProvidersTargetValue,
        setShowOnramp,
        showOnramp,
    }), [
        enabledOnrampProviders,
        onrampEnabled,
        openOnramp,
        selectedOnramp,
        setEnabledOnrampProvidersTargetValue,
        showOnramp,
        setShowOnramp,
        selectOnrampProvider,
    ]);
    return (jsx(OnrampContext.Provider, { value: value, children: children }));
};
const useOnrampContext = createProviderHook(OnrampContext, 'OnrampContextProvider');

export { OnrampContext, OnrampContextProvider, useOnrampContext };
