import React, { createContext, useContext, useEffect, useState } from "react";
import WalletSDK from "../index";
import { SwapToken } from "./SwapToken";

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

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

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

interface WalletContextType {
  walletSDK: WalletSDK | null;
  isLoggedIn: boolean;
  username: string | null;
  walletAddress: string | null;
  solanaAddress: string | null;
  balance: any | null;
  connect: () => void;
  disconnect: () => void;
  swap: (params: SwapParams) => void;
}

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;
  sdkKey: string;
}

export const WalletProvider: React.FC<WalletProviderProps> = ({
  children,
  sdkKey,
}) => {
  const [walletSDK, setWalletSDK] = useState<WalletSDK | null>(null);
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [username, setUsername] = useState<string | null>(null);
  const [walletAddress, setWalletAddress] = useState<string | null>(null);
  const [solanaAddress, setSolanaAddress] = useState<string | null>(null);
  const [balance, setBalance] = useState<any | null>(null);
  const [showSwapModal, setShowSwapModal] = useState(false);
  const [swapParams, setSwapParams] = useState<SwapParams | null>(null);

  useEffect(() => {
    const sdk = new WalletSDK(sdkKey);
    setWalletSDK(sdk);

    // Check initial state
    const saved = localStorage.getItem("enclave_wallet_login");
    if (saved) {
      const parsed = JSON.parse(saved);
      setIsLoggedIn(true);
      setUsername(parsed.result?.username || null);
      setWalletAddress(parsed.result?.wallet?.scw_address || null);
      setSolanaAddress(parsed.result?.wallet?.solana_program_wallet || null);
      // Fetch initial balance
    }
  }, [sdkKey]);

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

  const disconnect = () => {
    if (walletSDK) {
      walletSDK.logout();
      setIsLoggedIn(false);
      setUsername(null);
      setWalletAddress(null);
      setBalance(null);
    }
  };

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

    const checkSession = async () => {
      const saved = localStorage.getItem("enclave_wallet_login");
      if (saved) {
        const parsed = JSON.parse(saved);
        setIsLoggedIn(true);
        setUsername(parsed.result?.username || null);
        setWalletAddress(parsed.result?.wallet?.scw_address || null);
        setSolanaAddress(parsed.result?.wallet?.solana_program_wallet || null);
        // Fetch updated balance
      } else {
        setIsLoggedIn(false);
        setUsername(null);
        setWalletAddress(null);
        setBalance(null);
      }
    };

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

  useEffect(() => {
    if (!walletSDK) {
      return;
    }
    const checkSession = async () => {
      const saved = localStorage.getItem("enclave_wallet_login");
      if (saved) {
        const newBalance = await walletSDK.getUserCryptoBalance();
        setBalance(newBalance);
      } else {
        setBalance(null);
      }
    };

    const interval = setInterval(checkSession, 10000);
    return () => clearInterval(interval);
  }, [isLoggedIn]);

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

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

  const value = {
    walletSDK,
    isLoggedIn,
    username,
    walletAddress,
    solanaAddress,
    balance,
    connect,
    disconnect,
    swap,
  };

  return (
    <WalletContext.Provider value={value}>
      <div
        style={{
          fontFamily: "Inter, sans-serif",
        }}
      >
        {children}
      </div>
    </WalletContext.Provider>
  );
};
