import React, { useState, useMemo } from "react";
import { ArrowLeft } from "lucide-react";
import { formatUnits, parseUnits } from "ethers";
import { NETWORK_LOGO_URLS, NETWORK_NAME_TO_CHAIN_ID } from "./utils";
import { validateNumericInput, handleNumericKeyDown } from "./utils";

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

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

const TokenAllocation: React.FC<TokenAllocationProps> = ({
  selectedNetworks,
  fromToken,
  onBack,
  onDone,
  initialAllocations = [],
}) => {
  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 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 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: "#fff",
        borderRadius: 20,
        fontFamily: "Inter, sans-serif",
        paddingBottom: 24,
      }}
    >
      <div
        style={{
          display: "flex",
          alignItems: "center",
          marginBottom: 8,
          position: "relative",
        }}
      >
        <button
          onClick={onBack}
          style={{
            background: "none",
            border: "none",
            fontSize: 22,
            color: "#222",
            cursor: "pointer",
            position: "absolute",
            left: 0,
            fontFamily: "Inter, sans-serif",
          }}
        >
          <ArrowLeft style={{ width: 24, height: 24, color: "#717680" }} />
        </button>
        <span
          style={{
            fontWeight: 600,
            fontSize: 20,
            width: "100%",
            textAlign: "center",
          }}
        >
          Enter Token Allocation
        </span>
      </div>

      <div
        style={{
          marginBottom: 16,
          width: "100%",
          display: "flex",
          justifyContent: "center",
        }}
      >
        <p
          style={{
            color: "#717680",
            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 }}>
                    {network}
                  </span>
                </div>
                <div
                  style={{
                    display: "flex",
                    fontSize: 14,
                    color: "#717680",
                    alignItems: "center",
                    gap: 8,
                  }}
                >
                  <span>
                    Bal: {parseFloat(balance).toFixed(6)} {fromToken?.symbol}
                  </span>
                  <button
                    onClick={() =>
                      handleInputChange(network, balance.toString())
                    }
                    style={{
                      background: "none",
                      border: "none",
                      color: "#4664E9",
                      cursor: "pointer",
                      padding: 0,
                      borderLeft: "1px solid #D5D7DA",
                      paddingLeft: 8,
                    }}
                  >
                    Max
                  </button>
                </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" : "#D5D7DA"}`,
                      borderRadius: 8,
                      backgroundColor: "white",
                      fontSize: 16,
                      outline: "none",
                    }}
                  />
                  <span
                    style={{
                      position: "absolute",
                      right: 12,
                      top: "50%",
                      transform: "translateY(-50%)",
                      color: "#717680",
                    }}
                  >
                    {fromToken?.symbol}
                  </span>
                </div>
                {hasError && (
                  <span style={{ color: "#FF4D4F", fontSize: 12 }}>
                    {errors[network]}
                  </span>
                )}
              </div>
            </div>
          );
        })}
      </div>

      <div style={{ display: "flex", gap: 12, padding: "0 16px" }}>
        <button
          onClick={onBack}
          style={{
            flex: 1,
            border: "1px solid #D5D7DA",
            background: "#fff",
            color: "#414651",
            fontWeight: 600,
            fontSize: 16,
            borderRadius: 8,
            padding: "12px 0",
            cursor: "pointer",
          }}
        >
          Go back
        </button>
        <button
          onClick={handleDone}
          disabled={!isValid}
          style={{
            flex: 1,
            border: "none",
            background: isValid ? "#4664E9" : "#D5D7DA",
            color: "#fff",
            fontWeight: 600,
            fontSize: 16,
            borderRadius: 8,
            cursor: isValid ? "pointer" : "not-allowed",
          }}
        >
          Done
        </button>
      </div>
    </div>
  );
};

export default TokenAllocation;
