import React, { useState, useRef, useEffect } from "react";
import { Enclave } from "@enclavemoney/enclavemoney-web-experimental";
import { SwapToken } from "./Swap/SwapToken";
import { Dashboard } from "./Dashboard/Dashboard";
import TransferToken from "./Transfer/TransferToken";
import ActivityDetails from "./Activity/ActivityDetails";
import { WalletProvider, useWallet } from "./WalletProvider";
import { searchToken } from "../services/services";
import {
  signInWithGoogle,
  GoogleAuthResult,
  signInWithX,
  TwitterAuthResult,
  signInWithCustomTokenAndGetIdToken,
} from "../services/firebase-auth";
import {
  ArrowLeftIcon,
  BadgeAlert,
  BadgeCheck,
  CircleUserRound,
  CircleX,
} from "lucide-react";
import Spinner from "./ui/Spinner";
import { SwapParams } from "../types/swap";
import { motion, AnimatePresence } from "framer-motion";
import {
  ThemeMode,
  themeStyles,
  getThemeStyles,
  CornerRadius,
  borderRadiusStyles,
  WalletConfig,
  Theme,
} from "../types/theme";
import { getContrastingTextColor } from "./utils";

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

interface Token {
  symbol: string;
  name: string;
  icon: string;
  address: string;
  chainId: number;
  decimals: number;
  balance?: string;
  amount?: string;
  chainIds: Array<{
    chainId: number;
    address: string;
    balance?: string;
  }>;
  priceUsd?: number;
}

interface WalletModalProps {
  isOpen: boolean;
  onClose: () => void;
  walletSDKKey: string;
  swapParams?: SwapParams;
  transferParams?: TransferParams;
  showMessagePopup?: boolean;
  messageType?: "success" | "error";
  transactionId?: string;
  theme?: ThemeMode;
  cornerRadius?: CornerRadius;
  config?: WalletConfig;
}

const StartStep: React.FC<{
  onNext: () => void;
}> = ({ onNext }) => {
  const { walletCornerRadius, currentTheme } = useWallet();

  const currentRadius = borderRadiusStyles[walletCornerRadius];
  return (
    <>
      <div style={{ fontSize: 36, marginBottom: 10 }}>
        <img
          src="https://storage.googleapis.com/enclave_assets/passKey.png"
          alt="passkey Logo"
          style={{ width: 84 }}
        />
      </div>
      <div
        style={{
          color: currentTheme.textSecondary,
          fontSize: 17,
          textAlign: "center",
          marginBottom: 10,
        }}
      >
        Authenticate securely using your device's passkey
      </div>
      <button
        style={{
          marginTop: 10,
          width: "100%",
          background: currentTheme.primary,
          color: getContrastingTextColor(currentTheme.primary),
          fontWeight: 600,
          fontSize: 18,
          border: "none",
          borderRadius: currentRadius.innerRadius,
          padding: "16px 0",
          cursor: "pointer",
          boxShadow: "0 2px 8px rgba(70,100,233,0.10)",
          transition: "background 0.2s",
        }}
        onClick={onNext}
      >
        Use my passkey
      </button>
    </>
  );
};

const SignupStep: React.FC<{
  username: string;
  onUsernameChange: (v: string) => void;
  usernameStatus: null | "exists" | "not-exists";
  checking: boolean;
  error: string | null;
  actionLoading: boolean;
  onLogin: () => Promise<void>;
  onSignup: () => Promise<void>;
}> = ({
  username,
  onUsernameChange,
  usernameStatus,
  checking,
  error,
  actionLoading,
  onLogin,
  onSignup,
}) => {
  const { walletCornerRadius, currentTheme } = useWallet();
  const currentRadius = borderRadiusStyles[walletCornerRadius];
  return (
    <div style={{ width: "100%" }}>
      <label
        style={{
          fontWeight: 600,
          fontSize: 14,
          margin: "0px 10px 10px 10px",
          display: "block",
          color: currentTheme.textSecondary,
        }}
      >
        Choose a username
      </label>
      <input
        type="text"
        value={username}
        onChange={(e) => onUsernameChange(e.target.value)}
        placeholder="Enter username"
        style={{
          width: "100%",
          padding: "16px",
          borderRadius: currentRadius.innerRadius,
          border: `1px solid ${currentTheme.border}`,
          color: currentTheme.text,
          backgroundColor: currentTheme.surface,
          fontSize: 16,
          marginBottom: 8,
        }}
        disabled={actionLoading}
      />
      {checking && (
        <div
          style={{
            color: currentTheme.textSecondary,
            fontSize: 14,
            margin: "0px 10px 10px 10px",
          }}
        >
          Searching username...
        </div>
      )}
      {usernameStatus === "exists" && (
        <div
          style={{
            color: currentTheme.successText,
            fontSize: 14,
            display: "flex",
            alignItems: "center",
            gap: 4,
            margin: "0px 10px 10px 10px",
          }}
        >
          <BadgeCheck color={currentTheme.successText} size={16} /> Username
          found. You can log in.
        </div>
      )}
      {usernameStatus === "not-exists" && (
        <div
          style={{
            color: currentTheme.primary,
            fontSize: 14,
            display: "flex",
            alignItems: "center",
            gap: 4,
            margin: "0px 10px 10px 10px",
          }}
        >
          <BadgeAlert color={currentTheme.primary} size={16} /> Username is
          available. You can sign up.
        </div>
      )}
      {error && (
        <div
          style={{
            color: currentTheme.errorText,
            fontSize: 14,
            margin: "0px 10px 10px 10px",
          }}
        >
          <CircleX color={currentTheme.errorText} size={16} /> {error}
        </div>
      )}
      <button
        style={{
          marginTop: 16,
          width: "100%",
          background: currentTheme.primary,
          color: getContrastingTextColor(currentTheme.primary),
          fontWeight: 600,
          fontSize: 16,
          border: "none",
          borderRadius: currentRadius.innerRadius,
          padding: "16px 0",
          cursor: usernameStatus && !checking ? "pointer" : "not-allowed",
          boxShadow: "0 2px 8px rgba(70,100,233,0.10)",
          transition: "background 0.2s",
          opacity: usernameStatus && !checking && !actionLoading ? 1 : 0.5,
        }}
        disabled={!usernameStatus || checking || actionLoading}
        onClick={async () => {
          if (usernameStatus === "exists") {
            await onLogin();
          } else if (usernameStatus === "not-exists") {
            await onSignup();
          }
        }}
      >
        {checking
          ? "Searching username..."
          : actionLoading
          ? usernameStatus === "exists"
            ? "Logging in..."
            : "Signing up..."
          : usernameStatus === "exists"
          ? "Login"
          : usernameStatus === "not-exists"
          ? "Sign Up"
          : "Continue"}
      </button>
    </div>
  );
};

