import { Avatar, Box, Link } from "@mui/material";
import { styled } from "@mui/material/styles";

import React, { useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";

import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import { useChainId } from "wagmi";

import TokenModal from "./TokenModal";
import StakeConfirmationModal from "./StakeConfirmationModal";
import StakeSettingsModal from "./StakeSettingsModal";

import SwapCard from "../../../components/Swap/SwapCard";
import SwapCollection from "../../../components/Swap/SwapCollection";
import { InfoNotification } from "../../../components/Notification";
import { PrimaryButton } from "../../../components/Button";

import {
    GHST_ADDRESSES,
    FTSO_ADDRESSES,
    STNK_ADDRESSES,
    STAKING_ADDRESSES,
} from "../../../constants/addresses";
import { useCurrentIndex } from "../../../hooks/staking";
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
import { formatNumber } from "../../../helpers";

const PREFIX = "StakeInputArea";

const classes = {
    inputRow: `${PREFIX}-inputRow`,
    gridItem: `${PREFIX}-gridItem`,
    input: `${PREFIX}-input`,
    button: `${PREFIX}-button`,
};

const StyledBox = styled(Box)(({ theme }) => ({
    [`& .${classes.inputRow}`]: {
        justifyContent: "space-around",
        alignItems: "center",
        height: "auto",
        marginTop: "4px",
    },

    [`& .${classes.gridItem}`]: {
        width: "100%",
        paddingRight: "5px",
        alignItems: "center",
        justifyContent: "center",
    },

    [`& .${classes.input}`]: {
        [theme.breakpoints.down("md")]: {
            marginBottom: "10px",
        },
        [theme.breakpoints.up("sm")]: {
            marginBottom: "0",
        },
    },

    [`& .${classes.button}`]: {
        width: "100%",
        minWidth: "163px",
        maxWidth: "542px",
    },
}));

export const StakeInputArea = ({
    upperToken,
    setUpperToken,
    bottomToken,
    setBottomToken,
    action,
    chainId,
    address,
    connect,
    settingsModalOpen,
    closeSettingModal
}) => {
    const [upperTokenModalOpen, setUpperTokenModalOpen] = useState(false);
    const [bottomTokenModalOpen, setBottomTokenModalOpen] = useState(false);
    const [confirmationModalOpen, setConfirmationModalOpen] = useState(false);

    const [formatDecimals, setFormatDecimals] = useState(localStorage.getItem("stake-decimals")
        ? localStorage.getItem("stake-decimals")
        : "5"
    );

    const [isClaim, setIsClaim] = useState(localStorage.getItem("stake-isClaim")
        ? localStorage.getItem("stake-isClaim") === 'true'
        : true
    );

    const [isTrigger, setIsTrigger] = useState(localStorage.getItem("stake-isTrigger")
        ? localStorage.getItem("stake-isTrigger") === 'true'
        : true
    );

    const [amount, setAmount] = useState("");
    const [receiveAmount, setReceiveAmount] = useState("");
    const [exceedsAmount, setExceedsAmount] = useState(false)

    const { currentIndex, refetch: refetchCurrentIndex } = useCurrentIndex(chainId);
    const { balance: ftsoBalance, refetch: ftsoRefetch } = useBalance(chainId, "FTSO", address);
    const { balance: stnkBalance, refetch: stnkRefetch } = useBalance(chainId, "STNK", address);
    const { balance: ghstBalance, refetch: ghstRefetch } = useBalance(chainId, "GHST", address);

    const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
    const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
    const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");

    const setIsClaimInner = (value) => {
        setIsClaim(value);
        localStorage.setItem("stake-isClaim", value);

    }

    const setIsTriggerInner = (value) => {
        setIsTrigger(value);
        localStorage.setItem("stake-isTrigger", value);
    }

    const setFormatDecimalsInner = (value) => {
        if (Number(value) <= 17) {
            setFormatDecimals(value);
            localStorage.setItem("staking-decimals", value);
        }
    }

    useEffect(() => {
        const innerBalance = upperToken === ghstSymbol ?
            ghstBalance
            :
            upperToken === stnkSymbol ?
                stnkBalance
                :
                ftsoBalance;

        if (
            (upperToken === ftsoSymbol && bottomToken === stnkSymbol) ||
            (upperToken === stnkSymbol && bottomToken === ftsoSymbol)
        ) {
            setReceiveAmount(amount);
            setExceedsAmount(new DecimalBigNumber(amount, 9).gt(innerBalance))
        } else {
            const decimals = upperToken === ghstSymbol ? 18 : 9;
            const raw = new DecimalBigNumber(amount, decimals);
            const amountIn = new DecimalBigNumber(raw._value.toBigInt(), decimals);
            const result = upperToken === ghstSymbol ?
                currentIndex.mul(amountIn).toString()
                :
                currentIndex._value > 0n ? amountIn.div(currentIndex).toString() : "0";

            const innerBalance = upperToken === ghstSymbol ?
                ghstBalance
                :
                upperToken === stnkSymbol ?
                    stnkBalance
                    :
                    ftsoBalance;

            setReceiveAmount(result);
            setExceedsAmount(amountIn.gt(innerBalance));
        }
    }, [upperToken, bottomToken, amount, currentIndex]);

    const handleTokenModalInput = (value, isUpper) => {
        if (isUpper) {
            if (value === bottomToken) {
                const newValue = value === ghstSymbol ? stnkSymbol : ghstSymbol;
                setBottomToken(newValue)
            }
            setUpperToken(value);
        } else {
            setBottomToken(value);
        }
    }

    const onSwapClick = () => {
        const tmpUpper = upperToken;
        const tmpBottom = bottomToken;
        setUpperToken(tmpBottom);
        setBottomToken(tmpUpper);
    }

    const SwapCardTemplate = (tokenName, tokenAmount, isUpper, handleModal) => {
        const balance = tokenName === stnkSymbol
            ? stnkBalance
            : tokenName === ftsoSymbol ? ftsoBalance : ghstBalance;

        let realTokenName = "";
        switch (tokenName.toUpperCase()) {
            case ftsoSymbol:
                realTokenName = ftsoSymbol;
                break;
            case stnkSymbol:
                realTokenName = stnkSymbol;
                break;
            case ghstSymbol:
                realTokenName = ghstSymbol;
                break;
        }

        return (
            <SwapCard
                id={`${tokenName.toLowerCase()}-input`}
                token={tokenName}
                tokenName={realTokenName}
                tokenOnClick={() => handleModal(true)}
                inputProps={{ "data-testid": `${tokenName.toLowerCase()}-input`, min: "0" }}
                value={tokenAmount}
                onChange={event => setAmount(event.target.value)}
                info={`Balance: ${formatNumber(balance, formatDecimals)} ${tokenName}`}
                endString={isUpper ? "Max" : ""}
                endStringOnClick={() => isUpper && setAmount(balance.toString())}
                disabled={!isUpper}
                inputWidth={`${tokenAmount.length > 0 ? tokenAmount.length : 1}ch`}
            />
        )
    }

    const closeAndUpdate = () => {
        setAmount("");
        setConfirmationModalOpen(false);
        refetchCurrentIndex();
        ftsoRefetch();
        stnkRefetch();
        ghstRefetch();
    }

    return (
        <>
            <StyledBox mb={3}>
                <Box display="flex" flexDirection="row" width="100%" justifyContent="center" mt="24px">
                    <Box display="flex" flexDirection="column" width="100%" maxWidth="476px">
                        <Box mb="21px">
                            <SwapCollection
                                UpperSwapCard={SwapCardTemplate(upperToken, amount, true, setUpperTokenModalOpen)}
                                LowerSwapCard={SwapCardTemplate(bottomToken, receiveAmount, false, setBottomTokenModalOpen)}
                                arrowOnClick={onSwapClick}
                            />
                        </Box>

                        {upperTokenModalOpen && (
                            <TokenModal
                                open={upperTokenModalOpen}
                                handleSelect={data => handleTokenModalInput(data.token, data.isUpper)}
                                handleClose={() => setUpperTokenModalOpen(false)}
                                ftsoBalance={formatNumber(ftsoBalance, formatDecimals)}
                                stnkBalance={formatNumber(stnkBalance, formatDecimals)}
                                ghstBalance={formatNumber(ghstBalance, formatDecimals)}
                                isUpper={true}
                                ftsoSymbol={ftsoSymbol}
                                stnkSymbol={stnkSymbol}
                                ghstSymbol={ghstSymbol}
                            />
                        )}
                        {bottomTokenModalOpen && (
                            <TokenModal
                                open={bottomTokenModalOpen}
                                handleSelect={data => handleTokenModalInput(data.token, data.isUpper)}
                                handleClose={() => setBottomTokenModalOpen(false)}
                                ftsoBalance={formatNumber(ftsoBalance, formatDecimals)}
                                stnkBalance={formatNumber(stnkBalance, formatDecimals)}
                                ghstBalance={formatNumber(ghstBalance, formatDecimals)}
                                tokenToExclude={upperToken}
                                isUpper={false}
                                ftsoSymbol={ftsoSymbol}
                                stnkSymbol={stnkSymbol}
                                ghstSymbol={ghstSymbol}
                            />
                        )}

                        <Box>
                            <PrimaryButton
                                fullWidth
                                onClick={() => setConfirmationModalOpen(true)}
                                loading={false}
                                disabled={exceedsAmount}
                            >
                                {exceedsAmount ?
                                    "Exceeds amount"
                                    :
                                    action[0] + String(action.toLowerCase()).slice(1)
                                }
                            </PrimaryButton>
                        </Box>
                    </Box>
                </Box>
            </StyledBox>
            <StakeSettingsModal
                open={settingsModalOpen}
                onClose={closeSettingModal}
                formatDecimals={formatDecimals}
                onFormatDecimalsChange={event => setFormatDecimalsInner(event.currentTarget.value)}
                isClaim={isClaim}
                onIsClaimChanged={setIsClaimInner}
                isTrigger={isTrigger}
                onTriggerRebaseChange={setIsTriggerInner}
            />
            <StakeConfirmationModal
                open={confirmationModalOpen}
                onClose={() => closeAndUpdate()}
                chainId={chainId}
                address={address}
                action={action}
                upperToken={upperToken}
                bottomToken={bottomToken}
                amount={amount}
                receiveAmount={receiveAmount}
                amountExceedsBalance={exceedsAmount}
                connect={connect}
                spendDecimals={upperToken === ghstSymbol ? 18 : 9}
                receiveDecimals={bottomToken === ghstSymbol ? 18 : 9}
                isClaim={isClaim}
                isTrigger={isTrigger}
                ftsoSymbol={ftsoSymbol}
                stnkSymbol={stnkSymbol}
                ghstSymbol={ghstSymbol}
            />
        </>
    );
};
