import React, { useState, useMemo } from "react";
import { ArrowLeft } from "lucide-react";
import { formatUnits, parseUnits } from "ethers";
import {
  getContrastingTextColor,
  NETWORK_LOGO_URLS,
  NETWORK_NAME_TO_CHAIN_ID,
} from "./utils";
import { validateNumericInput, handleNumericKeyDown } from "./utils";
import { borderRadiusStyles, ThemeMode } from "../types/theme";
import { useWallet } from "./WalletProvider";
import { AmountDropdown } from "./ui";

interface NetworkAllocation {
  name: string;
  chainId: number;
  amount: string;
}

interface TokenAllocationProps {
  selectedNetworks: string[];
  fromToken: any;
  onBack: () => void;
  onDone: (allocations: NetworkAllocation[]) => void;
  initialAllocations?: NetworkAllocation[];
  theme?: ThemeMode;
}

const TokenAllocation: React.FC<TokenAllocationProps> = ({
  selectedNetworks,
  fromToken,
  onBack,
  onDone,
  initialAllocations = [],
  theme = "dark",
}) => {
  const [allocations, setAllocations] = useState<{ [network: string]: string }>(
    () => {
      const initial = selectedNetworks.reduce((acc, network) => {
        const existingAllocation = initialAllocations.find(
          (a) => a.name === network
        );
        return {
          ...acc,
          [network]: existingAllocation?.amount || "",
        };
      }, {});
      return initial;
    }
  );

  const [errors, setErrors] = useState<{ [network: string]: string }>({});

  const { walletCornerRadius, currentTheme } = useWallet();
  const currentRadius = borderRadiusStyles[walletCornerRadius];

  const getNetworkBalance = (networkName: string) => {
    const chainId = NETWORK_NAME_TO_CHAIN_ID[networkName];
    const tokenChainInfo = fromToken?.chainIds?.find(
      (chain: any) => chain.chainId === chainId
    );
    const chainBalance = tokenChainInfo?.balance ?? "0";
    return formatUnits(chainBalance, fromToken?.decimals || 6);
  };

  const handleInputChange = (network: string, value: string) => {
    // Validate and sanitize the input first
    const sanitizedValue = validateNumericInput(value, fromToken?.decimals);

    const balance = getNetworkBalance(network);

    // Compare using parseUnits for both values
    const numValueWei = sanitizedValue
      ? parseUnits(sanitizedValue, fromToken?.decimals || 6)
      : BigInt(0);
    const balanceWei = parseUnits(balance, fromToken?.decimals || 6);

    setAllocations((prev) => ({
      ...prev,
      [network]: sanitizedValue,
    }));

    // Update error state
    setErrors((prev) => ({
      ...prev,
      [network]: numValueWei > balanceWei ? "Insufficient balance" : "",
    }));
  };

  const handlePresetClick = (network: string, percentage: number) => {
    const balance = getNetworkBalance(network);
    if (!balance || balance === "0") return;

    try {
      if (percentage === 100) {
        handleInputChange(network, balance.toString());
      } else {
        // Calculate percentage
        const parsedBalance = parseUnits(balance, fromToken?.decimals || 6);
        const amount = (parsedBalance * BigInt(percentage)) / BigInt(100);
        const formattedAmount = formatUnits(amount, fromToken?.decimals || 6);
        handleInputChange(network, formattedAmount);
      }
    } catch (error) {
      console.error("Error calculating preset amount:", error);
    }
  };

  const isValid = useMemo(() => {
    return (
      Object.values(errors).every((error) => !error) && // No errors
      Object.values(allocations).some((amount) => {
        if (!amount) return false;
        try {
          const amountWei = parseUnits(amount, fromToken?.decimals || 6);
          return amountWei > BigInt(0);
        } catch {
          return false;
        }
      }) // At least one amount > 0
    );
  }, [errors, allocations, fromToken?.decimals]);

  const handleDone = () => {
    const networkAllocations: NetworkAllocation[] = selectedNetworks.map(
      (network) => ({
        name: network,
        chainId: NETWORK_NAME_TO_CHAIN_ID[network],
        amount: allocations[network],
      })
    );
    onDone(networkAllocations);
  };

  return (
    <div
      style={{
        width: "100%",
        background: currentTheme.surface,
        borderRadius: `${currentRadius.innerRadius}px`,

        paddingBottom: 24,
        color: currentTheme.text,
      }}
    >
      <div
        style={{
          display: "flex",
          alignItems: "center",
          marginBottom: 8,
          position: "relative",
        }}
      >
        <button
          onClick={onBack}
          style={{
            background: "none",
            border: "none",
            fontSize: 22,
            color: currentTheme.text,
            cursor: "pointer",
            position: "absolute",
            left: 0,
          }}
        >
          <ArrowLeft
            style={{ width: 24, height: 24, color: currentTheme.textSecondary }}
          />
        </button>
        <span
          style={{
            fontWeight: 600,
            fontSize: 20,
            width: "100%",
            textAlign: "center",
            color: currentTheme.text,
          }}
        >
          Enter Token Allocation
        </span>
      </div>

      <div
        style={{
          marginBottom: 16,
          width: "100%",
          display: "flex",
          justifyContent: "center",
        }}
      >
        <p
          style={{
            color: currentTheme.textSecondary,
            fontSize: 14,
            margin: "0 0 6px 0",
            textAlign: "center",
            width: "300px",
          }}
        >
          Specify how much {fromToken?.symbol} you want to send out of each
          network
        </p>
      </div>

      <div style={{ marginBottom: 24 }}>
        {selectedNetworks.map((network) => {
          const balance = getNetworkBalance(network);
          const hasError = errors[network];

          return (
            <div
              key={network}
              style={{
                padding: "16px 0px",
                display: "flex",
                flexDirection: "column",
                gap: 8,
              }}
            >
              <div style={{ display: "flex", justifyContent: "space-between" }}>
                <div
                  style={{
                    display: "flex",
                    alignItems: "center",
                    gap: 8,
                    marginBottom: 8,
                  }}
                >
                  <img
                    src={NETWORK_LOGO_URLS[NETWORK_NAME_TO_CHAIN_ID[network]]}
                    alt={network}
                    style={{ width: 24, height: 24 }}
                  />
                  <span
                    style={{
                      fontWeight: 500,
                      fontSize: 16,
                      color: currentTheme.text,
                    }}
                  >
                    {network}
                  </span>
                </div>
                <div
                  style={{
                    display: "flex",
                    fontSize: 14,
                    color: currentTheme.textSecondary,
                    alignItems: "center",
                    gap: 8,
                  }}
                >
                  <div
                    style={{
                      display: "flex",
                      alignItems: "center",
                      background: currentTheme.surface,
                      padding: "6px 10px",
                      border: `1px solid ${currentTheme.border}`,
                      borderTopLeftRadius: currentRadius.level3Radius,
                      borderBottomLeftRadius: currentRadius.level3Radius,
                    }}
                  >
                    <span>
                      Bal: {parseFloat(balance).toFixed(6)} {fromToken?.symbol}
                    </span>
                  </div>
                  <AmountDropdown
                    onSelectPercentage={(percentage) =>
                      handlePresetClick(network, percentage)
                    }
                    disabled={!balance || parseFloat(balance) === 0}
                  />
                </div>
              </div>
              <div
                style={{
                  display: "flex",
                  flexDirection: "column",
                  gap: 4,
                }}
              >
                <div style={{ flex: 1, position: "relative" }}>
                  <input
                    type="text"
                    value={allocations[network]}
                    onChange={(e) => handleInputChange(network, e.target.value)}
                    onKeyDown={(e) =>
                      handleNumericKeyDown(
                        e,
                        allocations[network],
                        fromToken?.decimals
                      )
                    }
                    placeholder="0.00"
                    style={{
                      width: "100%",
                      padding: "12px 70px 12px 12px",
                      border: `1px solid ${
                        hasError ? "#FF4D4F" : currentTheme.border
                      }`,
                      borderRadius: `${currentRadius.innerRadius}px`,
                      backgroundColor: currentTheme.surface,
                      fontSize: 16,
                      outline: "none",
                      color: currentTheme.text,
                    }}
                  />
                  <span
                    style={{
                      position: "absolute",
                      right: 12,
                      top: "50%",
                      transform: "translateY(-50%)",
                      color: currentTheme.textSecondary,
                    }}
                  >
                    {fromToken?.symbol}
                  </span>
                </div>
                {hasError && (
                  <span style={{ color: "#FF4D4F", fontSize: 12 }}>
                    {errors[network]}
                  </span>
                )}
              </div>
            </div>
          );
        })}
      </div>

      <div style={{ display: "flex", gap: 12 }}>
        <button
          onClick={onBack}
          style={{
            flex: 1,
            border: `1px solid ${currentTheme.border}`,
            background: currentTheme.surface,
            color: currentTheme.text,
            fontWeight: 600,
            fontSize: 16,
            borderRadius: `${currentRadius.innerRadius}px`,
            padding: "16px 0",
            cursor: "pointer",
          }}
        >
          Go back
        </button>
        <button
          onClick={handleDone}
          disabled={!isValid}
          style={{
            flex: 1,
            border: "none",
            background: currentTheme.primary,
            color: getContrastingTextColor(currentTheme.primary),
            fontWeight: 600,
            fontSize: 16,
            padding: "16px 0",
            borderRadius: `${currentRadius.innerRadius}px`,
            cursor: isValid ? "pointer" : "not-allowed",
            opacity: isValid ? 1 : 0.5,
          }}
        >
          Done
        </button>
      </div>
    </div>
  );
};

export default TokenAllocation;