const PasskeyUsernameStep: React.FC<{
  username: string;
  actionLoading: boolean;
  error: string | null;
  onLogin: () => Promise<void>;
  onSwitchToManual: () => void;
}> = ({ username, actionLoading, error, onLogin, onSwitchToManual }) => {
  const { walletCornerRadius, currentTheme } = useWallet();
  const currentRadius = borderRadiusStyles[walletCornerRadius];
  return (
    <div style={{ width: "100%" }}>
      <label
        style={{
          fontWeight: 600,
          fontSize: 14,
          marginBottom: 6,
          marginLeft: 10,
          display: "block",
        }}
      >
        Continue with your passkey
      </label>

      {/* Pre-selected username row */}
      <div
        style={{
          display: "flex",
          alignItems: "center",
          padding: "12px",
          borderRadius: currentRadius.innerRadius,
          border: `1px solid ${currentTheme.border}`,
          backgroundColor: currentTheme.surface,
          marginBottom: 8,
          gap: 10,
        }}
      >
        <CircleUserRound color={currentTheme.primary} size={24} />
        <span
          style={{
            flex: 1,
            fontSize: 16,
            color: currentTheme.text,
            fontWeight: 500,
          }}
        >
          {username}
        </span>
        <button
          onClick={onSwitchToManual}
          style={{
            background: "none",
            border: "none",
            color: currentTheme.textSecondary,
            fontSize: 12,
            cursor: "pointer",
            padding: "4px 8px",
            borderRadius: 4,
            textDecoration: "underline",
          }}
          disabled={actionLoading}
        >
          Use different username
        </button>
      </div>

      {error && (
        <div
          style={{
            color: currentTheme.errorText,
            fontSize: 14,
            marginBottom: 8,
          }}
        >
          {error}
        </div>
      )}

      <button
        style={{
          marginTop: 8,
          width: "100%",
          background: currentTheme.primary,
          color: "white",
          fontWeight: 600,
          fontSize: 16,
          border: "none",
          borderRadius: currentRadius.innerRadius,
          padding: "16px 0",
          cursor: actionLoading ? "not-allowed" : "pointer",
          boxShadow: "0 2px 8px rgba(70,100,233,0.10)",
          transition: "background 0.2s",
          opacity: actionLoading ? 0.5 : 1,
        }}
        disabled={actionLoading}
        onClick={onLogin}
      >
        {actionLoading ? "Logging in..." : "Continue with passkey"}
      </button>
    </div>
  );
};

// Add CSS styles with theme and borderRadius support
const getStyles = (
  theme: ThemeMode,
  cornerRadius: CornerRadius = "medium",
  themeObject: Theme,
  config: WalletConfig
) => {
  const currentTheme = themeObject;
  const currentRadius = borderRadiusStyles[cornerRadius];
  const fontFamily = config?.fontFamily || "Inter, sans-serif";

  return `
    .modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.5);
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 1001;
      animation: fadeIn 0.3s ease-out;
    }

    .modal-content {
     box-sizing: border-box;
      background-color: ${currentTheme.surface};
      max-height: 95vh;
      overflow-y: auto;
      padding: 28px ;
      border-radius: ${currentRadius.outerRadius}px;
      min-width: 480px;
      max-width: 440px;
      color: ${currentTheme.text};
      box-shadow: 0 4px 24px rgba(0,0,0,0.10);
      position: relative;
      font-family: ${fontFamily} !important;
      animation: slideIn 0.3s ease-out;
      border: 1px solid ${currentTheme.border};
    }
      .modal-content * {
        box-sizing: border-box;
        font-family: ${fontFamily} !important;
      }

    .hide-scrollbar::-webkit-scrollbar {
      display: none;
    }

    @keyframes fadeIn {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }

    @keyframes slideIn {
      from {
        transform: translateY(100%);
      }
      to {
        transform: translateY(0);
      }
    }

    @media (max-width: 768px) {
      .modal-overlay {
        align-items: flex-end;
      }

      .modal-content {
        width: 100%;
        min-width: 100%;
        max-height: 90vh;
        border-radius: ${currentRadius.outerRadius}px ${currentRadius.outerRadius}px 0 0;
        padding: 24px;
        margin: 0;
      }
    }
  `;
};

