import React, { useState, useRef, useEffect } from "react";
import { Enclave } from "enclavemoney-web-experimental";
import { formatUnits } from "ethers";
import { SwapToken } from "./SwapToken";
import { Dashboard } from "./Dashboard";
import TransferToken from "./Transfer/TransferToken";
import {
  CryptoBalanceProvider,
  useCryptoBalance,
} from "../context/CryptoBalanceContext";
import Activity from "./Activity";
import ActivityDetails from "./ActivityDetails";

interface swapToken {
  amount: string;
  chainId: number;
  tokenAddress: string;
}

interface SwapParams {
  fromToken: swapToken;
  toToken: Omit<swapToken, "amount">;
}

interface Token {
  symbol: string;
  name: string;
  icon: string;
  address: string;
  chainId: number;
  decimals: number;
  balance: string;
  amount?: string;
  chainIds: any;
}

interface WalletModalProps {
  isOpen: boolean;
  onClose: () => void;
  walletSDKKey: string;
  swapParams?: SwapParams;
}

const enclaveLogo =
  "https://firebasestorage.googleapis.com/v0/b/enclave-wallet.appspot.com/o/enclave_black.png?alt=media&token=6e32e0d1-4ef5-44a5-9ba6-339852ba0359";

const StartStep: React.FC<{ onNext: () => void }> = ({ onNext }) => (
  <>
    <div style={{ fontSize: 36, marginBottom: 10 }}>
      <img
        src="https://firebasestorage.googleapis.com/v0/b/enclave-wallet.appspot.com/o/wallet-sdk%2FpassKey.png?alt=media&token=00244583-8acf-4805-9fb3-c0fd9f103cfa"
        alt="passkey Logo"
        style={{ width: 84 }}
      />
    </div>
    <div
      style={{
        color: "#4B5563",
        fontSize: 17,
        textAlign: "center",
        marginBottom: 10,
      }}
    >
      Authenticate securely using your device's passkey
    </div>
    <button
      style={{
        marginTop: 10,
        width: "100%",
        background: "#3662E3",
        color: "white",
        fontWeight: 600,
        fontSize: 18,
        border: "none",
        borderRadius: 10,
        padding: "14px 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,
}) => (
  <div style={{ width: "100%" }}>
    <label
      style={{
        fontWeight: 600,
        fontSize: 14,
        marginBottom: 6,

        display: "block",
      }}
    >
      Choose a username
    </label>
    <input
      type="text"
      value={username}
      onChange={(e) => onUsernameChange(e.target.value)}
      placeholder="Enter username"
      style={{
        width: "100%",
        padding: "10px",
        borderRadius: 8,
        border: "1px solid #ccc",
        fontSize: 16,
        marginBottom: 8,
      }}
      disabled={actionLoading}
    />
    {checking && (
      <div style={{ color: "#888", fontSize: 14 }}>Searching username...</div>
    )}
    {usernameStatus === "exists" && (
      <div style={{ color: "green", fontSize: 14 }}>
        Username found. You can log in.
      </div>
    )}
    {usernameStatus === "not-exists" && (
      <div style={{ color: "blue", fontSize: 14 }}>
        Username is available. You can sign up.
      </div>
    )}
    {error && <div style={{ color: "red", fontSize: 14 }}>{error}</div>}
    <button
      style={{
        marginTop: 16,
        width: "100%",
        background: usernameStatus && !checking ? "#4664E9" : "#bfc8e6",
        color: "white",
        fontWeight: 600,
        fontSize: 16,
        border: "none",
        borderRadius: 10,
        padding: "14px 0",
        cursor: usernameStatus && !checking ? "pointer" : "not-allowed",
        boxShadow: "0 2px 8px rgba(70,100,233,0.10)",
        transition: "background 0.2s",
      }}
      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 WalletModalContent: React.FC<WalletModalProps> = ({
  isOpen,
  onClose,
  walletSDKKey,
  swapParams,
}) => {
  const [step, setStep] = useState<"start" | "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 { cryptoBalance, refreshBalance } = useCryptoBalance();
  const [combinedBalance, setCombinedBalance] = useState<any>(null);
  const { showActivity, setShowActivity, activity, setActivity, setLoading } =
    useCryptoBalance();

  const enclave = new Enclave(walletSDKKey);

  useEffect(() => {
    if (isOpen) {
      const saved = localStorage.getItem("enclave_wallet_login");
      if (saved) {
        const parsed = JSON.parse(saved);
        setResult(parsed.result);
        setBalance(parsed.balance);
        // Trigger immediate balance refresh when modal opens with existing session
        refreshBalance();
      }
    }
  }, [isOpen, swapParams]);

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

  useEffect(() => {
    if (swapParams) {
      setShowSwap(true);
    }
    if (result && swapParams && cryptoBalance) {
      setCombinedBalance({
        data: [
          // Only add fromToken if it doesn't exist in cryptoBalance
          ...(cryptoBalance.data.some((token: any) =>
            token.chainIds.some(
              (chain: any) =>
                chain.address.toLowerCase() ===
                  swapParams.fromToken.tokenAddress.toLowerCase() &&
                chain.chainId === swapParams.fromToken.chainId
            )
          )
            ? []
            : [swapParams.fromToken]),
          // Only add toToken if it doesn't exist in cryptoBalance
          ...(cryptoBalance.data.some((token: any) =>
            token.chainIds.some(
              (chain: any) =>
                chain.address.toLowerCase() ===
                  swapParams.toToken.tokenAddress.toLowerCase() &&
                chain.chainId === swapParams.toToken.chainId
            )
          )
            ? []
            : [swapParams.toToken]),
          ...cryptoBalance.data,
        ],
      });
    }
    if (!swapParams && cryptoBalance) {
      setCombinedBalance(cryptoBalance);
    }
  }, [result, swapParams, cryptoBalance]);

  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 {
          setResult(verificationResp);

          // 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 {
          setResult(verificationResp);

          // 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 = () => {
    setResult(null);
    setUsername("");
    setUsernameStatus(null);
    setError(null);
    setStep("start");
    localStorage.removeItem("enclave_wallet_login");
  };

  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 = (): Token | undefined => {
    if (!swapParams?.fromToken) return undefined;
    const matchingToken = getMatchingTokenFromCryptoBalance(
      swapParams.fromToken.tokenAddress,
      swapParams.fromToken.chainId
    );
    return formatTokenForSwap(matchingToken, swapParams.fromToken.chainId);
  };

  const getInitialToToken = (): Token | undefined => {
    if (!swapParams?.toToken) return undefined;
    const matchingToken = getMatchingTokenFromCryptoBalance(
      swapParams.toToken.tokenAddress,
      swapParams.toToken.chainId
    );
    console.log(
      matchingToken,
      "matchingToken",
      swapParams.toToken,
      cryptoBalance,
      "cryptoBalance"
    );
    return formatTokenForSwap(matchingToken, swapParams.toToken.chainId);
  };

  if (!isOpen) return null;

  return (
    <div
      style={{
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: "rgba(0, 0, 0, 0.5)",
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
        zIndex: 1000,
      }}
      onClick={onClose}
    >
      <div
        style={{
          backgroundColor: "white",
          maxHeight: "95vh",
          overflowY: "auto",
          padding: "32px 24px 24px 24px",
          borderRadius: "20px",
          minWidth: "440px",
          color: "#222",
          boxShadow: "0 4px 24px rgba(0,0,0,0.10)",
          position: "relative",
          fontFamily: "Inter, sans-serif",
        }}
        onClick={(e) => e.stopPropagation()}
      >
        {!result && (
          <div>
            {/* Logo */}
            <div
              style={{
                display: "flex",
                justifyContent: "center",
                marginBottom: 16,
              }}
            >
              <img
                src={enclaveLogo}
                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",
            }}
          >
            {"Log In or Sign Up"}
          </h2>
        )}
        {/* Subtitle */}
        {!result && (
          <p
            style={{
              color: "#6B7280",
              fontSize: 16,
              margin: "10px 0 24px 0",
              textAlign: "center",
            }}
          >
            {"Sign into your wallet with one click"}
          </p>
        )}
        {/* Card */}

        {!result && (
          <div
            style={{
              background: "#F6F8FE",
              borderRadius: 16,
              padding: "24px 16px 20px 16px",
              flexDirection: "column",
              alignItems: "center",
              marginBottom: 24,
              display: showSwap ? "none" : "flex",
            }}
          >
            {step === "start" && !result && (
              <StartStep onNext={() => setStep("signup")} />
            )}
            {step === "signup" && !result && (
              <SignupStep
                username={username}
                onUsernameChange={handleUsernameChange}
                usernameStatus={usernameStatus}
                checking={checking}
                error={error}
                actionLoading={actionLoading}
                onLogin={signInAccount}
                onSignup={createAccount}
              />
            )}
          </div>
        )}

        {showSwap && !showTransfer && (
          <SwapToken
            onBack={() => {
              setShowSwap(false);
              if (swapParams) {
                onClose();
              }
            }}
            walletSDKKey={walletSDKKey}
            combinedBalance={combinedBalance}
            initialFromToken={cryptoBalance && getInitialFromToken()}
            initialToToken={cryptoBalance && getInitialToToken()}
            initialAmount={swapParams?.fromToken?.amount || ""}
          />
        )}
        {showTransfer && (
          <TransferToken
            onBack={() => setShowTransfer(false)}
            onClose={() => setShowTransfer(false)}
            walletSdkKey={walletSDKKey}
            username={result?.username || ""}
          />
        )}
        {result &&
          !showSwap &&
          !swapParams &&
          !showTransfer &&
          !showActivity && (
            <Dashboard
              result={result}
              onLogout={handleLogout}
              onShowSwap={() => setShowSwap(true)}
              onShowTransfer={() => setShowTransfer(true)}
              sdkKey={walletSDKKey}
            />
          )}

        {showActivity && (
          <ActivityDetails
            onBack={() => setShowActivity(false)}
            activity={activity}
          />
        )}

        <div
          style={{
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            gap: 8,
          }}
        >
          <span style={{ fontSize: 12, color: "#B4B4B6" }}>Secured by</span>
          <img
            src="https://firebasestorage.googleapis.com/v0/b/enclave-wallet.appspot.com/o/wallet-sdk%2FLogoNameGray.png?alt=media&token=10a251a9-3dc9-441f-bf41-d4e60704cc33"
            alt="Enclave text Logo"
            style={{ width: 84 }}
          />
        </div>
      </div>
    </div>
  );
};

export const WalletModal: React.FC<WalletModalProps> = (props) => {
  return (
    <CryptoBalanceProvider walletSDKKey={props.walletSDKKey}>
      <WalletModalContent {...props} />
    </CryptoBalanceProvider>
  );
};
