import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useNavigation, useRoute } from '@react-navigation/native';
import { useTranslation } from 'react-i18next';

import {
  CustomKeyboardAvoidingView,
  ThemeText,
} from '../../../../functions/CustomElements';
import CustomButton from '../../../../functions/CustomElements/button';
import CustomSettingsTopBar from '../../../../functions/CustomElements/settingsTopBar';
import FormattedBalanceInput from '../../../../functions/CustomElements/formattedBalanceInput';
import CustomNumberKeyboard from '../../../../functions/CustomElements/customNumberKeyboard';
import CustomSearchInput from '../../../../functions/CustomElements/searchInput';
import ChoosePaymentMethod from './components/choosePaymentMethodContainer';
import SwipeButtonNew from '../../../../functions/CustomElements/sliderButton';

import GetThemeColors from '../../../../hooks/themeColors';
import {
  APPROXIMATE_SYMBOL,
  CENTER,
  COLORS,
  CONTENT_KEYBOARD_OFFSET,
  SIZES,
  USDB_TOKEN_ID,
} from '../../../../constants';
import {
  HIDDEN_OPACITY,
  INSET_WINDOW_WIDTH,
  WINDOWWIDTH,
} from '../../../../constants/theme';
import { useGlobalThemeContext } from '../../../../../context-store/theme';
import { useGlobalInsets } from '../../../../../context-store/insetsProvider';
import { useNodeContext } from '../../../../../context-store/nodeContext';
import { useKeysContext } from '../../../../../context-store/keys';
import { useActiveCustodyAccount } from '../../../../../context-store/activeAccount';
import { useSparkWallet } from '../../../../../context-store/sparkContext';
import { useUserBalanceContext } from '../../../../../context-store/userBalanceContext';
import { useFlashnet } from '../../../../../context-store/flashnetContext';
import { useGlobalContextProvider } from '../../../../../context-store/context';

import fetchBackend from '../../../../../db/handleBackend';
import { sendSparkPayment, sendSparkTokens } from '../../../../functions/spark';
import { bulkUpdateSparkTransactions } from '../../../../functions/spark/transactions';
import {
  calculateFlashnetAmountIn,
  dollarsToSats,
} from '../../../../functions/spark/flashnet';
import EmojiQuickBar from '../../../../functions/CustomElements/emojiBar';
import useCurrencyDisplay from '../../../../hooks/useCurrencyDisplay';
import useDisplayCurrencyController from '../../../../hooks/useDisplayCurrencyController';
import SendTransactionFeeInfo from './components/feeInfo';
import { formatStablecoinAmount } from '../../../../functions/sendBitcoin';
import { SliderProgressAnimation } from '../../../../functions/CustomElements/sendPaymentAnimation';
import { formatBalanceAmount } from '../../../../functions';
import { useBudgetWarning } from '../../../../hooks/useBudgetWarning';
import {
  getDefaultDisplayCurrency,
  resolveUsdFiatStats,
} from '../../../../functions/displayCurrency';
import CurrencySwitchButton from '../../../../functions/CustomElements/currencySwitchButton';

const QUOTE_TTL_MS = 115_000;

function truncateAddress(addr) {
  if (!addr || addr.length <= 16) return addr || '';
  return `${addr.slice(0, 8)}...${addr.slice(-6)}`;
}

function formatCountdown(ms) {
  const secs = Math.max(0, Math.floor(ms / 1000));
  const m = Math.floor(secs / 60);
  const s = secs % 60;
  return `${m}:${s.toString().padStart(2, '0')}`;
}

function capitalizeChain(chain) {
  if (typeof chain !== 'string') return '';
  const lowered = chain.toLowerCase();
  const firstLetter = lowered[0].toUpperCase();
  return firstLetter + lowered.slice(1);
}