const WalletModalContent: React.FC<WalletModalProps> = ({
  isOpen,
  onClose,
  walletSDKKey,
  swapParams,
  transferParams,
  showMessagePopup,
  messageType = "success",
  transactionId,
}) => {
  const [step, setStep] = useState<"start" | "passkey-username" | "signup">(
    "start"
  );
  const [username, setUsername] = useState("");
  const [checking, setChecking] = useState(false);
  const [usernameStatus, setUsernameStatus] = useState<
    null | "exists" | "not-exists"
  >(null);
  const [error, setError] = useState<string | null>(null);
  const [actionLoading, setActionLoading] = useState(false);
  const [result, setResult] = useState<any>(null);
  const [balance, setBalance] = useState<any>(null);
  const [showSwap, setShowSwap] = useState(false);
  const [showTransfer, setShowTransfer] = useState(false);
  const debounceRef = useRef<NodeJS.Timeout | null>(null);
  const {
    tokenOptions,
    tokensLoading,
    cryptoBalance,
    loading,
    refreshBalance,
    showActivity,
    setShowActivity,
    activity,
    setLoading,
    refreshTokenOptions,
    theme,
    walletCornerRadius,
    config,
    currentTheme,
  } = useWallet();

  const [combinedBalance, setCombinedBalance] = useState<any>(null);
  const [initialTokensLoading, setInitialTokensLoading] = useState(false);
  const [initialFromToken, setInitialFromToken] = useState<Token | undefined>(
    undefined
  );
  const [initialToToken, setInitialToToken] = useState<Token | undefined>(
    undefined
  );

  // Add transfer-related state
  const [initialTransferToken, setInitialTransferToken] = useState<
    Token | undefined
  >(undefined);
  const [initialTransferAmount, setInitialTransferAmount] =
    useState<string>("");
  const [initialRecipient, setInitialRecipient] = useState<string>("");

  // New state for passkey username flow
  const [savedUsername, setSavedUsername] = useState<string | null>(null);
  const [showManualInput, setShowManualInput] = useState(false);

  const [showMessagePopupState, setShowMessagePopupState] = useState(false);
  const [messageTypeState, setMessageTypeState] = useState<"success" | "error">(
    "success"
  );
  const [transactionIdState, setTransactionIdState] = useState<string | null>(
    null
  );
  const [showActivityState, setShowActivityState] = useState(false);

  // Google authentication state
  const [googleAuthLoading, setGoogleAuthLoading] = useState(false);
  const [xAuthLoading, setXAuthLoading] = useState(false);
  const [googleUser, setGoogleUser] = useState<any>(null);
  const [twitterUser, setTwitterUser] = useState<any>(null);

  const enclave = new Enclave(walletSDKKey);

  const currentRadius = borderRadiusStyles[walletCornerRadius];

  // Add style tag to document head
  useEffect(() => {
    const styleElement = document.createElement("style");
    styleElement.textContent = getStyles(
      theme,
      walletCornerRadius,
      currentTheme,
      config
    );
    document.head.appendChild(styleElement);
    return () => {
      document.head.removeChild(styleElement);
    };
  }, [theme, walletCornerRadius, currentTheme]);

  // Prevent body scroll when modal is open
  useEffect(() => {
    if (isOpen) {
      // Store the original overflow value
      const originalOverflow = document.body.style.overflow;
      // Prevent body scroll
      document.body.style.overflow = "hidden";

      // Restore original overflow when modal closes
      return () => {
        document.body.style.overflow = originalOverflow;
      };
    }
  }, [isOpen]);

  useEffect(() => {
    if (isOpen) {
      // Check for existing session first
      const saved = localStorage.getItem("enclave_wallet_login");
      if (saved) {
        const parsed = JSON.parse(saved);
        setResult(parsed.result);
        setBalance(parsed.balance);
        if (parsed.googleUser) {
          setGoogleUser(parsed.googleUser);
        }
        if (parsed.twitterUser) {
          setTwitterUser(parsed.twitterUser);
        }
        // Trigger immediate balance refresh when modal opens with existing session
        refreshBalance();
        return;
      }

      // Check for previously used username
      const lastUsername = localStorage.getItem("enclave_last_username");
      if (lastUsername) {
        setSavedUsername(lastUsername);
        setUsername(lastUsername);
        setStep("passkey-username");
      } else {
        setStep("start");
      }
    }
  }, [isOpen, swapParams]);

  useEffect(() => {
    if (result) {
      localStorage.setItem(
        "enclave_wallet_login",
        JSON.stringify({ result, balance, googleUser, twitterUser })
      );
      setLoading(true);
    }
  }, [result, balance, googleUser, twitterUser]);

  useEffect(() => {
    if (swapParams) {
      setShowSwap(true);
    }

    if (transferParams) {
      setShowTransfer(true);
      setInitialTransferAmount(transferParams.inputAmount || "");
      setInitialRecipient(transferParams.recipient);
    }

    if (cryptoBalance) {
      setCombinedBalance(cryptoBalance);
    }
  }, [result, swapParams, transferParams, cryptoBalance]);

  useEffect(() => {
    const initializeTokens = async () => {
      setInitialTokensLoading(true);
      if (swapParams) {
        const fromToken = await getInitialFromToken();
        const toToken = await getInitialToToken();
        setInitialFromToken(fromToken);
        setInitialToToken(toToken);
        console.log("initialFromToken", fromToken);
        console.log("initialToToken", toToken);
      }

      if (transferParams) {
        const transferToken = await getInitialTransferToken();
        setInitialTransferToken(transferToken);
        console.log("initialTransferToken", transferToken);
      }

      setInitialTokensLoading(false);
    };
    if ((swapParams || transferParams) && tokenOptions.length > 0) {
      initializeTokens();
    }
  }, [swapParams, transferParams, tokenOptions, walletSDKKey]);

  useEffect(() => {
    if (isOpen) {
      // Check for transaction data in localStorage
      const transactionData = localStorage.getItem("enclave_transaction_data");
      if (transactionData) {
        const data = JSON.parse(transactionData);
        setTransactionIdState(data.transactionId || null);
        // Clear the data after reading
        localStorage.removeItem("enclave_transaction_data");
      }
    }
  }, [isOpen]);

  const handleUsernameChange = (value: string) => {
    setUsername(value);
    setUsernameStatus(null);
    setError(null);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    if (!value) return;
    setChecking(true);
    debounceRef.current = setTimeout(() => {
      checkUserName(value);
    }, 500);
  };

  const checkUserName = async (username: string) => {
    setChecking(true);
    setError(null);
    try {
      const resp = await enclave.checkUserName(username);
      if (resp.value === true) {
        setUsernameStatus("exists");
      } else if (resp.value === false) {
        setUsernameStatus("not-exists");
      } else {
        setUsernameStatus(null);
      }
    } catch (e) {
      setError("Error checking username");
      setUsernameStatus(null);
    } finally {
      setChecking(false);
    }
  };

  const signInAccount = async () => {
    setActionLoading(true);
    setError(null);
    try {
      const resp = await enclave.getPasskeyAccountRegisteredOptions(username);
      let attResp;
      try {
        attResp = await enclave.startPasskeyAccountAuthentication(resp);
      } catch (error) {
        throw error;
      }
      const verificationResp =
        await enclave.submitPasskeyAccountRegisteredResponse({
          username,
          attResp,
        });

      if (verificationResp) {
        if (verificationResp.error) {
          setError(verificationResp.message);
        } else {
          // Get Firebase ID token using the custom token from verification response
          if (verificationResp.token) {
            const firebaseResult = await signInWithCustomTokenAndGetIdToken(
              verificationResp.token
            );

            if (firebaseResult.success && firebaseResult.idToken) {
              // Update the verification response with Firebase ID token and refresh token
              const updatedVerificationResp = {
                ...verificationResp,
                token: firebaseResult.idToken,
                refreshToken: firebaseResult.refreshToken,
              };

              setResult(updatedVerificationResp);
              refreshTokenOptions();

              // Save username for future passkey login
              localStorage.setItem("enclave_last_username", username);

              // Fetch balance after successful login
              const sdkInstance = (window as any).__walletSDKInstance;

              if (sdkInstance) {
                const balanceData = await sdkInstance.getUserCryptoBalance();
                setBalance(balanceData);
                sdkInstance.setUserSession({
                  result: updatedVerificationResp,
                  balance: balanceData,
                });
              }
            } else {
              setError(
                firebaseResult.error || "Failed to get Firebase ID token"
              );
            }
          } else {
            // Fallback to original response if no token
            setResult(verificationResp);
            refreshTokenOptions();

            // Save username for future passkey login
            localStorage.setItem("enclave_last_username", username);

            // Fetch balance after successful login
            const sdkInstance = (window as any).__walletSDKInstance;

            if (sdkInstance) {
              const balanceData = await sdkInstance.getUserCryptoBalance();

              setBalance(balanceData);
              sdkInstance.setUserSession({
                result: verificationResp,
                balance: balanceData,
              });
            }
          }
        }
      } else {
        setError("Login failed");
      }
    } catch (e: any) {
      setError(e.message || "Login failed");
    } finally {
      setActionLoading(false);
    }
  };

  const createAccount = async () => {
    setActionLoading(true);
    setError(null);
    try {
      const resp = await enclave.getPasskeyAccountRegistrationOptions(username);
      let attResp;
      try {
        attResp = await enclave.startPasskeyAccountRegistration(resp);
      } catch (error) {
        throw error;
      }
      const verificationResp =
        await enclave.submitPasskeyAccountRegistrationResponse({
          username,
          attResp,
        });
      if (verificationResp) {
        if (verificationResp.error) {
          setError(verificationResp.message);
        } else {
          // Get Firebase ID token using the custom token from verification response
          if (verificationResp.token) {
            const firebaseResult = await signInWithCustomTokenAndGetIdToken(
              verificationResp.token
            );

            if (firebaseResult.success && firebaseResult.idToken) {
              // Update the verification response with Firebase ID token and refresh token
              const updatedVerificationResp = {
                ...verificationResp,
                token: firebaseResult.idToken,
                refreshToken: firebaseResult.refreshToken,
              };

              setResult(updatedVerificationResp);
              refreshTokenOptions();

              // Save username for future passkey login
              localStorage.setItem("enclave_last_username", username);

              // Fetch balance after successful signup
              const sdkInstance = (window as any).__walletSDKInstance;
              if (sdkInstance) {
                const balanceData = await sdkInstance.getUserCryptoBalance();
                setBalance(balanceData);
                sdkInstance.setUserSession({
                  result: updatedVerificationResp,
                  balance: balanceData,
                });
              }
            } else {
              setError(
                firebaseResult.error || "Failed to get Firebase ID token"
              );
            }
          } else {
            // Fallback to original response if no token
            setResult(verificationResp);
            refreshTokenOptions();

            // Save username for future passkey login
            localStorage.setItem("enclave_last_username", username);

            // Fetch balance after successful signup
            const sdkInstance = (window as any).__walletSDKInstance;
            if (sdkInstance) {
              const balanceData = await sdkInstance.getUserCryptoBalance();

              setBalance(balanceData);
              sdkInstance.setUserSession({
                result: verificationResp,
                balance: balanceData,
              });
            }
          }
        }
      } else {
        setError("Signup failed");
      }
    } catch (e: any) {
      setError(e.message || "Signup failed");
    } finally {
      setActionLoading(false);
    }
  };

  const handleLogout = async () => {
    // Sign out from Google if logged in via Google
    if (googleUser) {
      try {
        const { signOutUser } = await import("../services/firebase-auth");
        await signOutUser();
        setGoogleUser(null);
      } catch (error) {
        console.error("Error signing out from Google:", error);
      }
    }

    setResult(null);
    setUsername("");
    setUsernameStatus(null);
    setError(null);
    setStep("start");
    localStorage.removeItem("enclave_wallet_login");
    localStorage.removeItem("enclave_last_username"); // Clear saved username
    onClose();
  };

  // Handler for passkey username login
  const handlePasskeyLogin = async () => {
    if (savedUsername) {
      await signInAccount();
    }
  };

  // Handler to switch to manual username input
  const handleSwitchToManual = () => {
    setShowManualInput(true);
    setStep("signup");
    setUsername("");
    setUsernameStatus(null);
    setError(null);
  };

  // Handler for Google login
  const handleGoogleLogin = async () => {
    setGoogleAuthLoading(true);
    setError(null);

    try {
      const result: GoogleAuthResult = await signInWithGoogle(walletSDKKey);

      if (result.success && result.user) {
        setGoogleUser(result.user);
        // console.log("Social account result:", result);

        // Use the social account response directly
        const googleResult = {
          username: result.user.socialLoginDetails.googleUser?.email, // Store email as username in localStorage
          email: result.user.socialLoginDetails.googleUser?.email,
          displayName: result.user.socialLoginDetails.googleUser?.displayName,
          photoURL: result.user.socialLoginDetails.googleUser?.photoURL,
          uid: result.user.socialLoginDetails.googleUser?.uid,
          authMethod: "google",
          wallet: result.user.wallet,
          verified: result.user.verified,
          socialLoginDetails: result.user.socialLoginDetails,
          _id: result.user._id,
          // @ts-ignore
          token: result.user.accessToken,
          // @ts-ignore
          refreshToken: result.user.refreshToken,
        };

        setResult(googleResult);
        refreshTokenOptions();

        // Fetch balance after successful Google login
        const sdkInstance = (window as any).__walletSDKInstance;
        if (sdkInstance) {
          const balanceData = await sdkInstance.getUserCryptoBalance();

          setBalance(balanceData);
          sdkInstance.setUserSession({
            result: googleResult,
            balance: balanceData,
          });
        }
      } else {
        setError(result.error || "Google login failed");
      }
    } catch (error: any) {
      console.error("Google login error:", error);
      setError(error.message || "Google login failed");
    } finally {
      setGoogleAuthLoading(false);
    }
  };

  // Handler for X (Twitter) login
  const handleXLogin = async () => {
    setXAuthLoading(true);
    setError(null);
    try {
      const result: TwitterAuthResult = await signInWithX(walletSDKKey);
      if (result.success && result.user) {
        console.log("result", result);

        setTwitterUser(result.user); // You may want a separate state for X user if needed
        // Use the social account response directly
        const socialLoginDetails = result.user.socialLoginDetails || {};
        const twitterUser: any = socialLoginDetails.twitterUser || {};
        const xResult = {
          username: result?.user?.username,
          email: twitterUser.email,
          displayName: twitterUser.username,
          photoURL: twitterUser.profile_image_url,
          uid: twitterUser.uid,
          authMethod: "twitter",
          wallet: result.user.wallet,
          verified: result.user.verified,
          socialLoginDetails: result.user.socialLoginDetails,
          _id: result.user._id,
          // @ts-ignore
          token: result.user.accessToken,
          // @ts-ignore
          refreshToken: result.user.refreshToken,
        };
        setResult(xResult);
        refreshTokenOptions();
        // Fetch balance after successful X login
        const sdkInstance = (window as any).__walletSDKInstance;
        if (sdkInstance) {
          const balanceData = await sdkInstance.getUserCryptoBalance();

          setBalance(balanceData);
          sdkInstance.setUserSession({
            result: xResult,
            balance: balanceData,
          });
        }
      } else {
        setError(result.error || "X login failed");
      }
    } catch (error: any) {
      console.error("X login error:", error);
      setError(error.message || "X login failed");
    } finally {
      setXAuthLoading(false);
    }
  };

  const getMatchingTokenFromCryptoBalance = (
    tokenAddress: string,
    chainId: number
  ) => {
    return cryptoBalance?.data.find((token: any) =>
      token.chainIds.some(
        (chain: any) =>
          chain.address.toLowerCase() === tokenAddress.toLowerCase() &&
          chain.chainId === chainId
      )
    );
  };

  const formatTokenForSwap = (
    matchingToken: any,
    chainId: number
  ): Token | undefined => {
    if (!matchingToken) return undefined;

    const matchingChain = matchingToken.chainIds.find(
      (chain: any) => chain.chainId === chainId
    );

    if (!matchingChain) return undefined;

    return {
      symbol: matchingToken.symbol,
      name: matchingToken.name,
      icon: matchingToken.logoURI,
      address: matchingChain.address,
      chainId: matchingChain.chainId,
      chainIds: matchingToken.chainIds,
      decimals: matchingToken.decimals,
      balance: matchingChain.balance,
      amount: matchingToken.amount?.toString(),
    };
  };

  const getInitialFromToken = async (): Promise<any | undefined> => {
    if (!swapParams?.fromToken || !tokenOptions.length) return undefined;

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

    if (!matchingToken || !matchingToken.chainIds) {
      if (swapParams.fromToken.metadata) {
        matchingToken = {
          address: swapParams.fromToken.tokenAddress,
          symbol: swapParams.fromToken.metadata.tokenSymbol,
          name: swapParams.fromToken.metadata.tokenName,
          logoURI: swapParams.fromToken.metadata.logoURI,
          chainIds: swapParams.fromToken.metadata.chainIds.map((chain) => ({
            chainId: chain.chainId,
            address: chain.address,
          })),
          decimals: swapParams.fromToken.metadata.decimals,
          chainId: swapParams.fromToken.metadata.chainIds[0].chainId,
        };
      } else {
        const searchTokenResponse = await searchToken(
          swapParams.fromToken.tokenAddress,
          swapParams.fromToken.chainId,
          walletSDKKey
        );
        if (searchTokenResponse?.success && searchTokenResponse.data) {
          matchingToken = {
            address: searchTokenResponse.data.chainIds[0].address,
            symbol: searchTokenResponse.data.symbol,
            name: searchTokenResponse.data.name,
            logoURI: searchTokenResponse.data.logoURI,
            chainIds: searchTokenResponse.data.chainIds.map((chain) => ({
              chainId: parseInt(chain.chainId),
              address: chain.address,
            })),
            decimals: searchTokenResponse.data.decimals,
            chainId: parseInt(searchTokenResponse.data.chainIds[0].chainId),
          };
        }
      }

      if (!matchingToken) return undefined;

      return {
        symbol: matchingToken.symbol,
        name: matchingToken.name,
        icon: matchingToken.logoURI || matchingToken.icon || "",
        address: matchingToken.address,
        chainId: matchingToken.chainId,
        chainIds: matchingToken.chainIds,
        decimals: matchingToken.decimals,
        balance: matchingToken.balance || "0",
        amount: matchingToken.amount?.toString() || "0",
        priceUsd: matchingToken.price || 0,
      };
    }

    const matchingChain = matchingToken.chainIds?.find(
      (chain) => chain.chainId === swapParams.fromToken.chainId
    );

    if (!matchingChain) return undefined;

    return {
      symbol: matchingToken.symbol,
      name: matchingToken.name,
      icon: matchingToken.logoURI || matchingToken.icon || "",
      address: matchingChain.address,
      chainId: matchingChain.chainId,
      chainIds: matchingToken.chainIds,
      decimals: matchingToken.decimals,
      balance: matchingToken.balance || "0",
      amount: matchingToken.amount?.toString() || "0",
      priceUsd: matchingToken.price || 0,
    };
  };

  const getInitialToToken = async (): Promise<any | undefined> => {
    if (!swapParams?.toToken || !tokenOptions.length) return undefined;

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

    if (!matchingToken || !matchingToken.chainIds) {
      if (swapParams.toToken.metadata) {
        matchingToken = {
          address: swapParams.toToken.tokenAddress,
          symbol: swapParams.toToken.metadata.tokenSymbol,
          name: swapParams.toToken.metadata.tokenName,
          logoURI: swapParams.toToken.metadata.logoURI,
          chainIds: swapParams.toToken.metadata.chainIds.map((chain) => ({
            chainId: chain.chainId,
            address: chain.address,
          })),
          decimals: swapParams.toToken.metadata.decimals,
          chainId: swapParams.toToken.metadata.chainIds[0].chainId,
        };
      } else {
        const searchTokenResponse = await searchToken(
          swapParams.toToken.tokenAddress,
          swapParams.toToken.chainId,
          walletSDKKey
        );
        if (searchTokenResponse?.success && searchTokenResponse.data) {
          matchingToken = {
            address: searchTokenResponse.data.chainIds[0].address,
            symbol: searchTokenResponse.data.symbol,
            name: searchTokenResponse.data.name,
            logoURI: searchTokenResponse.data.logoURI,
            chainIds: searchTokenResponse.data.chainIds.map((chain) => ({
              chainId: parseInt(chain.chainId),
              address: chain.address,
            })),
            decimals: searchTokenResponse.data.decimals,
            chainId: parseInt(searchTokenResponse.data.chainIds[0].chainId),
          };
        }
      }
      if (!matchingToken) return undefined;

      return {
        symbol: matchingToken.symbol,
        name: matchingToken.name,
        icon: matchingToken.logoURI || matchingToken.icon || "",
        address: matchingToken.address,
        chainId: matchingToken.chainId,
        chainIds: matchingToken.chainIds,
        decimals: matchingToken.decimals,
        balance: matchingToken.balance || "0",
        amount: matchingToken.amount?.toString() || "0",
        priceUsd: matchingToken.price || 0,
      };
    }

    const matchingChain = matchingToken.chainIds?.find(
      (chain) => chain.chainId === swapParams.toToken.chainId
    );

    if (!matchingChain) return undefined;

    return {
      symbol: matchingToken.symbol,
      name: matchingToken.name,
      icon: matchingToken.logoURI || matchingToken.icon || "",
      address: matchingChain.address,
      chainId: matchingChain.chainId,
      chainIds: matchingToken.chainIds,
      decimals: matchingToken.decimals,
      balance: matchingToken.balance || "0",
      amount: matchingToken.amount?.toString() || "0",
      priceUsd: matchingToken.price || 0,
    };
  };

  const getInitialTransferToken = async (): Promise<Token | undefined> => {
    if (!transferParams) return undefined;

    const { inputToken } = transferParams;

    // Find matching token from tokenOptions
    let matchingToken: any;

    // If not found in tokenOptions, try to find in cryptoBalance
    if (!matchingToken && cryptoBalance?.data) {
      matchingToken = cryptoBalance.data.find((token: any) =>
        token.chainIds?.some(
          (chain: any) =>
            chain.address.toLowerCase() === inputToken.address.toLowerCase() &&
            chain.chainId === inputToken.chainId
        )
      );
    }

    if (!matchingToken) {
      // If still not found, use the provided input token data
      return {
        symbol: inputToken.symbol || "",
        name: inputToken.name || "",
        icon: inputToken.logoURI || "",
        address: inputToken.address,
        chainId: inputToken.chainId,
        chainIds: inputToken.chainIds
          ? inputToken.chainIds.map((chain) => ({
              ...chain,
              balance: inputToken.balance || "0",
            }))
          : [
              {
                chainId: inputToken.chainId,
                address: inputToken.address,
                balance: inputToken.balance || "0",
              },
            ],
        decimals: inputToken.decimals || 0,
        balance: inputToken.balance || "0",
        amount: "0",
        priceUsd: 0,
      };
    }

    // Find the matching chain for the input token
    const matchingChain = matchingToken.chainIds?.find(
      (chain: any) => chain.chainId === inputToken.chainId
    );

    if (!matchingChain) {
      // If no exact chain match, use the provided input token data
      return {
        symbol: inputToken.symbol || "",
        name: inputToken.name || "",
        icon: inputToken.logoURI || "",
        address: inputToken.address,
        chainId: inputToken.chainId,
        chainIds: inputToken.chainIds
          ? inputToken.chainIds.map((chain) => ({
              ...chain,
              balance: inputToken.balance || "0",
            }))
          : [
              {
                chainId: inputToken.chainId,
                address: inputToken.address,
                balance: inputToken.balance || "0",
              },
            ],
        decimals: inputToken.decimals || 0,
        balance: inputToken.balance || "0",
        amount: "0",
        priceUsd: 0,
      };
    }

    return {
      symbol: matchingToken.symbol,
      name: matchingToken.name,
      icon: matchingToken.logoURI || matchingToken.icon || "",
      address: matchingChain.address,
      chainId: matchingChain.chainId,
      chainIds: matchingToken.chainIds || [],
      decimals: matchingToken.decimals,
      balance: (matchingChain as any).balance || matchingToken.balance || "0",
      amount: matchingToken.amount?.toString() || "0",
      priceUsd: matchingToken.price || matchingToken.priceUsd || 0,
    };
  };

  if (!isOpen) return null;

  return (
    <div className="modal-overlay" onClick={onClose}>
      <motion.div
        className="modal-content hide-scrollbar"
        onClick={(e) => e.stopPropagation()}
        layout
        initial={{ opacity: 0, y: 100 }}
        animate={{ opacity: 1, y: 0 }}
        exit={{ opacity: 0, y: 100 }}
      >
        <AnimatePresence mode="wait">
          {transactionIdState ? (
            <motion.div
              key="activity-details"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1, height: "auto" }}
              transition={{ duration: 0.3, ease: "easeInOut" }}
            >
              <ActivityDetails
                theme={theme}
                activityId={transactionIdState}
                apiKey={walletSDKKey}
                onBack={() => {
                  setShowActivityState(false);
                  setTransactionIdState(null);
                }}
              />
            </motion.div>
          ) : (
            <motion.div
              key="main-content"
              initial={{ opacity: 0, height: "auto" }}
              animate={{ opacity: 1, height: "auto" }}
              transition={{ duration: 0.2, ease: "easeInOut" }}
            >
              <>
                {step === "signup" && !result && (
                  <div style={{ position: "relative" }}>
                    <ArrowLeftIcon
                      style={{
                        cursor: "pointer",
                        color: currentTheme.text,
                        width: 24,
                        height: 24,
                        position: "absolute",
                        top: 16,
                        left: 0,
                      }}
                      onClick={() => {
                        setStep("start");
                      }}
                    />
                  </div>
                )}
                {config?.brandLogo && (
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "center",
                      marginBottom: 12,
                    }}
                  >
                    <img
                      src={config?.brandLogo}
                      alt="Brand Logo"
                      style={{ height: 30, objectFit: "contain" }}
                    />
                  </div>
                )}
                {!result && (
                  <div>
                    {/* Logo */}

                    {!config?.brandLogo && (
                      <div
                        style={{
                          display: "flex",
                          justifyContent: "center",
                          marginBottom: 16,
                        }}
                      >
                        <img
                          src={
                            theme === "dark"
                              ? "https://storage.googleapis.com/enclave_assets/enclave_white.png"
                              : "https://storage.googleapis.com/enclave_assets/enclave_black.png"
                          }
                          alt="Enclave Logo"
                          style={{ height: 48, objectFit: "contain" }}
                        />
                      </div>
                    )}
                    {/* Close button */}
                    <button
                      onClick={onClose}
                      style={{
                        position: "absolute",
                        top: 18,
                        right: 18,
                        background: "none",
                        border: "none",
                        fontSize: 22,
                        cursor: "pointer",
                        color: "#888",
                      }}
                      aria-label="Close"
                    >
                      ×
                    </button>
                  </div>
                )}
                {/* Title */}
                {!result && (
                  <h2
                    style={{
                      fontSize: 26,
                      fontWeight: 700,
                      margin: 0,
                      textAlign: "center",
                      color: currentTheme.text,
                    }}
                  >
                    {"Log In or Sign Up"}
                  </h2>
                )}
                {/* Subtitle */}
                {!result && (
                  <p
                    style={{
                      color: currentTheme.textSecondary,
                      fontSize: 16,
                      margin: "10px 0 24px 0",
                      textAlign: "center",
                    }}
                  >
                    {"Sign into your wallet with one click"}
                  </p>
                )}
                {/* Card */}

                {!result && (
                  <>
                    {step === "start" ||
                    (step === "passkey-username" && savedUsername) ? (
                      config?.authentication?.social &&
                      config?.authentication?.social.length > 0 ? (
                        <div
                          style={{
                            width: "100%",
                            padding: "0 16px",
                            display: "flex",
                            flexDirection: "column",
                            alignItems: "center",
                            marginBottom: 24,
                            gap: 16,
                          }}
                        >
                          {config?.authentication?.social.includes(
                            "google"
                          ) && (
                            <button
                              style={{
                                marginTop: 0,
                                width: "100%",
                                background: googleAuthLoading
                                  ? currentTheme.surfaceActive
                                  : currentTheme.surface,
                                color: googleAuthLoading
                                  ? currentTheme.textSecondary
                                  : currentTheme.text,
                                fontWeight: 600,
                                fontSize: 18,
                                borderRadius: currentRadius.innerRadius,
                                padding: "16px 0",
                                cursor: googleAuthLoading
                                  ? "not-allowed"
                                  : "pointer",
                                transition: "background 0.2s",
                                display: "flex",
                                alignItems: "center",
                                justifyContent: "center",
                                border: `1px solid ${currentTheme.border}`,
                                gap: 10,
                              }}
                              onClick={handleGoogleLogin}
                              disabled={googleAuthLoading}
                            >
                              {googleAuthLoading ? (
                                <Spinner theme={theme} />
                              ) : (
                                <img
                                  src="https://storage.googleapis.com/enclave_assets/google.svg"
                                  alt="Google Logo"
                                  style={{ width: 24 }}
                                />
                              )}
                              {googleAuthLoading
                                ? "Signing in..."
                                : "Continue with Google"}
                            </button>
                          )}

                          {config?.authentication?.social.includes(
                            "twitter"
                          ) && (
                            <button
                              style={{
                                marginTop: 0,
                                width: "100%",
                                background: xAuthLoading
                                  ? currentTheme.surfaceActive
                                  : currentTheme.surface,
                                color: xAuthLoading
                                  ? currentTheme.textSecondary
                                  : currentTheme.text,
                                fontWeight: 600,
                                fontSize: 18,
                                borderRadius: currentRadius.innerRadius,
                                padding: "16px 0",
                                cursor: xAuthLoading
                                  ? "not-allowed"
                                  : "pointer",
                                transition: "background 0.2s",
                                display: "flex",
                                alignItems: "center",
                                justifyContent: "center",
                                border: `1px solid ${currentTheme.border}`,
                                gap: 10,
                              }}
                              onClick={handleXLogin}
                              disabled={xAuthLoading}
                            >
                              {xAuthLoading ? (
                                <Spinner theme={theme} />
                              ) : (
                                <img
                                  src="https://storage.googleapis.com/enclave_assets/new-2023-twitter-logo-x-icon-design_1017-45418.avif"
                                  alt="x Logo"
                                  style={{ width: 24, borderRadius: 6 }}
                                />
                              )}
                              {xAuthLoading
                                ? "Signing in..."
                                : "Continue with X"}
                            </button>
                          )}
                        </div>
                      ) : null
                    ) : null}

                    {config?.authentication?.passkey && (
                      <div
                        style={{
                          background:
                            theme === "dark"
                              ? currentTheme.surfaceHover
                              : "#F6F8FE",
                          borderRadius: currentRadius.outerRadius,
                          padding: "24px 16px 20px 16px",
                          flexDirection: "column",
                          alignItems: "center",
                          marginBottom: 24,
                          display: showSwap ? "none" : "flex",
                          border: `1px solid ${currentTheme.border}`,
                        }}
                      >
                        {step === "start" && !result && (
                          <StartStep
                            onNext={() => {
                              // Check for previously used username first
                              const lastUsername = localStorage.getItem(
                                "enclave_last_username"
                              );
                              if (lastUsername) {
                                setSavedUsername(lastUsername);
                                setUsername(lastUsername);
                                setStep("passkey-username");
                              } else {
                                setStep("signup");
                              }
                            }}
                          />
                        )}
                        {step === "passkey-username" &&
                          !result &&
                          savedUsername && (
                            <PasskeyUsernameStep
                              username={savedUsername}
                              actionLoading={actionLoading}
                              error={error}
                              onLogin={handlePasskeyLogin}
                              onSwitchToManual={handleSwitchToManual}
                            />
                          )}
                        {step === "signup" && !result && (
                          <SignupStep
                            username={username}
                            onUsernameChange={handleUsernameChange}
                            usernameStatus={usernameStatus}
                            checking={checking}
                            error={error}
                            actionLoading={actionLoading}
                            onLogin={signInAccount}
                            onSignup={createAccount}
                          />
                        )}
                      </div>
                    )}
                  </>
                )}

                <AnimatePresence mode="wait">
                  {showSwap && !showTransfer && (
                    <motion.div
                      key="swap"
                      initial={{ opacity: 0, height: 550 }}
                      exit={{ opacity: 0, height: 550 }}
                      animate={{ opacity: 1, height: "auto" }}
                      transition={{ duration: 0.2, ease: "easeInOut" }}
                    >
                      <SwapToken
                        onBack={() => {
                          setShowSwap(false);
                          if (swapParams) {
                            onClose();
                          }
                        }}
                        walletSDKKey={walletSDKKey}
                        combinedBalance={combinedBalance}
                        initialFromToken={initialFromToken}
                        initialToToken={initialToToken}
                        initialAmount={swapParams?.fromToken?.amount || ""}
                        tokenOptions={tokenOptions}
                        tokensLoading={
                          tokensLoading ||
                          !combinedBalance ||
                          initialTokensLoading
                        }
                        theme={theme}
                      />
                    </motion.div>
                  )}
                  {showTransfer && (
                    <motion.div
                      key="transfer"
                      initial={{ opacity: 0, height: 550 }}
                      animate={{ opacity: 1, height: "auto" }}
                      transition={{ duration: 0.2, ease: "easeInOut" }}
                    >
                      <TransferToken
                        onBack={() => {
                          setShowTransfer(false);
                          if (transferParams) {
                            onClose();
                          }
                        }}
                        onClose={() => setShowTransfer(false)}
                        walletSdkKey={walletSDKKey}
                        username={result?.username || ""}
                        theme={theme}
                        initialToken={initialTransferToken}
                        initialAmount={initialTransferAmount}
                        initialRecipient={initialRecipient}
                      />
                    </motion.div>
                  )}
                  {result &&
                    !showSwap &&
                    !swapParams &&
                    !showTransfer &&
                    !showActivity && (
                      <motion.div
                        key="dashboard"
                        initial={{ opacity: 0, height: 550 }}
                        animate={{ opacity: 1, height: "auto" }}
                        transition={{ duration: 0.2, ease: "easeInOut" }}
                      >
                        <Dashboard
                          result={result}
                          onLogout={handleLogout}
                          onShowSwap={() => setShowSwap(true)}
                          onShowTransfer={() => setShowTransfer(true)}
                          sdkKey={walletSDKKey}
                          theme={theme}
                        />
                      </motion.div>
                    )}

                  {showActivity && (
                    <motion.div
                      key="activity"
                      initial={{ opacity: 0, height: 550 }}
                      exit={{ opacity: 0, height: 550 }}
                      animate={{ opacity: 1, height: "auto" }}
                      transition={{ duration: 0.2, ease: "easeInOut" }}
                    >
                      <ActivityDetails
                        apiKey={walletSDKKey}
                        onBack={() => setShowActivity(false)}
                        activity={activity}
                        theme={theme}
                      />
                    </motion.div>
                  )}
                </AnimatePresence>
                {config?.showEnclave && (
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "center",
                      alignItems: "center",
                      gap: 8,
                      marginTop: 16,
                    }}
                  >
                    <span
                      style={{
                        fontSize: 12,
                        color: currentTheme.textSecondary,
                      }}
                    >
                      Secured by
                    </span>
                    <img
                      src="https://storage.googleapis.com/enclave_assets/LogoEnclaveGray.png"
                      alt="Enclave text Logo"
                      style={{ width: 84 }}
                    />
                  </div>
                )}
              </>
            </motion.div>
          )}
        </AnimatePresence>
      </motion.div>
    </div>
  );
};

export const WalletModal: React.FC<WalletModalProps> = (props) => {
  const config = {
    sdkKey: props.walletSDKKey,
    appearance: (props.theme === "dark" ? "dark" : "light") as "light" | "dark",
    cornerRadius: (props.cornerRadius === "small"
      ? "S"
      : props.cornerRadius === "large"
      ? "L"
      : "M") as "S" | "M" | "L",
    primaryColor: props.config?.primaryColor || "#3662E3", // Use primaryColor from config or default
    brandLogo: props.config?.brandLogo,
    authentication: props.config?.authentication,
    fontFamily: props.config?.fontFamily,
    showEnclave: props.config?.showEnclave,
  };

  console.log(props);

  return (
    <WalletProvider config={config}>
      <WalletModalContent {...props} />
    </WalletProvider>
  );
};
