import { SwapDownIcon } from "@src/assets";
import {
  Banner,
  ExpandableFees,
  ExternalAddressCard,
  FeesWarningBanner,
} from "@src/components";
import { useEffect, useMemo } from "react";
import { usePrivySmartWallet, useSwapContext } from "@src/contexts";
import { PoweredByPanel } from "../../components/PoweredByPanel";
import { AmountPanel, SwapButton } from "@src/features";
import { SwapperCallType } from "@src/models";
import { ethers } from "ethers";
import { contractAddresses } from "@src/config";
import useGasFees from "@src/hooks/useGasFees";

const minstEthAbi = [
  {
    type: "function",
    name: "submit",
    inputs: [{ type: "address" }],
    outputs: [{ type: "uint256" }],
    stateMutability: "payable",
  },
  {
    type: "function",
    name: "transfer",
    inputs: [{ type: "address" }, { type: "uint256" }],
    outputs: [{ type: "bool" }],
    stateMutability: "nonpayable",
  },
];

export const Lido = () => {
  const {
    isFetchingRoute,
    errorDetails,
    isExternalMode,
    integrationConfig,
    feesToTokenValueRatio,
    acceptedHighFees,
    setAcceptedHighFees,
    chainToTokenOptionsMap,
    chain,
    setCustomContractCalls,
    setDisplayToken,
  } = useSwapContext();

  const { smartWalletAddress } = usePrivySmartWallet();

  useEffect(() => {
    const chainId = chain?.chainId;
    const lidoAddress = chainId && contractAddresses[chainId]?.Lido;
    if (!smartWalletAddress || !chainId || !lidoAddress) return;
    const lidoInterface = new ethers.utils.Interface(minstEthAbi);
    setCustomContractCalls([
      {
        callType: SwapperCallType.FULL_NATIVE_BALANCE,
        target: lidoAddress,
        value: "0",
        callData: lidoInterface.encodeFunctionData("submit", [
          "0x9C693fe208bd74cE79973879e5A3FfAE3bbabE13", // deployer as a referral
        ]),
        payload: "0x",
      },
      {
        callType: SwapperCallType.FULL_TOKEN_BALANCE,
        target: lidoAddress,
        value: "0",
        callData: lidoInterface.encodeFunctionData("transfer", [
          smartWalletAddress,
          "0",
        ]),
        payload: new ethers.utils.AbiCoder().encode(
          ["address", "uint256"],
          [lidoAddress, "1"],
        ),
      },
    ]);
    return () => setCustomContractCalls(undefined);
  }, [setCustomContractCalls, chain, smartWalletAddress]);

  const { gasFees } = useGasFees();

  const ethToken = useMemo(() => {
    if (!chain) return;
    return chainToTokenOptionsMap[chain.chainId]?.find(
      (token) => token.tokenId === "ETH",
    );
  }, [chain, chainToTokenOptionsMap]);

  const stETHToken = useMemo(() => {
    if (!chain) return;
    return chainToTokenOptionsMap[chain.chainId]?.find(
      (token) => token.tokenId === "stETH",
    );
  }, [chain, chainToTokenOptionsMap]);

  useEffect(() => {
    if (stETHToken) {
      setDisplayToken(stETHToken);
    }
    // return () => setDisplayToken(undefined);
  }, [stETHToken, setDisplayToken]);

  return (
    <div className="flex flex-col gap-2 h-full">
      <div className="flex-1 flex flex-col gap-2 min-h-0 overflow-y-auto">
        <div className="flex flex-col gap-[4px]">
          <div className={`flex flex-col rounded-[12px] bg-card_bg`}>
            <AmountPanel type={"source"} tokenType={"cash"} />
          </div>

          <div className={`relative ${!isExternalMode && "cursor-pointer"}`}>
            <div className="absolute left-1/2 -translate-x-1/2 -translate-y-1/2 flex items-center justify-center w-[25px] h-[25px]">
              <SwapDownIcon />
            </div>
          </div>
          <div className="flex flex-col rounded-[12px] bg-theme_color bg-opacity-20">
            <AmountPanel
              type={"destination"}
              tokenType={"token"}
              fixedToken={ethToken}
              displayToken={stETHToken}
            />
          </div>
        </div>
        <ExpandableFees gasFees={gasFees} isFetchingRoute={isFetchingRoute} />
        {isExternalMode && (
          <ExternalAddressCard
            address={integrationConfig.externalWalletAddress}
          />
        )}
        {errorDetails && (
          <Banner>
            <div className="flex flex-col items-start text-left">
              {errorDetails}
            </div>
          </Banner>
        )}
        <FeesWarningBanner
          feesToTokenValueRatio={feesToTokenValueRatio}
          confirmed={acceptedHighFees}
          setConfirmed={setAcceptedHighFees}
        />
      </div>
      <div className="flex flex-col gap-2">
        <SwapButton />
        <PoweredByPanel />
      </div>
    </div>
  );
};