export default function StablecoinSendScreen() {
  const navigate = useNavigation();
  const route = useRoute();
  const {
    address,
    chain,
    chainLabel,
    asset,
    selectedPaymentMethod,
    prefillAmount,
  } = route.params;
  const { t } = useTranslation();

  const { theme, darkModeType } = useGlobalThemeContext();
  const { backgroundOffset, backgroundColor } = GetThemeColors();
  const { bottomPadding } = useGlobalInsets();
  const didWarnAboutBudget = useRef(null);
  const { fiatStats } = useNodeContext();
  const { masterInfoObject } = useGlobalContextProvider();
  const { contactsPrivateKey, publicKey } = useKeysContext();
  const { currentWalletMnemoinc } = useActiveCustodyAccount();
  const { sparkInformation } = useSparkWallet();
  const { bitcoinBalance, dollarBalanceToken, dollarBalanceSat } =
    useUserBalanceContext();
  const { swapUSDPriceDollars, poolInfoRef } = useFlashnet();

  const [screenMode, setScreenMode] = useState('EDIT_AMOUNT'); // 'EDIT_AMOUNT' | 'CONFIRM_PAYMENT'
  const [rawInput, setRawInput] = useState(
    prefillAmount != null ? String(prefillAmount) : '',
  );
  console.log(rawInput);
  const [description, setDescription] = useState('');

  const [quote, setQuote] = useState(null);
  const [quoteLoading, setQuoteLoading] = useState(false);
  const [quoteError, setQuoteError] = useState(null);
  const [countdown, setCountdown] = useState(null);
  const [sending, setSending] = useState(false);
  const [isAmountFocused, setIsAmountFocused] = useState(true);
  const [retriggerQuoteFetch, setRetriggerQuoteFetch] = useState(0);

  const debounceRef = useRef(null);
  const countdownRef = useRef(null);
  const quoteExpiresAt = useRef(null);
  const isSendingPayment = useRef(null);
  const progressAnimationRef = useRef(null);
  const fetchTokenRef = useRef(0);
  const balanceRef = useRef({
    bitcoin: bitcoinBalance,
    dollarToken: dollarBalanceToken,
  });
  balanceRef.current.bitcoin = bitcoinBalance;
  balanceRef.current.dollarToken = dollarBalanceToken;

  const sourceMethod = selectedPaymentMethod || 'BTC';
  const usdFiatStats = useMemo(
    () => resolveUsdFiatStats(fiatStats, swapUSDPriceDollars),
    [fiatStats, swapUSDPriceDollars],
  );
  const initialDisplayCurrency = useMemo(
    () =>
      sourceMethod === 'USD'
        ? 'USD'
        : getDefaultDisplayCurrency({
            paymentMode: sourceMethod,
            masterInfoObject,
            fiatStats,
          }),
    [sourceMethod, masterInfoObject, fiatStats],
  );

  const { displayCurrency, currencyRates, isLoadingRate, selectCurrency } =
    useDisplayCurrencyController({
      initialCurrency: initialDisplayCurrency,
      fiatStats,
      usdFiatStats,
      masterInfoObject,
    });

  useEffect(() => {
    isSendingPayment.current = sending;
  }, [sending]);

  const {
    primaryDisplay,
    conversionFiatStats,
    convertSatsToDisplay,
    convertDisplayToSats,
  } = useCurrencyDisplay({
    displayCurrency: sourceMethod === 'USD' ? 'USD' : displayCurrency,
    fiatStats,
    usdFiatStats,
    currencyRates,
    masterInfoObject,
    isSendingPayment: isSendingPayment.current,
  });

  // Kept current so the success-page handoff reads the live display config
  // rather than a stale value captured in the handleSend useCallback closure.
  const primaryDisplayRef = useRef(primaryDisplay);
  useEffect(() => {
    primaryDisplayRef.current = primaryDisplay;
  }, [primaryDisplay]);

  const convertedSendAmount = convertDisplayToSats(rawInput);

  const { shouldWarn } = useBudgetWarning(convertedSendAmount);

  const clearCountdown = useCallback(() => {
    if (countdownRef.current) clearInterval(countdownRef.current);
    countdownRef.current = null;
    setCountdown(null);
  }, []);

  const startCountdown = useCallback(
    expiresAt => {
      clearCountdown();
      quoteExpiresAt.current = expiresAt;
      countdownRef.current = setInterval(() => {
        const remaining = quoteExpiresAt.current - Date.now();
        if (remaining <= 0) {
          clearInterval(countdownRef.current);
          countdownRef.current = null;
          setCountdown(null);
          setQuote(null);
          setRetriggerQuoteFetch(prev => prev + 1);
        } else {
          setCountdown(remaining);
        }
      }, 1000);
    },
    [clearCountdown, t],
  );

  const fetchQuote = useCallback(
    async (sats, myToken) => {
      if (sats <= 0 || !contactsPrivateKey || !publicKey) return;
      setQuoteError(null);
      setQuote(null);
      clearCountdown();
      try {
        const apiSourceMethod = sourceMethod === 'BTC' ? 'spark' : 'usdb';
        // Adding flag for backend to not manipulate the amount so we don't cause balance issues + failures
        const maxBalance =
          sourceMethod === 'BTC'
            ? balanceRef.current.bitcoin
            : balanceRef.current.dollarToken * Math.pow(10, 6);
        const isUsingMax = maxBalance > 0 && sats >= maxBalance * 0.98;

        // ── stale-response guard ──────────────────────────────────────────────
        if (myToken !== fetchTokenRef.current) return;
        const result = await fetchBackend(
          'createFlashnetStablecoinQuoteV2',
          {
            recipientAddress: address,
            destinationChain: chain,
            destinationAsset: asset,
            amountSats: sats,
            sourceMethod: apiSourceMethod,
            refundAddress: sparkInformation.sparkAddress,
            isUsingMax,
          },
          contactsPrivateKey,
          publicKey,
        );

        // ── stale-response guard ──────────────────────────────────────────────
        if (myToken !== fetchTokenRef.current) return;

        if (!result || result.error) {
          const { code, message, minimumSats } = result.error;

          if (code === 'amount_too_small') {
            if (minimumSats) {
              throw new Error(
                t('flashnetUSDCUSDTMessages.amount_too_small_minimum', {
                  minimumSats,
                }),
              );
            }
            throw new Error(
              t('flashnetUSDCUSDTMessages.amount_too_small_chain_fees'),
            );
          }

          throw new Error(t(`flashnetUSDCUSDTMessages.${code}`));
        }

        const expiresAt = result.expiresAt || Date.now() + QUOTE_TTL_MS;
        const formattedFee =
          sourceMethod === 'BTC'
            ? result.fee
            : dollarsToSats(
                result?.fee / Math.pow(10, 6),
                poolInfoRef.currentPriceAInB,
              );
        setQuote({ ...result, fee: formattedFee, expiresAt });
        startCountdown(expiresAt);
      } catch (err) {
        // Only surface the error if this is still the active request
        if (myToken !== fetchTokenRef.current) return;
        setQuoteError(err.message || t('wallet.stablecoinSend.quoteError'));
      } finally {
        // Only clear loading if this is still the active request
        if (myToken === fetchTokenRef.current) {
          setQuoteLoading(false);
        }
      }
    },
    [
      address,
      chain,
      asset,
      sourceMethod,
      contactsPrivateKey,
      publicKey,
      clearCountdown,
      startCountdown,
      t,
    ],
  );

  useEffect(() => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    if (rawInput > 0) {
      const exceedsBalance =
        sourceMethod === 'BTC'
          ? convertedSendAmount > balanceRef.current.bitcoin
          : Number(rawInput) > Number(balanceRef.current.dollarToken);

      // Stop quote fetch if we do not have an available balance
      if (exceedsBalance) {
        fetchTokenRef.current += 1;
        setQuoteLoading(false);
        setQuote(null);
        setQuoteError(null);
        clearCountdown();
        return;
      }

      setQuoteLoading(true);
      // Invalidate any in-flight response right now, before the debounce fires.
      fetchTokenRef.current += 1;

      //  Find max balance without going over actual user balance
      const amountIn = calculateFlashnetAmountIn({
        baseAmountIn:
          sourceMethod === 'BTC'
            ? convertDisplayToSats(rawInput)
            : rawInput * Math.pow(10, 6),
        isUsdAssetIn: sourceMethod === 'USD',
        dollarBalanceSat,
        maxBalance: bitcoinBalance,
        currentPriceAInB: poolInfoRef.currentPriceAInB,
        bufferMultiplier: 1,
      });

      debounceRef.current = setTimeout(
        () => fetchQuote(amountIn, fetchTokenRef.current),
        800,
      );
    } else {
      fetchTokenRef.current += 1;
      setQuoteLoading(false);
      setQuote(null);
      setQuoteError(null);
      clearCountdown();
    }
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, [rawInput, sourceMethod, fetchQuote, clearCountdown, retriggerQuoteFetch]);

  useEffect(() => {
    return () => {
      clearCountdown();
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, [clearCountdown]);

  // Handle back press from CONFIRM_PAYMENT — return to EDIT_AMOUNT
  useEffect(() => {
    const unsubscribe = navigate.addListener('beforeRemove', e => {
      if (screenMode !== 'CONFIRM_PAYMENT') return;
      if (isSendingPayment.current) return;
      e.preventDefault();
      setScreenMode('EDIT_AMOUNT');
    });
    return unsubscribe;
  }, [navigate, screenMode]);

  const openPicker = () => {
    if (!isAmountFocused) return;
    if (isConfirmMode || sourceMethod === 'USD') return;

    navigate.navigate('CustomHalfModal', {
      wantedContent: 'displayCurrencySelect',
      sliderHight: 0.6,
      currentCurrency: displayCurrency,
      onSelectCurrency: async code => {
        const response = await selectCurrency(code);
        if (response?.didWork) setRawInput('');
      },
    });
  };

  const handleMethodToggle = () => {
    navigate.navigate('CustomHalfModal', {
      wantedContent: 'SelectPaymentMethod',
      selectedPaymentMethod: sourceMethod,
      fromPage: 'StablecoinSendScreen',
    });
  };

  const handleSend = useCallback(async () => {
    if (!quote || sending) return;
    if (Date.now() >= quote.expiresAt) {
      setQuoteError(t('wallet.stablecoinSend.quoteExpired'));
      setQuote(null);
      clearCountdown();
      setScreenMode('EDIT_AMOUNT');
      return;
    }

    setSending(true);
    clearCountdown();

    try {
      let result;
      if (sourceMethod === 'BTC') {
        result = await sendSparkPayment({
          receiverSparkAddress: quote.depositAddress,
          amountSats: Number(quote.amountIn),
          mnemonic: currentWalletMnemoinc,
        });
      } else {
        // USDb: quote.amountIn is in token micro-units (e.g. 1_000_000 = $1)
        result = await sendSparkTokens({
          tokenIdentifier: USDB_TOKEN_ID,
          tokenAmount: Number(quote.amountIn),
          receiverSparkAddress: quote.depositAddress,
          mnemonic: currentWalletMnemoinc,
        });
      }

      if (!result.didWork) throw new Error(result.error);

      const sparkTransferId =
        sourceMethod === 'USD' ? result.response : result.response?.id;

      const pendingTx = {
        id: sparkTransferId,
        paymentStatus: 'pending',
        paymentType: 'spark',
        accountId: sparkInformation.identityPubKey,
        details: {
          amount: quote.amountIn,
          fee: quote?.fee,
          totalFee: 0,
          supportFee: 0,
          description: description || '',
          address: quote.depositAddress,
          sourceSparkAddress: sparkInformation.sparkAddress,
          time: Date.now(),
          createdAt: Date.now(),
          direction: 'OUTGOING',
          isFlashnetStablecoin: true,
          quoteId: quote.quoteId,
          destinationAddress: address,
          destinationChain: chain,
          destinationAsset: asset,
          sourceMethod,
          isLRC20Payment: sourceMethod === 'USD',
          ...(sourceMethod === 'USD' ? { LRC20Token: USDB_TOKEN_ID } : {}),
        },
      };

      await bulkUpdateSparkTransactions([pendingTx], 'fullUpdate');

      fetchBackend(
        'submitFlashnetStablecoinOrder',
        {
          quoteId: quote.quoteId,
          sparkTxHash: sparkTransferId,
          sourceSparkAddress: sparkInformation.sparkAddress,
        },
        contactsPrivateKey,
        publicKey,
      );

      if (progressAnimationRef.current) {
        progressAnimationRef.current.completeProgress();
        await new Promise(res => setTimeout(res, 600));
      }

      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          navigate.reset({
            index: 0,
            routes: [
              {
                name: 'HomeAdmin',
                params: {
                  screen: 'Home',
                },
              },
              {
                name: 'ConfirmTxPage',
                params: {
                  transaction: pendingTx,
                  paymentDisplay: primaryDisplayRef.current,
                  displayAmount: rawInput,
                },
              },
            ],
          });
        });
      });
    } catch (err) {
      console.log(err, 'error navigating to bla bla bla');
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          navigate.reset({
            index: 0,
            routes: [
              {
                name: 'HomeAdmin',
                params: {
                  screen: 'Home',
                },
              },
              {
                name: 'ConfirmTxPage',
                params: {
                  transaction: {},
                  error: err.message,
                  lnurlAddress: undefined,
                  blitzContactInfo: undefined,
                },
              },
            ],
          });
        });
      });
    }
  }, [
    quote,
    sending,
    sourceMethod,
    navigate,
    currentWalletMnemoinc,
    sparkInformation,
    description,
    address,
    chain,
    asset,
    contactsPrivateKey,
    publicKey,
    clearCountdown,
    t,
    rawInput,
  ]);

  const handleEmoji = newDescription => {
    setDescription(newDescription);
  };

  const isQuoteLoading =
    (quoteLoading || (quote && countdown === null)) && !sending;

  const hasEnoughBalance =
    sourceMethod === 'BTC'
      ? convertedSendAmount <= Number(bitcoinBalance)
      : Number(rawInput) <= Number(dollarBalanceToken);

  const canConfirm =
    !!quote &&
    !isQuoteLoading &&
    !sending &&
    convertedSendAmount > 0 &&
    hasEnoughBalance;

  const canReview =
    (convertedSendAmount > 0 && hasEnoughBalance && !sending && quote) ||
    quoteLoading;

  const handleReview = useCallback(() => {
    if (!convertedSendAmount || convertedSendAmount <= 0) {
      navigate.navigate('ErrorScreen', {
        errorMessage: t('wallet.stablecoinSend.noAmount'),
      });
      return;
    }

    if (!hasEnoughBalance) {
      navigate.navigate('ErrorScreen', {
        errorMessage: t('screens.inAccount.swapsPage.insufficientBalance'),
      });
      return;
    }

    if (isQuoteLoading) {
      navigate.navigate('ErrorScreen', {
        errorMessage: t('wallet.stablecoinSend.quoteStillLoading'),
      });
      return;
    }

    if (quoteError) {
      navigate.navigate('ErrorScreen', { errorMessage: quoteError });
      return;
    }

    if (!quote) {
      navigate.navigate('ErrorScreen', {
        errorMessage: t('wallet.stablecoinSend.noQuote'),
      });
      return;
    }

    if (Date.now() >= quote.expiresAt) {
      setQuoteError(t('wallet.stablecoinSend.quoteExpired'));
      setQuote(null);
      clearCountdown();
      return;
    }
    setIsAmountFocused(true);
    setScreenMode('CONFIRM_PAYMENT');
  }, [
    canConfirm,
    quote,
    quoteError,
    clearCountdown,
    t,
    convertedSendAmount,
    isQuoteLoading,
    sourceMethod,
    rawInput,
    bitcoinBalance,
    dollarBalanceToken,
    navigate,
    hasEnoughBalance,
  ]);

  const rowBg = backgroundOffset;

  const memorizedKeyboardStyle = useMemo(() => {
    return {
      paddingBottom: !isAmountFocused ? 0 : bottomPadding,
    };
  }, [isAmountFocused]);

  const isConfirmMode = screenMode === 'CONFIRM_PAYMENT';

  const receiveAmountContent = `${APPROXIMATE_SYMBOL}${formatBalanceAmount(
    formatStablecoinAmount(
      quote?.estimatedOut || 0,
      2,
      chain === 'bsc' ? 18 : 6,
    ),
    false,
    masterInfoObject,
  )} ${asset}`;

  useEffect(() => {
    if (
      isConfirmMode &&
      shouldWarn &&
      !didWarnAboutBudget.current &&
      !isSendingPayment.current
    ) {
      didWarnAboutBudget.current = true;
      navigate.navigate('CustomHalfModal', {
        wantedContent: 'nearBudgetLimitWarning',
        sliderHight: 0.6,

        sendingAmount: convertedSendAmount,
      });
    }
  }, [isConfirmMode, shouldWarn, convertedSendAmount]);

  return (
    <CustomKeyboardAvoidingView globalThemeViewStyles={memorizedKeyboardStyle}>
      <View style={styles.replacementContainer}>
        <CustomSettingsTopBar
          label={`${t('constants.send')}`}
          containerStyles={{ marginBottom: 0 }}
          rightContent={
            isConfirmMode ? (
              countdown != null ? (
                <ThemeText
                  styles={[
                    styles.countdownText,
                    { backgroundColor: backgroundOffset },
                    countdown < 30000 && {
                      color:
                        theme && darkModeType
                          ? COLORS.darkModeText
                          : COLORS.cancelRed,
                    },
                  ]}
                  content={formatCountdown(countdown)}
                />
              ) : null
            ) : (
              <CurrencySwitchButton
                displayCurrency={
                  sourceMethod === 'USD' ? 'USD' : displayCurrency
                }
                onPress={openPicker}
                disabled={isLoadingRate || sourceMethod === 'USD'}
              />
            )
          }
        />
        <ThemeText
          styles={styles.sectionTitle}
          content={`${t('wallet.stablecoinSend.networkLabel', {
            currency: asset,
            chain: chainLabel || capitalizeChain(chain),
          })}`}
        />

        <ScrollView
          showsVerticalScrollIndicator={false}
          contentContainerStyle={styles.scrollContent}
          keyboardShouldPersistTaps="handled"
        >
          <View style={CENTER}>
            <FormattedBalanceInput
              maxWidth={0.9}
              amountValue={rawInput}
              inputDenomination={primaryDisplay.denomination}
              forceCurrency={primaryDisplay.forceCurrency}
              forceFiatStats={primaryDisplay.forceFiatStats}
              activeOpacity={!convertedSendAmount ? 0.5 : 1}
            />
            <ThemeText
              styles={styles.receiveAmount}
              content={receiveAmountContent}
            />
          </View>

          {/* Confirm mode: fee info */}
          {isConfirmMode && (
            <SendTransactionFeeInfo
              paymentFee={quote?.fee}
              isLightningPayment={true}
              isDecoding={isQuoteLoading}
            />
          )}

          {/* Confirm mode: destination info */}
          {isConfirmMode && (
            <TouchableOpacity
              onPress={() =>
                navigate.navigate('ErrorScreen', {
                  errorMessage: address,
                })
              }
              style={[styles.destinationBox, { backgroundColor: rowBg }]}
            >
              <ThemeText
                styles={styles.quoteValue}
                content={`${truncateAddress(address)}`}
              />
            </TouchableOpacity>
          )}
        </ScrollView>

        {/* Source method picker: shown in edit mode only */}
        {!isConfirmMode && (
          <ChoosePaymentMethod
            theme={theme}
            darkModeType={darkModeType}
            determinePaymentMethod={sourceMethod}
            handleSelectPaymentMethod={handleMethodToggle}
            bitcoinBalance={bitcoinBalance}
            dollarBalanceToken={dollarBalanceToken}
            masterInfoObject={masterInfoObject}
            fiatStats={fiatStats}
            uiState="EDIT_AMOUNT"
            t={t}
            containerStyles={{ marginTop: 5 }}
            showPayWith={true}
          />
        )}

        {/* Description input: edit mode only */}
        {!isConfirmMode && (
          <CustomSearchInput
            onFocusFunction={() => setIsAmountFocused(false)}
            onBlurFunction={() => setIsAmountFocused(true)}
            placeholderText={t('constants.paymentDescriptionPlaceholder')}
            setInputText={setDescription}
            inputText={description}
            textInputMultiline={true}
            textAlignVertical="baseline"
            maxLength={150}
            containerStyles={{
              width: INSET_WINDOW_WIDTH,
              marginTop: 10,
              ...CENTER,
            }}
          />
        )}

        {/* EDIT_AMOUNT: keyboard + Review button */}
        {!isConfirmMode && isAmountFocused && (
          <CustomNumberKeyboard
            setInputValue={setRawInput}
            showDot={primaryDisplay.denomination === 'fiat'}
            fiatStats={conversionFiatStats}
            usingForBalance={true}
          />
        )}

        {!isConfirmMode && isAmountFocused && (
          <CustomButton
            textContent={t('constants.review')}
            actionFunction={handleReview}
            buttonStyles={{
              ...CENTER,
              opacity: canReview ? 1 : HIDDEN_OPACITY,
            }}
            useLoading={isQuoteLoading}
          />
        )}

        {/* CONFIRM_PAYMENT: swipe button */}
        {isConfirmMode && (
          <View style={styles.buttonContainer}>
            {sending ? (
              <SliderProgressAnimation
                ref={progressAnimationRef}
                isVisible={true}
                textColor={COLORS.darkModeText}
                backgroundColor={
                  theme && darkModeType ? backgroundOffset : COLORS.primary
                }
                width={0.95}
              />
            ) : (
              <SwipeButtonNew
                onSwipeSuccess={handleSend}
                width={0.85}
                resetAfterSuccessAnimDuration={true}
                shouldResetAfterSuccess={!sending}
                containerStyles={{
                  opacity: canConfirm ? 1 : HIDDEN_OPACITY,
                }}
                thumbIconStyles={{
                  backgroundColor:
                    theme && darkModeType ? backgroundOffset : backgroundColor,
                  borderColor:
                    theme && darkModeType ? backgroundOffset : backgroundColor,
                }}
                railStyles={{
                  backgroundColor:
                    theme && darkModeType ? backgroundOffset : backgroundColor,
                  borderColor:
                    theme && darkModeType ? backgroundOffset : backgroundColor,
                }}
              />
            )}
          </View>
        )}
      </View>

      {/* Emoji bar for description input */}
      {!isAmountFocused && !isConfirmMode && (
        <EmojiQuickBar description={description} onEmojiSelect={handleEmoji} />
      )}
    </CustomKeyboardAvoidingView>
  );
}

const styles = StyleSheet.create({
  globalContainer: {
    flex: 1,
  },
  sectionTitle: {
    fontSize: SIZES.medium,
    opacity: HIDDEN_OPACITY,
    textAlign: 'center',
    marginBottom: CONTENT_KEYBOARD_OFFSET,
    // textTransform: 'capitalize',
  },
  replacementContainer: {
    flexGrow: 1,
    width: WINDOWWIDTH,
    ...CENTER,
  },
  scrollContent: {
    flexGrow: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 10,
  },
  satValue: {
    fontSize: SIZES.medium,
    marginTop: 4,
  },
  destinationBox: {
    width: '80%',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 8,
    borderRadius: 8,
    ...CENTER,
    marginTop: 30,
  },
  receiveAmount: {
    opacity: HIDDEN_OPACITY,
    ...CENTER,
  },
  countdownText: {
    fontSize: SIZES.medium,
    includeFontPadding: false,
    paddingVertical: 5,
    paddingHorizontal: 15,
    borderRadius: 20,
  },
  quoteValue: {
    fontSize: SIZES.medium,
    includeFontPadding: false,
  },
  buttonContainer: {
    width: '100%',
    alignItems: 'center',
    paddingVertical: 10,
  },
});
