import React, { createContext, useContext, useEffect, useState } from "react";
import { toast, ToastProvider } from "./ui";
import WalletSDK from "../index";
import { getAuth } from "firebase/auth";
import firebase, { auth } from "../config/firebase";
import {
  getAllTokens,
  TokenInfo,
  getMultiRelaySwapQuote,
  getMultiFromBTCLifiSwapQuote,
  getMultiToBTCRelaySwapQuote,
  OutputDetails,
  executeSwapFlow,
  executeBungeeSwapFlow,
  executeFromBTCSwapFlow,
  executeToBTCSwapFlow,
  searchToken,
  getTransactionInfo,
  executeLiFiSwapFlow,
  getOptimalSourceTokenDistribution,
  OptimalSourceTokenDistributionParams,
  OptimalSourceTokenDistributionResponse,
  OptimalSourceTokenDistributionInput,
  computeQuote,
  ComputeQuoteParams,
  ComputeQuoteResponse,
  ComputeQuoteInput,
  getSourceTokensFromTokenIdentifier,
  SourceTokensInput,
  SourceTokensResponse,
  executeTransferFlow,
  executeBitcoinTransfer,
  TransferFlowParams,
  BitcoinTransferParams,
  TransferResponse,
  BitcoinTransferResponse,
} from "../services/services";
import {
  calculateQuote,
  CalculateQuoteInput,
  CalculateQuoteParams,
  CalculateQuoteResponse,
  executeSwapQuote,
  ExecuteSwapInput,
  ExecuteSwapParams,
  ExecuteSwapResponse,
  getQuoteForActionAmountOut,
  GetQuoteForActionInput,
  GetQuoteForActionParams,
  GetQuoteForActionResponse,
  executeActionAmountOut,
  ExecuteActionInput,
  ExecuteActionParams,
  ExecuteActionResponse,
  UserBalance,
} from "../services/quoteServices";
import { QuoteType, QuoteChoice } from "../services/services";
import { swapToken } from "../types/swap";
import { ProtocolProvider } from "./utils";
import {
  ThemeMode,
  CornerRadius,
  WalletSDKConfig,
  WalletConfig,
  mapCornerRadius,
  mapAppearanceToTheme,
  getThemeStyles,
  Theme,
} from "../types/theme";

// Add Bitcoin mainnet chain ID constant
const BITCOIN_MAINNET_CHAIN_ID = 8253038;

interface Token {
  chainIds: {
    chainId: number;
    address: string;
  }[];
  tokenAddress: string;
  amount?: string;
  icon?: string;
  symbol: string;
  name: string;
  decimals: number;
}

interface SwapParams {
  fromToken: swapToken;
  toToken: Omit<swapToken, "amount">;
  showMessagePopup?: boolean;
  messageType?: "success" | "error";
  transactionId?: string;
}

// Add new interface for transfer parameters
interface TransferParams {
  inputToken: {
    symbol?: string;
    name?: string;
    address: string;
    chainId: number;
    decimals?: number;
    balance?: string;
    logoURI?: string;
    chainIds?: {
      chainId: number;
      address: string;
      balance?: string;
    }[];
  };
  inputAmount?: string;
  recipient: string;
}

interface HeadlessTransferParams {
  inputToken: {
    symbol?: string;
    name?: string;
    address: string;
    chainId: number;
    decimals?: number;
    balance?: string;
    logoURI?: string;
    chainIds?: {
      chainId: number;
      address: string;
      balance?: string;
    }[];
  };
  inputAmount: string;
  recipient: string;
}

// Add new interface for quote calculation
interface QuoteParams {
  fromToken: {
    amount: string;
    chainId: number;
    tokenAddress: string;
    metadata?: {
      tokenName: string;
      tokenSymbol: string;
      decimals: number;
      logoURI: string;
      chainIds: {
        chainId: number;
        address: string;
      }[];
    };
  };
  toToken: {
    chainId: number;
    tokenAddress: string;
    metadata?: {
      tokenName: string;
      tokenSymbol: string;
      decimals: number;
      logoURI: string;
      chainIds: {
        chainId: number;
        address: string;
      }[];
    };
  };
  provider?: ProtocolProvider;
}

interface WalletContextType {
  walletSDK: WalletSDK | null;
  isLoggedIn: boolean;
  username: string | null;
  evmWalletAddress: string | null;
  solanaAddress: string | null;
  bitcoinWalletAddress: string | null;
  balance: any | null;
  connect: () => void;
  openWalletModal: () => void;
  disconnect: () => void;
  swap: (params: SwapParams) => void;
  executeTransfer: (params: TransferParams) => void;
  executeHeadlessTransfer: (params: HeadlessTransferParams) => Promise<any>;
  tokenOptions: TokenInfo[];
  tokensLoading: boolean;
  refreshTokenOptions: () => Promise<void>;
  cryptoBalance: any;
  loading: boolean;
  setLoading: (loading: boolean) => void;
  refreshBalance: (showLoading?: boolean) => Promise<void>;
  showActivity: boolean;
  setShowActivity: (showActivity: boolean) => void;
  activity: any;
  setActivity: (activity: any) => void;
  calculateDemoQuote: (params: QuoteParams) => Promise<OutputDetails | string>;
  headlessSwap: (params: QuoteParams) => Promise<any>;
  getOptimalSourceTokenDistribution: (
    params: OptimalSourceTokenDistributionInput
  ) => Promise<OptimalSourceTokenDistributionResponse | null>;
  computeQuote: (
    params: ComputeQuoteInput
  ) => Promise<ComputeQuoteResponse | null>;
  getSourceTokensFromTokenIdentifier: (
    params: SourceTokensInput
  ) => Promise<SourceTokensResponse | null>;
  calculateQuote: (
    params: CalculateQuoteInput
  ) => Promise<CalculateQuoteResponse | null>;
  executeSwap: (
    params: ExecuteSwapInput
  ) => Promise<ExecuteSwapResponse | null>;
  getQuoteForAction: (
    params: GetQuoteForActionInput
  ) => Promise<GetQuoteForActionResponse | null>;
  executeAction: (
    params: ExecuteActionInput
  ) => Promise<ExecuteActionResponse | null>;
  theme: ThemeMode;
  walletCornerRadius: CornerRadius;
  config: WalletConfig;
  currentTheme: Theme;
  // New popup login functions
  loginWithRedirect: () => void;
  handlePopupMessage: (event: MessageEvent) => void;
  // Popup login data
  isPopupAuthenticated: boolean;
  popupLoginData: any;
}

const WalletContext = createContext<WalletContextType | null>(null);

