import React, { useState, useMemo, useEffect, useCallback } from "react";
import { ArrowLeft, Search } from "lucide-react";
import Spinner from "./ui/Spinner";
import { searchTokensByQuery } from "../services/services";
import { TokenLogo } from "./ui/TokenLogo";
import { useWallet } from "./WalletProvider";

const styles = `
  .hide-scrollbar::-webkit-scrollbar {
    display: none;
  }
`;

export interface Token {
  symbol: string;
  name: string;
  icon?: string;
  logoURI?: string;
  address: string;
  chainId: number;
  decimals: number;
  balance?: string;
  amount?: string;
  chainIds?: any[];
  price?: number;
  priceUsd?: number;
  valueUsd?: number;
}

interface TokenSelectorProps {
  title: string;
  tokens: Token[];
  onTokenSelect: (token: Token) => void;
  onBack: () => void;
  isLoading?: boolean;
  tokenFilter?: string[];
  inSwap?: boolean;
  apiKey: string;
}

const TokenSelector: React.FC<TokenSelectorProps> = ({
  title,
  tokens,
  onTokenSelect,
  onBack,
  isLoading = false,
  tokenFilter,
  inSwap = false,
  apiKey,
}) => {
  const [searchQuery, setSearchQuery] = useState("");
  const [isSearching, setIsSearching] = useState(false);
  const [searchResults, setSearchResults] = useState<Token[]>([]);
  const [debouncedQuery, setDebouncedQuery] = useState("");
  const { cryptoBalance } = useWallet();

  // Get user balance tokens
  const userBalanceTokens: Token[] = cryptoBalance?.data || [];

  // Debounce search query
  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedQuery(searchQuery);
    }, 300); // 300ms delay

    return () => clearTimeout(timer);
  }, [searchQuery]);

  // Perform search when debounced query changes
  useEffect(() => {
    const performSearch = async () => {
      if (!debouncedQuery) {
        setSearchResults([]);
        return;
      }

      setIsSearching(true);
      try {
        const result = await searchTokensByQuery(debouncedQuery, apiKey);
        if (result?.success && result.data) {
          // Map TokenInfo to Token interface
          const mappedTokens: Token[] = result.data.map((token) => ({
            symbol: token.symbol,
            name: token.name,
            icon: token.logoURI,
            logoURI: token.logoURI,
            address: token.chainIds?.[0]?.address || "",
            chainId: token.chainIds?.[0]?.chainId || 0,
            decimals: token.decimals,
            balance: undefined,
            amount: token.amount?.toString(),
            chainIds: token.chainIds,
            price: token.price,
            priceUsd: token.priceUsd,
          }));
          setSearchResults(mappedTokens);
        }
      } catch (error) {
        console.error("Error searching tokens:", error);
      } finally {
        setIsSearching(false);
      }
    };

    performSearch();
  }, [debouncedQuery, apiKey]);

  // Filter user balance tokens based on search query
  const filteredUserTokens = useMemo(() => {
    if (!userBalanceTokens || userBalanceTokens.length === 0) return [];

    let filtered = userBalanceTokens;

    // Apply search filter
    if (searchQuery) {
      const query = searchQuery.toLowerCase();
      filtered = filtered.filter(
        (token: Token) =>
          token.name.toLowerCase().includes(query) ||
          token.symbol.toLowerCase().includes(query) ||
          (token.address && token.address.toLowerCase().includes(query))
      );
    }

    // Apply token filter if provided
    if (tokenFilter && tokenFilter.length > 0) {
      filtered = filtered.filter((token) => tokenFilter.includes(token.symbol));
    }

    // Sort by valueUsd in descending order
    filtered = filtered.sort((a, b) => {
      const valueA = a.valueUsd || 0;
      const valueB = b.valueUsd || 0;
      return valueB - valueA;
    });

    return filtered;
  }, [userBalanceTokens, searchQuery, tokenFilter]);

  // Filter all tokens based on search query and exclude user balance tokens
  const filteredTokens = useMemo(() => {
    // If there's a search query and search results, show those instead
    if (debouncedQuery && searchResults.length > 0) {
      return searchResults;
    }

    let filtered = tokens;

    // Remove tokens that are already in user balances
    if (userBalanceTokens && userBalanceTokens.length > 0) {
      const userTokenKeys = new Set(
        userBalanceTokens.flatMap(
          (userToken: Token) =>
            userToken.chainIds?.map(
              (chain: any) => `${chain.address.toLowerCase()}-${chain.chainId}`
            ) || [`${userToken.address?.toLowerCase()}-${userToken.chainId}`]
        )
      );

      filtered = filtered.filter((token) => {
        const tokenKey = `${token.address.toLowerCase()}-${token.chainId}`;
        return !userTokenKeys.has(tokenKey);
      });
    }

    // Apply token filter if provided
    if (tokenFilter && tokenFilter.length > 0) {
      filtered = filtered.filter((token) => tokenFilter.includes(token.symbol));
    }

    // Apply search filter
    if (searchQuery) {
      const query = searchQuery.toLowerCase();
      filtered = filtered.filter(
        (token: Token) =>
          token.name.toLowerCase().includes(query) ||
          token.symbol.toLowerCase().includes(query) ||
          (token.address && token.address.toLowerCase().includes(query))
      );
    }

    return filtered;
  }, [
    tokens,
    userBalanceTokens,
    searchQuery,
    tokenFilter,
    debouncedQuery,
    searchResults,
  ]);

  // Helper function to render token rows
  const renderTokenRow = (
    token: Token,
    idx: number,
    isLastInSection: boolean,
    showBalance: boolean = false
  ) => (
    <div
      key={`${token.symbol}-${idx}`}
      style={{
        display: "flex",
        alignItems: "center",
        padding: "14px 0",
        borderBottom: !isLastInSection ? "1px solid #E9EAEB" : "none",
        cursor: "pointer",
        transition: "background 0.1s",
      }}
      onClick={() => onTokenSelect(token)}
    >
      <TokenLogo
        logoURI={token.logoURI || token.icon}
        symbol={token.symbol}
        name={token.name}
        size={36}
        style={{ marginRight: 12 }}
      />
      <div style={{ flexGrow: 1 }}>
        <div style={{ fontWeight: 600 }}>{token.name}</div>
        <div style={{ color: "#666", fontSize: 12 }}>{token.symbol}</div>
      </div>
      {/* Balance and Value Display for user tokens */}
      {showBalance && token.balance && (
        <div style={{ textAlign: "right" }}>
          {token.valueUsd && (
            <div style={{ fontWeight: 600, fontSize: 16 }}>
              $
              {(() => {
                const valueUsd = parseFloat(String(token?.valueUsd || "0"));
                if (valueUsd > 0 && valueUsd < 0.0001) {
                  return "<0.0001";
                }
                return valueUsd.toLocaleString(undefined, {
                  minimumFractionDigits: 2,
                  maximumFractionDigits: 2,
                });
              })()}
            </div>
          )}
          <div style={{ fontWeight: 400, fontSize: 12, color: "#666" }}>
            {(() => {
              const amount = parseFloat(token?.amount || "0");
              if (amount > 0 && amount < 0.0001) {
                return "<0.0001";
              }
              return amount.toLocaleString(undefined, {
                maximumFractionDigits: 6,
              });
            })()}
          </div>
        </div>
      )}
    </div>
  );

  return (
    <>
      <style>{styles}</style>
      <div
        style={{
          width: "100%",
          background: "#fff",
          borderRadius: 20,
          fontFamily: "Inter, sans-serif",
          display: "flex",
          flexDirection: "column",
          height: "550px",
        }}
      >
        {/* Header */}
        <div
          style={{
            display: "flex",
            alignItems: "center",
            marginBottom: 18,
            position: "relative",
          }}
        >
          <button
            onClick={onBack}
            style={{
              background: "none",
              border: "none",
              fontSize: 22,
              color: "#222",
              cursor: "pointer",
              position: "absolute",
              left: 0,
              fontFamily: "Inter, sans-serif",
              padding: 0,
              margin: 0,
              outline: "none",
            }}
          >
            <ArrowLeft style={{ width: 24, height: 24, color: "#717680" }} />
          </button>
          <span
            style={{
              fontWeight: 600,
              fontSize: 20,
              width: "100%",
              textAlign: "center",
            }}
          >
            {title}
          </span>
        </div>

        {/* Search Input */}
        <div style={{ position: "relative", marginBottom: 18 }}>
          {isSearching ? (
            <div
              style={{
                position: "absolute",
                left: 14,
                top: "50%",
                transform: "translateY(-50%)",
              }}
            >
              <Spinner />
            </div>
          ) : (
            <Search
              style={{
                position: "absolute",
                left: 14,
                top: "50%",
                transform: "translateY(-50%)",
                width: 18,
                height: 18,
                color: "#717680",
              }}
            />
          )}
          <input
            type="text"
            placeholder="Search name or paste address..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            style={{
              width: "100%",
              padding: "10px 14px 10px 40px",
              borderRadius: 10,
              border: "1px solid #E0E0E0",
              backgroundColor: "white",
              fontSize: 16,
              color: "#717680",
              outline: "none",
            }}
          />
        </div>

        {/* Token List */}
        <div>
          <div
            style={{
              flex: 1,
              overflowY: "auto",
              maxHeight: "440px",
              paddingRight: 8,
              msOverflowStyle: "none",
              scrollbarWidth: "none",
              WebkitOverflowScrolling: "touch",
            }}
            className="hide-scrollbar"
          >
            {isLoading || isSearching ? (
              <div
                style={{
                  display: "flex",
                  flexDirection: "column",
                  alignItems: "center",
                  justifyContent: "center",
                  height: "200px",
                  gap: "16px",
                }}
              >
                <Spinner />
                <span style={{ color: "#717680", fontSize: 16 }}>
                  {isSearching ? "Searching Tokens..." : "Loading Tokens..."}
                </span>
              </div>
            ) : filteredTokens.length === 0 &&
              filteredUserTokens.length === 0 &&
              debouncedQuery ? (
              <div
                style={{
                  display: "flex",
                  flexDirection: "column",
                  alignItems: "center",
                  justifyContent: "center",
                  height: "200px",
                  gap: "16px",
                }}
              >
                <span style={{ color: "#717680", fontSize: 16 }}>
                  No tokens found
                </span>
              </div>
            ) : (
              <>
                {/* User Tokens Section */}
                {filteredUserTokens && filteredUserTokens.length > 0 && (
                  <div>
                    <div
                      style={{
                        fontWeight: 600,
                        fontSize: 16,
                        color: "#333",
                        padding: "8px 0",
                        marginBottom: 8,
                      }}
                    >
                      Your Tokens
                    </div>
                    {filteredUserTokens.map((token: Token, idx: number) =>
                      renderTokenRow(
                        token,
                        idx,
                        idx === filteredUserTokens.length - 1,
                        true
                      )
                    )}
                  </div>
                )}

                {/* Remaining Tokens Section */}
                {filteredTokens.length > 0 && (
                  <div
                    style={{
                      marginTop:
                        filteredUserTokens && filteredUserTokens.length > 0
                          ? 16
                          : 0,
                    }}
                  >
                    <div
                      style={{
                        fontWeight: 600,
                        fontSize: 16,
                        color: "#333",
                        padding: "8px 0",
                        marginBottom: 8,
                      }}
                    >
                      {filteredUserTokens && filteredUserTokens.length > 0
                        ? "All Tokens"
                        : "Tokens"}
                    </div>
                    {filteredTokens.map((token: Token, idx: number) =>
                      renderTokenRow(
                        token,
                        idx,
                        idx === filteredTokens.length - 1,
                        false
                      )
                    )}
                  </div>
                )}
              </>
            )}
          </div>
        </div>
      </div>
    </>
  );
};

export default TokenSelector;