export const useWallet = () => {
  const context = useContext(WalletContext);
  if (!context) {
    throw new Error("useWallet must be used within a WalletProvider");
  }
  return context;
};

interface WalletProviderProps {
  children: React.ReactNode;
  config: WalletConfig;
}

export const WalletProvider: React.FC<WalletProviderProps> = ({
  children,
  config,
}) => {
  // Extract values from config with defaults
  const sdkKey = config.sdkKey;
  const theme = mapAppearanceToTheme(config.appearance);
  const cornerRadius = mapCornerRadius(config.cornerRadius);
  const fontFamily = config.fontFamily || "Inter, sans-serif";

  const [walletSDK, setWalletSDK] = useState<WalletSDK | null>(null);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [username, setUsername] = useState<string | null>(null);
  const [evmWalletAddress, setEvmWalletAddress] = useState<string | null>(null);
  const [solanaAddress, setSolanaAddress] = useState<string | null>(null);
  const [bitcoinWalletAddress, setBitcoinWalletAddress] = useState<
    string | null
  >(null);
  const [balance, setBalance] = useState<any | null>(null);
  const [showSwapModal, setShowSwapModal] = useState(false);
  const [swapParams, setSwapParams] = useState<SwapParams | null>(null);
  const [tokenOptions, setTokenOptions] = useState<TokenInfo[]>([]);
  const [tokensLoading, setTokensLoading] = useState(false);

  // Add transfer-related state
  const [transferParams, setTransferParams] = useState<TransferParams | null>(
    null
  );

  // Add new states for crypto balance functionality
  const [cryptoBalance, setCryptoBalance] = useState<any>(null);
  const [loading, setLoading] = useState(false);
  const [showActivity, setShowActivity] = useState(false);
  const [activity, setActivity] = useState<any>(null);
  const [showMessagePopup, setShowMessagePopup] = useState(true);
  const [messageType, setMessageType] = useState<"success" | "error">(
    "success"
  );
  const [transactionId, setTransactionId] = useState<string | null>(null);
  const [walletTheme, setWalletTheme] = useState<ThemeMode>(theme);
  const [walletCornerRadius, setWalletCornerRadius] =
    useState<CornerRadius>(cornerRadius);

  // Computed theme that includes primaryColor
  const [currentTheme, setCurrentTheme] = useState<Theme>(
    getThemeStyles(config.primaryColor || "#1657FF")[theme]
  );

  // Update currentTheme when config.primaryColor or theme changes
  useEffect(() => {
    setCurrentTheme(
      getThemeStyles(config.primaryColor || "#1657FF")[walletTheme]
    );
  }, [config.primaryColor, walletTheme]);

  // Add popup login state
  const [isPopupAuthenticated, setIsPopupAuthenticated] = useState(false);
  const [popupLoginData, setPopupLoginData] = useState<any>(null);

  // Function to refresh Firebase token
  const refreshFirebaseToken = async () => {
    try {
      const currentUser = auth.currentUser;
      if (currentUser) {
        // Get fresh ID token
        const newIdToken = await currentUser.getIdToken(true); // Force refresh
        const newRefreshToken = currentUser.refreshToken;

        // Update localStorage with new tokens
        if (typeof window !== "undefined") {
          const savedLogin = localStorage.getItem("enclave_wallet_login");
          if (savedLogin) {
            const parsedLogin = JSON.parse(savedLogin);
            const updatedLogin = {
              ...parsedLogin,
              result: {
                ...parsedLogin.result,
                token: newIdToken,
                refreshToken: newRefreshToken,
              },
            };
            localStorage.setItem(
              "enclave_wallet_login",
              JSON.stringify(updatedLogin)
            );
            console.log("Firebase tokens refreshed successfully");
          }
        }
      }
    } catch (error) {
      console.error("Error refreshing Firebase token:", error);
    }
  };

  const refreshTokenOptions = async () => {
    try {
      setTokensLoading(true);
      const response = await getAllTokens(sdkKey);
      if (response?.success) {
        setTokenOptions(response.tokens);
      }
    } catch (error) {
      console.error("Error fetching token options:", error);
    } finally {
      setTokensLoading(false);
    }
  };

  const refreshBalance = async (showLoading: boolean = false) => {
    try {
      if (showLoading) {
        setLoading(true);
      }

      const sdkInstance = (window as any).__walletSDKInstance;

      if (sdkInstance) {
        const balance = await sdkInstance.getUserCryptoBalance();
        if (balance) {
          setCryptoBalance(balance);
          // Store balance in localStorage for persistence

          if (typeof window !== "undefined" && balance !== null) {
            localStorage.setItem(
              "enclave_crypto_balance",
              JSON.stringify(balance)
            );
          }
        }
      }
    } catch (error) {
      console.error("Error fetching balance:", error);
    } finally {
      setLoading(false);
    }
  };

  // Initialize crypto balance from localStorage on mount
  useEffect(() => {
    if (typeof window !== "undefined") {
      const savedBalance = localStorage.getItem("enclave_crypto_balance");
      if (savedBalance) {
        try {
          setCryptoBalance(JSON.parse(savedBalance));
        } catch (error) {
          console.error("Error parsing saved balance:", error);
        }
      }

      // Initialize popup login data from localStorage
      const savedPopupLoginData = localStorage.getItem(
        "enclave_popup_login_data"
      );
      if (savedPopupLoginData) {
        try {
          const parsedData = JSON.parse(savedPopupLoginData);
          setPopupLoginData(parsedData);
          setIsPopupAuthenticated(true);
        } catch (error) {
          console.error("Error parsing saved popup login data:", error);
        }
      }
    }
  }, []);

  // Listen for storage changes to trigger balance refresh
  useEffect(() => {
    const handleStorageChange = (e: StorageEvent) => {
      if (e.key === "enclave_wallet_login") {
        if (e.newValue) {
          refreshBalance(true);
          refreshTokenOptions();
        } else {
          setCryptoBalance(null);
          // Clear popup login data when main login is cleared
          setIsPopupAuthenticated(false);
          setPopupLoginData(null);
          // Clear balance from localStorage when user logs out
          if (typeof window !== "undefined") {
            localStorage.removeItem("enclave_crypto_balance");
            localStorage.removeItem("enclave_popup_login_data");
          }
        }
      }
    };

    if (typeof window !== "undefined") {
      window.addEventListener("storage", handleStorageChange);
      return () => window.removeEventListener("storage", handleStorageChange);
    }
  }, []);

  // Initial balance load
  useEffect(() => {
    if (typeof window !== "undefined") {
      const userSession = localStorage.getItem("enclave_wallet_login");
      if (userSession) {
        refreshBalance(true); // Show loading on initial load
      }
    }
  }, [sdkKey]);

  // Balance polling effect
  useEffect(() => {
    if (typeof window !== "undefined") {
      const userSession = localStorage.getItem("enclave_wallet_login");
      if (!userSession) return;

      const pollInterval = setInterval(() => {
        refreshBalance(false); // Don't show loading during polling
      }, 10000);

      return () => clearInterval(pollInterval);
    }
  }, [sdkKey]);

  // Firebase token refresh effect
  useEffect(() => {
    if (typeof window !== "undefined") {
      const userSession = localStorage.getItem("enclave_wallet_login");
      if (!userSession) return;

      // Refresh token every 50 minutes (Firebase tokens typically expire in 1 hour)
      const tokenRefreshInterval = setInterval(() => {
        refreshFirebaseToken();
      }, 50 * 60 * 1000); // 50 minutes

      return () => clearInterval(tokenRefreshInterval);
    }
  }, []);

  // Listen for Firebase auth state changes
  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((user) => {
      if (user) {
        // User is signed in, refresh token
        refreshFirebaseToken();
      } else {
        // User is signed out, clear localStorage
        if (typeof window !== "undefined") {
          localStorage.removeItem("enclave_wallet_login");
          localStorage.removeItem("enclave_crypto_balance");
          localStorage.removeItem("enclave_popup_login_data");
        }
      }
    });

    return () => unsubscribe();
  }, []);

  useEffect(() => {
    // Create WalletSDK instance - it will automatically load saved config from localStorage
    const sdk = new WalletSDK(sdkKey, config);
    setWalletSDK(sdk);

    // Set the theme and corner radius from the final config (which includes saved preferences)
    const finalConfig = sdk.getConfig();
    const finalTheme = mapAppearanceToTheme(finalConfig.appearance);
    const finalCornerRadius = mapCornerRadius(finalConfig.cornerRadius);

    setWalletTheme(finalTheme);
    setWalletCornerRadius(finalCornerRadius);

    // Check initial login state and refresh Firebase token
    if (typeof window !== "undefined") {
      const saved = localStorage.getItem("enclave_wallet_login");
      if (saved) {
        const parsed = JSON.parse(saved);
        setIsLoggedIn(true);
        setUsername(
          parsed.result?.displayName || parsed.result?.username || null
        );
        setEvmWalletAddress(parsed.result?.wallet?.scw_address || null);
        setSolanaAddress(parsed.result?.wallet?.solana_program_wallet || null);
        setBitcoinWalletAddress(
          parsed.result?.wallet?.bitcoin_wallet?.native_segwit_address || null
        );

        // Refresh Firebase token on component mount
        refreshFirebaseToken();

        // Fetch initial balance and tokens if logged in
        refreshBalance(false);
        refreshTokenOptions();
      }
    }
  }, [sdkKey, config]);

  const connect = () => {
    if (walletSDK) {
      // Check if domain is localhost:3000 or demo.enclave.money
      const currentHostname = window.location.hostname;
      const currentOrigin = window.location.origin;

      if (
        currentOrigin === "https://localhost:3000" ||
        currentHostname === "demo.enclave.money" ||
        currentHostname === "localhost" ||
        currentHostname === "app.enclave.money"
      ) {
        walletSDK.openWalletModal();
      } else {
        loginWithRedirect();
      }
    }
  };

  const disconnect = () => {
    if (walletSDK) {
      walletSDK.logout();
      setIsLoggedIn(false);
      setUsername(null);
      setEvmWalletAddress(null);
      setBalance(null);
      setCryptoBalance(null);
      // Clear popup login data
      setIsPopupAuthenticated(false);
      setPopupLoginData(null);
      // Clear balance from localStorage when user disconnects
      if (typeof window !== "undefined") {
        auth.signOut();
        localStorage.removeItem("enclave_wallet_login");
        localStorage.removeItem("enclave_crypto_balance");
        localStorage.removeItem("enclave_popup_login_data");
      }
    }
  };

  // Listen for session changes and update balance
  useEffect(() => {
    if (!walletSDK) return;

    const checkSession = async () => {
      if (typeof window !== "undefined") {
        const saved = localStorage.getItem("enclave_wallet_login");
        if (saved) {
          const parsed = JSON.parse(saved);
          setIsLoggedIn(true);
          setUsername(
            parsed.result?.displayName || parsed.result?.username || null
          );
          setEvmWalletAddress(parsed.result?.wallet?.scw_address || null);
          setSolanaAddress(
            parsed.result?.wallet?.solana_program_wallet || null
          );
          setBitcoinWalletAddress(
            parsed.result?.wallet?.bitcoin_wallet?.native_segwit_address || null
          );

          // Fetch updated balance
        } else {
          setIsLoggedIn(false);
          setUsername(null);
          setEvmWalletAddress(null);
          setBalance(null);
          setCryptoBalance(null);
          setSolanaAddress(null);
          setBitcoinWalletAddress(null);
          const sdkInstance = (window as any).__walletSDKInstance;
          if (sdkInstance) {
            sdkInstance.setUsername(null);
          }
          // Clear balance from localStorage when session is not found
          localStorage.removeItem("enclave_crypto_balance");
        }
      }
    };

    // Check session every 1 seconds
    const interval = setInterval(checkSession, 1000);
    return () => clearInterval(interval);
  }, [walletSDK]);

  const swap = (params: SwapParams) => {
    if (!isLoggedIn) {
      connect();
      return;
    }

    setSwapParams(params);
    setShowSwapModal(true);
    walletSDK?.openWalletModal(params);
  };

  const executeTransfer = (params: TransferParams) => {
    if (!isLoggedIn) {
      connect();
      return;
    }

    setTransferParams(params);
    walletSDK?.openWalletModal(undefined, params);
  };

  const executeHeadlessTransfer = async (
    params: TransferParams
  ): Promise<any> => {
    const sdkInstance = (window as any).__walletSDKInstance;
    if (!sdkInstance) {
      throw new Error("SDK instance not found");
    }

    const userName = sdkInstance.getUsername();
    if (!userName) {
      throw new Error("User not logged in");
    }

    // Show processing toast
    const loadingToast = toast.loading("Processing transfer...");

    try {
      // Search for the token in cryptoBalance to get accurate data
      let tokenFromBalance = null;
      if (cryptoBalance?.data) {
        tokenFromBalance = cryptoBalance.data.find((token: any) =>
          token.chainIds?.some(
            (chain: any) =>
              chain.address.toLowerCase() ===
                params.inputToken.address.toLowerCase() &&
              chain.chainId === params.inputToken.chainId
          )
        );
      }

      const isBitcoin =
        tokenFromBalance?.chainId === BITCOIN_MAINNET_CHAIN_ID &&
        tokenFromBalance?.symbol === "BTC";

      // Use token data from cryptoBalance if found, otherwise fallback to provided data
      const tokenData = tokenFromBalance || {
        symbol: params.inputToken.symbol || "",
        name: params.inputToken.name || "",
        decimals: params.inputToken.decimals || (isBitcoin ? 8 : 6),
        logoURI: params.inputToken.logoURI || "",
        chainIds: params.inputToken.chainIds || [
          {
            chainId: params.inputToken.chainId,
            address: params.inputToken.address,
            balance: params.inputToken.balance || "0",
          },
        ],
      };

      let response;

      if (isBitcoin) {
        // Handle Bitcoin transfer
        const btcTransferParams: BitcoinTransferParams = {
          username: userName,
          inputAmount: params.inputAmount || "0",
          recipient: params.recipient,
          outputChainId: params.inputToken.chainId,
          metadata: {
            token: {
              tokenSymbol: tokenData.symbol,
              tokenName: tokenData.name,
              decimals: tokenData.decimals,
              logoURI: tokenData.logoURI,
            },
            receiver: {
              username: "", // This would need to be filled based on recipient lookup
              walletAddress: params.recipient,
              solanaWalletAddress: "",
              ensName: "",
              sns: "",
            },
          },
        };

        response = await executeBitcoinTransfer(btcTransferParams, sdkKey);
      } else {
        // Get the specific chain data for the target chain
        const chainData = tokenData.chainIds?.find(
          (chain: any) => chain.chainId === params.inputToken.chainId
        );

        // Handle regular token transfer
        const transferParams: TransferFlowParams = {
          username: userName,
          inputAmount: params.inputAmount || "0",
          outputToken: chainData?.address || params.inputToken.address,
          outputDecimals: tokenData.decimals,
          outputChainId: params.inputToken.chainId,
          recipient: params.recipient,
          userBalance: tokenData.chainIds || [
            {
              chainId: params.inputToken.chainId,
              address: params.inputToken.address,
              balance: params.inputToken.balance || "0",
            },
          ],
          metadata: {
            token: {
              tokenSymbol: tokenData.symbol,
              tokenName: tokenData.name,
              decimals: tokenData.decimals,
              logoURI: tokenData.logoURI,
            },
            receiver: {
              username: "", // This would need to be filled based on recipient lookup
              walletAddress: params.recipient,
              solanaWalletAddress: "",
              ensName: "",
              sns: "",
            },
          },
        };

        response = await executeTransferFlow(transferParams, sdkKey);
      }

      // Dismiss loading toast
      toast.dismiss(loadingToast);

      if (isBitcoin) {
        // Handle Bitcoin transfer response
        const btcResponse = response as BitcoinTransferResponse;
        if (
          btcResponse.success &&
          btcResponse.transactionDetails?.multiTransactionId
        ) {
          console.log("Bitcoin transfer initiated:", btcResponse);

          // Show transfer initiated toast with loader
          const transferInitiatedToast = toast.loading("Transfer initiated...");

          setActivity(btcResponse);

          // Start polling transaction status for Bitcoin
          const multiTransactionId =
            btcResponse.transactionDetails.multiTransactionId;

          const pollTransactionStatus = async () => {
            let isCompleted = false;
            let attempts = 0;
            const maxAttempts = 60; // Poll for up to 5 minutes (60 * 5 seconds)

            while (!isCompleted && attempts < maxAttempts) {
              try {
                await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5 seconds

                const transactionInfo = await getTransactionInfo(
                  multiTransactionId,
                  sdkKey
                );

                if (transactionInfo) {
                  const status = transactionInfo.overallStatus;

                  if (status === "COMPLETED") {
                    toast.dismiss(transferInitiatedToast);
                    const successToastId = toast.success(
                      <div
                        style={{
                          display: "flex",
                          alignItems: "center",
                          gap: "12px",
                        }}
                      >
                        <span>Transfer completed</span>
                        <button
                          onClick={() => {
                            if (walletSDK) {
                              // Store the transaction data in localStorage
                              if (typeof window !== "undefined") {
                                localStorage.setItem(
                                  "enclave_transaction_data",
                                  JSON.stringify({
                                    transactionId: multiTransactionId,
                                  })
                                );
                              }
                              walletSDK.openWalletModal();
                            }
                            toast.dismiss(successToastId);
                          }}
                          style={{
                            color: "white",
                            borderRadius: "20px",
                            padding: "4px 8px",
                            fontSize: "13px",
                            fontWeight: "500",
                            cursor: "pointer",
                            background: "black",
                            border: "1px solid rgba(255, 255, 255, 0.33)",
                          }}
                        >
                          View
                        </button>
                      </div>,
                      { duration: 6000 }
                    );
                    isCompleted = true;
                    // Refresh balance after successful completion
                    refreshBalance(false);
                  } else if (status === "FAILED") {
                    toast.dismiss(transferInitiatedToast);
                    toast.error("Transfer failed");
                    isCompleted = true;
                  }
                  // If status is still PENDING, continue polling
                }

                attempts++;
              } catch (error) {
                console.error("Error polling transaction status:", error);
                attempts++;
              }
            }

            // If polling times out
            if (!isCompleted) {
              toast.dismiss(transferInitiatedToast);
              toast.error("Transfer status check timed out");
            }
          };

          // Start polling in background
          pollTransactionStatus();
        } else {
          console.error("Bitcoin transfer failed:", btcResponse);
          toast.error("Bitcoin transfer failed");
        }
      } else {
        // Handle regular transfer response
        const transferResponse = response as TransferResponse;
        if (
          transferResponse.outputDetails &&
          (transferResponse.onChainTransfer || transferResponse.relayTransfer)
        ) {
          console.log("Transfer completed:", transferResponse);

          // Get transaction ID for viewing
          let transactionId =
            (transferResponse as any).transactionDetails?.multiTransactionId ||
            "";

          // Show success message immediately for regular transfers
          const successToastId = toast.success(
            <div
              style={{
                display: "flex",
                alignItems: "center",
                gap: "12px",
              }}
            >
              <span>Transfer completed</span>
              {transactionId && (
                <button
                  onClick={() => {
                    if (walletSDK) {
                      // Store the transaction data in localStorage
                      if (typeof window !== "undefined") {
                        localStorage.setItem(
                          "enclave_transaction_data",
                          JSON.stringify({
                            transactionId: transactionId,
                          })
                        );
                      }
                      walletSDK.openWalletModal();
                    }
                    toast.dismiss(successToastId);
                  }}
                  style={{
                    color: "white",
                    borderRadius: "20px",
                    padding: "4px 8px",
                    fontSize: "13px",
                    fontWeight: "500",
                    cursor: "pointer",
                    background: "black",
                    border: "1px solid rgba(255, 255, 255, 0.33)",
                  }}
                >
                  View
                </button>
              )}
            </div>,
            { duration: 6000 }
          );

          // Refresh balance after successful completion
          refreshBalance(false);
        } else {
          console.error("Transfer failed:", transferResponse);
          toast.error("Transfer failed");
        }
      }

      return response;
    } catch (error: any) {
      console.error("Error executing headless transfer:", error);

      // Dismiss loading toast and show error toast
      toast.dismiss(loadingToast);
      toast.error("Transfer failed");

      throw error;
    }
  };

  // Add unified calculateQuote function
  const calculateQuoteWrapper = async (
    params: CalculateQuoteInput
  ): Promise<CalculateQuoteResponse | null> => {
    try {
      const sdkInstance = (window as any).__walletSDKInstance;
      if (!sdkInstance) {
        throw new Error("SDK instance not found");
      }

      const userName = sdkInstance.getUsername();
      if (!userName) {
        throw new Error("User not logged in");
      }

      const requestParams: CalculateQuoteParams = {
        username: userName,
        fromTokens: params.fromTokens,
        toToken: params.toToken,
        quoteType: params.quoteType,
        ...(params.action && { action: params.action }),
      };

      return await calculateQuote(requestParams, sdkKey);
    } catch (error) {
      console.error("Error calculating quote:", error);
      return null;
    }
  };

  // Add unified executeSwap function
  const executeSwap = async (
    params: ExecuteSwapInput
  ): Promise<ExecuteSwapResponse | null> => {
    try {
      const sdkInstance = (window as any).__walletSDKInstance;
      if (!sdkInstance) {
        throw new Error("SDK instance not found");
      }

      const userName = sdkInstance.getUsername();
      if (!userName) {
        throw new Error("User not logged in");
      }

      const requestParams: ExecuteSwapParams = {
        username: userName,
        fromTokens: params.fromTokens,
        toToken: params.toToken,
        isHeadless: params.isHeadless,
        quoteChoice: params.quoteChoice,
        quoteType: params.quoteType,
        quoteId: params.quoteId,
        ...(params.action && { action: params.action }),
      };

      return await executeSwapQuote(requestParams, sdkKey);
    } catch (error) {
      console.error("Error executing quote:", error);
      return null;
    }
  };

  const openWalletModal = () => {
    if (walletSDK) {
      walletSDK.openWalletModal();
    }
  };

  // Add initial token fetch
  useEffect(() => {
    refreshTokenOptions();
  }, [sdkKey]);

  // Add token refresh on login/logout
  useEffect(() => {
    if (isLoggedIn) {
      refreshBalance(true);
    } else {
      setTokenOptions([]);
    }
  }, [isLoggedIn]);

  // Add quote calculation function
  const calculateDemoQuote = async (
    params: QuoteParams
  ): Promise<OutputDetails | string> => {
    const sdkInstance = (window as any).__walletSDKInstance;
    if (!sdkInstance) {
      throw new Error("SDK instance not found");
    }

    const userName = sdkInstance.getUsername();
    if (!userName) {
      throw new Error("User not logged in");
    }

    try {
      // Check if input token is Bitcoin
      if (params.fromToken.chainId === BITCOIN_MAINNET_CHAIN_ID) {
        const metadata = {
          inputToken: {
            tokenName: params.fromToken.metadata?.tokenName || "",
            tokenSymbol: params.fromToken.metadata?.tokenSymbol || "",
            tokenAddress: params.fromToken.tokenAddress,
            decimals: params.fromToken.metadata?.decimals || 0,
            logoURI: params.fromToken.metadata?.logoURI || "",
          },
          outputToken: {
            tokenName: params.toToken.metadata?.tokenName || "",
            tokenSymbol: params.toToken.metadata?.tokenSymbol || "",
            tokenAddress: params.toToken.tokenAddress,
            decimals: params.toToken.metadata?.decimals || 0,
            logoURI: params.toToken.metadata?.logoURI || "",
          },
        };

        const userBalance = cryptoBalance?.data?.find((token: any) =>
          token.chainIds?.some(
            (chain: any) =>
              chain.address.toLowerCase() ===
                params.fromToken.tokenAddress.toLowerCase() &&
              chain.chainId === params.fromToken.chainId
          )
        );

        const defaultBalance = [
          {
            chainId: params.fromToken.chainId,
            address: params.fromToken.tokenAddress,
            balance: "0",
          },
        ];

        return await getMultiFromBTCLifiSwapQuote(
          {
            username: userName,
            inputAmount: params.fromToken.amount,
            outputToken: params.toToken.tokenAddress,
            outputChainId: params.toToken.chainId,
            metadata,
            proMode: false,
            userBalance: userBalance?.chainIds || defaultBalance,
          },
          sdkKey
        );
      }
      // Check if output token is Bitcoin
      else if (params.toToken.chainId === BITCOIN_MAINNET_CHAIN_ID) {
        // Get user balance for the input token
        const userBalance = cryptoBalance?.data?.find((token: any) =>
          token.chainIds?.some(
            (chain: any) =>
              chain.address.toLowerCase() ===
                params.fromToken.tokenAddress.toLowerCase() &&
              chain.chainId === params.fromToken.chainId
          )
        );

        // Default balance if user doesn't have the token
        const defaultBalance = [
          {
            chainId: params.fromToken.chainId,
            address: params.fromToken.tokenAddress,
            balance: "0",
          },
        ];

        return await getMultiToBTCRelaySwapQuote(
          {
            username: userName,
            userBalance: userBalance?.chainIds || defaultBalance,
            inputAmount: params.fromToken.amount,
            proMode: false,
          },
          sdkKey
        );
      }
      // Regular swap quote
      else {
        // Get user balance for the input token
        const userBalance = cryptoBalance?.data?.find((token: any) =>
          token.chainIds?.some(
            (chain: any) =>
              chain.address.toLowerCase() ===
                params.fromToken.tokenAddress.toLowerCase() &&
              chain.chainId === params.fromToken.chainId
          )
        );

        // Default balance if user doesn't have the token
        const defaultBalance = [
          {
            chainId: params.fromToken.chainId,
            address: params.fromToken.tokenAddress,
            balance: "0",
          },
        ];

        const metadata = {
          inputToken: {
            tokenName: params.fromToken.metadata?.tokenName || "",
            tokenSymbol: params.fromToken.metadata?.tokenSymbol || "",
            tokenAddress: params.fromToken.tokenAddress,
            decimals: params.fromToken.metadata?.decimals || 0,
            logoURI: params.fromToken.metadata?.logoURI || "",
          },
          outputToken: {
            tokenName: params.toToken.metadata?.tokenName || "",
            tokenSymbol: params.toToken.metadata?.tokenSymbol || "",
            tokenAddress: params.toToken.tokenAddress,
            decimals: params.toToken.metadata?.decimals || 0,
            logoURI: params.toToken.metadata?.logoURI || "",
          },
        };

        return await getMultiRelaySwapQuote(
          {
            username: userName,
            userBalance: userBalance?.chainIds || defaultBalance,
            outputToken: params.toToken.tokenAddress,
            outputChainId: params.toToken.chainId,
            inputAmount: params.fromToken.amount,
            proMode: false,
            metadata,
          },
          sdkKey
        );
      }
    } catch (error) {
      console.error("Error calculating quote:", error);
      return "Error calculating quote";
    }
  };

  // Add execute swap function
  const headlessSwap = async (params: QuoteParams): Promise<any> => {
    const sdkInstance = (window as any).__walletSDKInstance;
    if (!sdkInstance) {
      throw new Error("SDK instance not found");
    }

    const userName = sdkInstance.getUsername();
    if (!userName) {
      throw new Error("User not logged in");
    }

    // Show processing toast
    const loadingToast = toast.loading("Processing transaction...");

    try {
      // Get token details from tokenOptions for metadata

      let fromTokenDetails = tokenOptions.find((token) =>
        token.chainIds?.some(
          (chain) =>
            chain.address.toLowerCase() ===
              params.fromToken.tokenAddress.toLowerCase() &&
            chain.chainId === params.fromToken.chainId
        )
      );

      let toTokenDetails = tokenOptions.find((token) =>
        token.chainIds?.some(
          (chain) =>
            chain.address.toLowerCase() ===
              params.toToken.tokenAddress.toLowerCase() &&
            chain.chainId === params.toToken.chainId
        )
      );

      // If either token details are not found, try to fetch them using searchToken
      if (!fromTokenDetails) {
        if (params.fromToken.metadata) {
          fromTokenDetails = {
            name: params.fromToken.metadata.tokenName,
            symbol: params.fromToken.metadata.tokenSymbol,
            decimals: params.fromToken.metadata.decimals,
            logoURI: params.fromToken.metadata.logoURI,
            chainIds: params.fromToken.metadata.chainIds.map((chain) => ({
              chainId: chain.chainId,
              address: chain.address,
            })),
          } as TokenInfo;
        } else {
          const fromTokenSearch = await searchToken(
            params.fromToken.tokenAddress,
            params.fromToken.chainId,
            sdkKey
          );
          if (fromTokenSearch?.success) {
            fromTokenDetails = {
              name: fromTokenSearch.data.name,
              symbol: fromTokenSearch.data.symbol,
              decimals: fromTokenSearch.data.decimals,
              logoURI: fromTokenSearch.data.logoURI,
              chainIds: fromTokenSearch.data.chainIds.map((chain) => ({
                chainId: parseInt(chain.chainId),
                address: chain.address,
              })),
            } as TokenInfo;
          }
        }
      }

      if (!toTokenDetails) {
        if (params.toToken.metadata) {
          toTokenDetails = {
            name: params.toToken.metadata.tokenName,
            symbol: params.toToken.metadata.tokenSymbol,
            decimals: params.toToken.metadata.decimals,
            logoURI: params.toToken.metadata.logoURI,
            chainIds: params.toToken.metadata.chainIds.map((chain) => ({
              chainId: chain.chainId,
              address: chain.address,
            })),
          } as TokenInfo;
        } else {
          const toTokenSearch = await searchToken(
            params.toToken.tokenAddress,
            params.toToken.chainId,
            sdkKey
          );
          if (toTokenSearch?.success) {
            toTokenDetails = {
              name: toTokenSearch.data.name,
              symbol: toTokenSearch.data.symbol,
              decimals: toTokenSearch.data.decimals,
              logoURI: toTokenSearch.data.logoURI,
              chainIds: toTokenSearch.data.chainIds.map((chain) => ({
                chainId: parseInt(chain.chainId),
                address: chain.address,
              })),
            } as TokenInfo;
          }
        }
      }

      if (!fromTokenDetails || !toTokenDetails) {
        throw new Error(
          "Token details not found for " +
            params.fromToken.tokenAddress +
            " or " +
            params.toToken.tokenAddress
        );
      }

      const metadata = {
        inputToken: {
          tokenName: fromTokenDetails.name,
          tokenSymbol: fromTokenDetails.symbol,
          tokenAddress: params.fromToken.tokenAddress,
          decimals: fromTokenDetails.decimals,
          logoURI: fromTokenDetails.logoURI || fromTokenDetails.icon || "",
        },
        outputToken: {
          tokenName: toTokenDetails.name,
          tokenSymbol: toTokenDetails.symbol,
          tokenAddress: params.toToken.tokenAddress,
          decimals: toTokenDetails.decimals,
          logoURI: toTokenDetails.logoURI || toTokenDetails.icon || "",
        },
      };

      // Get user balance for the input token
      const userBalance = cryptoBalance?.data?.find((token: any) =>
        token.chainIds?.some((chain: any) =>
          fromTokenDetails?.chainIds?.some(
            (tokenChain) =>
              tokenChain.address.toLowerCase() ===
                chain.address.toLowerCase() &&
              tokenChain.chainId === chain.chainId
          )
        )
      );

      // Default balance if user doesn't have the token
      const defaultBalance = [
        {
          chainId: params.fromToken.chainId,
          address: params.fromToken.tokenAddress,
          balance: "0",
        },
      ];

      let data;
      if (params.fromToken.chainId === BITCOIN_MAINNET_CHAIN_ID) {
        data = await executeFromBTCSwapFlow(
          {
            username: userName,
            inputAmount: params.fromToken.amount,
            outputToken: params.toToken.tokenAddress,
            outputChainId: params.toToken.chainId,
            metadata,
            userBalance: userBalance?.chainIds || defaultBalance,
            proMode: false,
          },
          sdkKey
        );
      } else if (params.toToken.chainId === BITCOIN_MAINNET_CHAIN_ID) {
        data = await executeToBTCSwapFlow(
          {
            username: userName,
            userBalance: userBalance?.chainIds || defaultBalance,
            inputAmount: params.fromToken.amount,
            proMode: false,
            metadata,
          },
          sdkKey
        );
      } else {
        // Create swap parameters
        const swapParams = {
          username: userName,
          userBalance: userBalance?.chainIds || defaultBalance,
          outputToken: params.toToken.tokenAddress,
          outputChainId: params.toToken.chainId,
          inputAmount: params.fromToken.amount,
          metadata,
          proMode: false,
        };

        // Use appropriate swap function based on isBungee parameter
        if (params.provider === ProtocolProvider.BUNGEE) {
          data = await executeBungeeSwapFlow(swapParams, sdkKey);
        } else if (params.provider === ProtocolProvider.LIFI) {
          data = await executeLiFiSwapFlow(swapParams, sdkKey);
        } else {
          data = await executeSwapFlow(swapParams, sdkKey);
        }
      }

      // Dismiss loading toast
      toast.dismiss(loadingToast);

      if (
        data?.transactionDetails?.overallStatus === "PENDING" ||
        data?.transactionDetails?.overallStatus === "COMPLETED"
      ) {
        console.log("Transaction initiated:", data);

        // Show swap initiated toast with loader
        const swapInitiatedToast = toast.loading("Swap initiated...");

        setActivity(data);

        // Start polling transaction status
        const multiTransactionId = data.transactionDetails.multiTransactionId;

        const pollTransactionStatus = async () => {
          let isCompleted = false;
          let attempts = 0;
          const maxAttempts = 60; // Poll for up to 5 minutes (60 * 5 seconds)

          while (!isCompleted && attempts < maxAttempts) {
            try {
              await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5 seconds

              const transactionInfo = await getTransactionInfo(
                multiTransactionId,
                sdkKey
              );

              if (transactionInfo) {
                const status = transactionInfo.overallStatus;

                if (status === "COMPLETED") {
                  toast.dismiss(swapInitiatedToast);
                  const successToastId = toast.success(
                    <div
                      style={{
                        display: "flex",
                        alignItems: "center",
                        gap: "12px",
                      }}
                    >
                      <span>Transaction completed</span>
                      <button
                        onClick={() => {
                          if (walletSDK) {
                            // Store the transaction data in localStorage
                            if (typeof window !== "undefined") {
                              localStorage.setItem(
                                "enclave_transaction_data",
                                JSON.stringify({
                                  transactionId: multiTransactionId,
                                })
                              );
                            }
                            walletSDK.openWalletModal();
                          }
                          toast.dismiss(successToastId);
                        }}
                        style={{
                          color: "white",
                          borderRadius: "20px",
                          padding: "4px 8px",
                          fontSize: "13px",
                          fontWeight: "500",
                          cursor: "pointer",
                          background: "black",
                          border: "1px solid rgba(255, 255, 255, 0.33)",
                        }}
                      >
                        View
                      </button>
                    </div>,
                    { duration: 6000 }
                  );
                  isCompleted = true;
                  // Refresh balance after successful completion
                  refreshBalance(false);
                } else if (status === "FAILED") {
                  toast.dismiss(swapInitiatedToast);
                  toast.error("Transaction failed");
                  isCompleted = true;
                }
                // If status is still PENDING, continue polling
              }

              attempts++;
            } catch (error) {
              console.error("Error polling transaction status:", error);
              attempts++;
            }
          }

          // If polling times out
          if (!isCompleted) {
            toast.dismiss(swapInitiatedToast);
            toast.error("Transaction status check timed out");
          }
        };

        // Start polling in background
        pollTransactionStatus();
      } else {
        console.error("Transaction failed:", data);

        // Show error toast
        toast.error("Transaction failed");
      }

      return data;
    } catch (error) {
      console.error("Error executing swap:", error);

      // Dismiss loading toast and show error toast
      toast.dismiss(loadingToast);
      toast.error("Transaction failed");

      throw error;
    }
  };

  // Add getOptimalSourceTokenDistribution function
  const getOptimalSourceTokenDistributionWrapper = async (
    params: OptimalSourceTokenDistributionInput
  ): Promise<OptimalSourceTokenDistributionResponse | null> => {
    try {
      const sdkInstance = (window as any).__walletSDKInstance;
      if (!sdkInstance) {
        throw new Error("SDK instance not found");
      }

      const userName = sdkInstance.getUsername();
      if (!userName) {
        throw new Error("User not logged in");
      }

      const requestParams: OptimalSourceTokenDistributionParams = {
        username: userName,
        inputAmount: params.inputAmount,
        tokenIdentifier: params.tokenIdentifier,
      };

      return await getOptimalSourceTokenDistribution(requestParams, sdkKey);
    } catch (error) {
      console.error("Error getting optimal source token distribution:", error);
      return null;
    }
  };

  // Add computeQuote function
  const computeQuoteWrapper = async (
    params: ComputeQuoteInput
  ): Promise<ComputeQuoteResponse | null> => {
    try {
      const sdkInstance = (window as any).__walletSDKInstance;
      if (!sdkInstance) {
        throw new Error("SDK instance not found");
      }

      const userName = sdkInstance.getUsername();
      if (!userName) {
        throw new Error("User not logged in");
      }

      const requestParams: ComputeQuoteParams = {
        username: userName,
        fromTokens: params.fromTokens,
        toToken: params.toToken,
        quoteType: params.quoteType,
      };

      return await computeQuote(requestParams, sdkKey);
    } catch (error) {
      console.error("Error computing quote:", error);
      return null;
    }
  };

  // Add getSourceTokensFromTokenIdentifier function
  const getSourceTokensFromTokenIdentifierWrapper = async (
    params: SourceTokensInput
  ): Promise<SourceTokensResponse | null> => {
    try {
      return await getSourceTokensFromTokenIdentifier(params, sdkKey);
    } catch (error) {
      console.error(
        "Error getting source tokens from token identifier:",
        error
      );
      return null;
    }
  };

  // Add getQuoteForAction function
  const getQuoteForActionWrapper = async (
    params: GetQuoteForActionInput
  ): Promise<GetQuoteForActionResponse | null> => {
    try {
      const sdkInstance = (window as any).__walletSDKInstance;
      if (!sdkInstance) {
        throw new Error("SDK instance not found");
      }

      const userName = sdkInstance.getUsername();
      if (!userName) {
        throw new Error("User not logged in");
      }

      const requestParams: GetQuoteForActionParams = {
        username: userName,
        ...(params.fromTokens && {
          fromTokens: params.fromTokens,
        }),
        toToken: params.toToken,
        outputAmount: params.outputAmount,
        quoteType: params.quoteType,
        ...(params.action && { action: params.action }),
      };

      return await getQuoteForActionAmountOut(requestParams, sdkKey);
    } catch (error) {
      console.error("Error getting quote for action:", error);
      return null;
    }
  };

  // Add executeAction function
  const executeActionWrapper = async (
    params: ExecuteActionInput
  ): Promise<ExecuteActionResponse | null> => {
    try {
      const sdkInstance = (window as any).__walletSDKInstance;
      if (!sdkInstance) {
        throw new Error("SDK instance not found");
      }

      const userName = sdkInstance.getUsername();
      if (!userName) {
        throw new Error("User not logged in");
      }

      const requestParams: ExecuteActionParams = {
        username: userName,
        quoteChoice: params.quoteChoice,
        quoteId: params.quoteId,
        ...(params.fromTokens && {
          fromTokens: params.fromTokens,
        }),
        ...(params.toToken && {
          toToken: params.toToken,
        }),
        ...(params.outputAmount && { outputAmount: params.outputAmount }),
      };

      return await executeActionAmountOut(requestParams, sdkKey);
    } catch (error) {
      console.error("Error executing action:", error);
      return null;
    }
  };

  // Popup login functions
  const loginWithRedirect = () => {
    // Show status (you might want to use your existing toast system)
    console.log("Opening login popup...");

    // Open popup (adjust URL to your Next.js app)
    const popup = window.open(
      "https://id.enclave.money",
      "loginPopup",
      "width=500,height=600,left=" +
        (window.screen.width - 500) / 2 +
        ",top=" +
        (window.screen.height - 600) / 2 +
        ",resizable=yes,scrollbars=yes"
    );

    // Check if popup was blocked
    if (!popup) {
      console.error("Popup blocked! Please allow popups for this site.");
      toast.error("Popup blocked! Please allow popups for this site.");
      return;
    }

    // Send config to popup once it's loaded
    const sendConfig = () => {
      if (popup && !popup.closed) {
        try {
          popup.postMessage(
            {
              type: "CONFIG_DATA",
              config: config,
              sdkKey: sdkKey,
            },
            "https://id.enclave.money"
          );
          console.log("Config sent to popup:", config);
        } catch (error) {
          console.error("Error sending config to popup:", error);
        }
      }
    };

    // Try sending config multiple times to ensure popup receives it
    // Send immediately and then retry every 100ms for 2 seconds
    setTimeout(sendConfig, 100);
    setTimeout(sendConfig, 500);
    setTimeout(sendConfig, 1000);
    setTimeout(sendConfig, 2000);

    // Also listen for popup requesting config
    const handlePopupConfigRequest = (event: MessageEvent) => {
      if (event.origin !== "https://id.enclave.money") {
        return;
      }

      if (event.data.type === "REQUEST_CONFIG") {
        console.log("Popup requested config");
        sendConfig();
      }
    };

    window.addEventListener("message", handlePopupConfigRequest);

    // Clean up listener when popup closes
    const checkClosed = setInterval(() => {
      if (popup.closed) {
        window.removeEventListener("message", handlePopupConfigRequest);
        clearInterval(checkClosed);
      }
    }, 1000);
  };

  const handlePopupMessage = (event: MessageEvent) => {
    // In production, verify the event.origin
    if (event.origin !== "https://id.enclave.money") {
      return;
    }
    console.log("Received message from popup:", event.data);

    switch (event.data.type) {
      case "LOGIN_SUCCESS":
        handleLoginSuccess(event.data.data);
        break;
      case "LOGIN_ERROR":
        handleLoginError(event.data.error);
        break;
      case "LOGIN_CLOSED":
        console.log("Login popup was closed");
        break;
      case "REQUEST_CONFIG":
        console.log(
          "Popup requested config, but handled by individual popup listener"
        );
        break;
    }
  };

  const handleLoginSuccess = (userData: any) => {
    try {
      console.log("Login successful:", userData);

      // Store the complete user data in localStorage
      if (typeof window !== "undefined") {
        const loginData = {
          result: userData,
          timestamp: Date.now(),
        };
        localStorage.setItem("enclave_wallet_login", JSON.stringify(loginData));
        localStorage.setItem(
          "enclave_popup_login_data",
          JSON.stringify(userData)
        );
      }

      const sdkInstance = (window as any).__walletSDKInstance;
      if (sdkInstance) {
        sdkInstance.setUserSession({
          result: userData,
        });
      }

      // Update state with the received user data
      setIsPopupAuthenticated(true);
      setPopupLoginData(userData);
      setIsLoggedIn(true);
      setUsername(userData.username || null);
      setEvmWalletAddress(userData.wallet?.scw_address || null);
      setSolanaAddress(userData.wallet?.solana_program_wallet || null);
      setBitcoinWalletAddress(
        userData.wallet?.bitcoin_wallet?.native_segwit_address || null
      );

      // Show success message
      // toast.success("Login successful!");

      // Refresh balance and tokens
      refreshBalance(true);
      refreshTokenOptions();
    } catch (error) {
      console.error("Error handling login success:", error);
      toast.error("Error processing login data");
    }
  };

  const handleLoginError = (error: any) => {
    console.error("Login error:", error);
    toast.error("Login failed: " + (error.message || "Unknown error"));
  };

  // Set up global message listener for popup messages
  useEffect(() => {
    const messageHandler = (event: MessageEvent) => {
      handlePopupMessage(event);
    };

    if (typeof window !== "undefined") {
      window.addEventListener("message", messageHandler);
      return () => window.removeEventListener("message", messageHandler);
    }
  }, []);

  const value = {
    theme: walletTheme,
    walletCornerRadius,
    walletSDK,
    isLoggedIn,
    username,
    evmWalletAddress,
    solanaAddress,
    bitcoinWalletAddress,
    balance,
    connect,
    openWalletModal,
    disconnect,
    swap,
    executeTransfer,
    executeHeadlessTransfer,
    tokenOptions,
    tokensLoading,
    refreshTokenOptions,
    cryptoBalance,
    loading,
    setLoading,
    refreshBalance,
    showActivity,
    setShowActivity,
    activity,
    setActivity,
    calculateDemoQuote,
    headlessSwap,
    getOptimalSourceTokenDistribution: getOptimalSourceTokenDistributionWrapper,
    computeQuote: computeQuoteWrapper,
    getSourceTokensFromTokenIdentifier:
      getSourceTokensFromTokenIdentifierWrapper,
    calculateQuote: calculateQuoteWrapper,
    executeSwap: executeSwap,
    getQuoteForAction: getQuoteForActionWrapper,
    executeAction: executeActionWrapper,
    currentTheme,
    // New popup login functions
    loginWithRedirect,
    handlePopupMessage,
    // Popup login data
    isPopupAuthenticated,
    popupLoginData,
    config,
  };

  return (
    <ToastProvider>
      <WalletContext.Provider value={value}>
        <div>{children}</div>
      </WalletContext.Provider>
    </ToastProvider>
  );
};
