import { CheckBoxOutlineBlank, CheckBoxOutlined } from "@mui/icons-material";
import { Box, Checkbox, FormControlLabel, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import ArrowRightIcon from '@mui/icons-material/ArrowRight';

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

import GhostStyledIcon from "../../../components/Icon/GhostIcon";
import Modal from "../../../components/Modal/Modal";
import Metric from "../../../components/Metric/Metric";
import Token from "../../../components/Token/Token";
import { PrimaryButton, SecondaryButton } from "../../../components/Button";
import { TokenAllowanceGuard } from "../../../components/TokenAllowanceGuard/TokenAllowanceGuard";

import { useWarmupLength, stake, unstake, wrap, unwrap } from "../../../hooks/staking";
import { formatNumber } from "../../../helpers";

import { STAKING_ADDRESSES } from "../../../constants/addresses";

const StakeConfirmationModal = (props) => {
    const { warmupLength, warmupExists: needsWarmup } = useWarmupLength(props.chainId);
    const [acknowledgedWarmup, setAcknowledgedWarmup] = useState(false);
    const [isPending, setIsPending] = useState(false);

    useEffect(() => setAcknowledgedWarmup(acknowledgedWarmup || !needsWarmup), [acknowledgedWarmup, needsWarmup])

    const AcknowledgeWarmupCheckbox = () => {
        if (!needsWarmup) return <></>;
        return (
            <>
                <Box sx={{ marginBottom: "1rem" }}>
                    <hr style={{ borderWidth: "0.5px" }} />
                    <FormControlLabel
                        control={
                            <Checkbox
                                data-testid="acknowledge-stake-warm-up"
                                checked={acknowledgedWarmup}
                                onChange={event => setAcknowledgedWarmup(event.target.checked)}
                                icon={<CheckBoxOutlineBlank viewBox="0 0 24 24" />}
                                checkedIcon={<CheckBoxOutlined viewBox="0 0 24 24" />}
                            />
                        }
                        label={
                            <Typography variant="body2">
                                {`I understand the ${props.ftsoSymbol} I’m staking will only be available to claim ${warmupLength.toString()} epochs after my transaction is confirmed`}
                            </Typography>
                        }
                    />
                </Box>
            </>
        );
    };

    const NeedsWarmupDetails = () => {
        if (needsWarmup && props.action === "STAKE") {
            return (
                <>
                    <AcknowledgeWarmupCheckbox />
                    <SecondaryButton
                        fullWidth
                        href="https://ghostchain.io/ghostdao_litepaper"
                    >
                        Why is there a warm-up?
                    </SecondaryButton>
                </>
            );
        } else {
            return <></>;
        }
    };

    const doAction = async () => {
        setIsPending(true);
        const actionAmount = new DecimalBigNumber(props.amount, props.spendDecimals);
        let isRebase = false;

        switch (props.action.toUpperCase()) {
            case "STAKE":
                isRebase = props.bottomToken === props.stnkSymbol;
                await stake(
                    props.chainId,
                    props.address,
                    actionAmount._value.toBigInt(),
                    isRebase,
                    props.isClaim,
                    props.ftsoSymbol,
                    props.stnkSymbol,
                    props.ghstSymbol
                );
                break;
            case "UNSTAKE":
                isRebase = props.upperToken === props.stnkSymbol;
                await unstake(
                    props.chainId,
                    props.address,
                    actionAmount._value.toBigInt(),
                    props.isTrigger,
                    isRebase,
                    props.ftsoSymbol,
                    props.stnkSymbol,
                    props.ghstSymbol
                );
                break;
            case "WRAP":
                await wrap(
                    props.chainId,
                    props.address,
                    actionAmount._value.toBigInt(),
                    props.ghstSymbol
                );
                break;
            case "UNWRAP":
                await unwrap(
                    props.chainId,
                    props.address,
                    actionAmount._value.toBigInt(),
                    props.stnkSymbol
                );
                break;
            default:
                console.log("Wrong action to be executed!");
        }

        setIsPending(false);
        props.onClose();
    }

    return (
        <Modal
            data-testid="stake-confirmation-modal"
            maxWidth="476px"
            headerContent={
                <Typography variant="h4">{`Confirm ${props.action}`}</Typography>
            }
            open={props.open}
            onClose={() => isPending ? {} : props.onClose()}
            minHeight={"100px"}
        >
            <Box display="flex" flexDirection="column">
                <Box display="flex" flexDirection="row" justifyContent="space-between" alignItems="center">
                    <Box height="170px" display="flex" flexDirection="column">
                        <Metric
                            label={`Assets to Spend`}
                            metric={formatNumber(new DecimalBigNumber(props.amount, props.spendDecimals), 5)}
                        />
                        <Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
                            <Token
                                parentSx={{
                                    height: "80px",
                                    "& svg:nth-of-type(2)": {
                                        transform: "translate(50%, -30%)",
                                        zIndex: 100,
                                    }
                                }}
                                sx={{ transform: "scale(1.65)", }}
                                chainTokenName={props.chainSymbol}
                                name={props.upperToken}
                            />
                        <Typography>{props.upperToken}</Typography>
                        </Box>
                    </Box>
                    <GhostStyledIcon component={ArrowRightIcon} />
                    <Box display="flex" flexDirection="column">
                        <Metric
                            label="Assets to Receive"
                            metric={formatNumber(new DecimalBigNumber(props.receiveAmount, props.receiveDecimals), 5)}
                            />
                        <Box display="flex" flexDirection="column" justifyContent="center" alignItems="center">
                            <Token
                                parentSx={{
                                    height: "80px",
                                    "& svg:nth-of-type(2)": {
                                        transform: "translate(50%, -30%)",
                                        zIndex: 100,
                                    }
                                }}
                                sx={{ transform: "scale(1.65)", }}
                                chainTokenName={props.chainSymbol}
                                name={props.upperToken === props.ftsoSymbol ? props.ghstSymbol : props.ftsoSymbol}
                            />
                            <Typography>{props.bottomToken}</Typography>
                        </Box>
                    </Box>
                </Box>

                <Box sx={{ marginTop: "1.5rem" }}>
                    {acknowledgedWarmup || props.action !== "STAKE" ?
                        <TokenAllowanceGuard
                            spendAmount={new DecimalBigNumber(props.amount, props.spendDecimals)}
                            tokenName={props.upperToken}
                            owner={props.address}
                            spender={STAKING_ADDRESSES[props.chainId]}
                            decimals={props.spendDecimals}
                            approvalText={`Approve ${props.upperToken}`}
                            approvalPendingText={"Approving..."}
                            connect={props.connect}
                            isVertical
                        >
                            <PrimaryButton
                                data-testid="submit-modal-button"
                                loading={isPending}
                                fullWidth
                                disabled={
                                    isPending ||
                                    parseFloat(props.amount) === 0 ||
                                    props.amountExceedsBalance ||
                                    (props.action === "STAKE" && !acknowledgedWarmup)
                                }
                                onClick={() => doAction()}
                            >
                                Confirm
                            </PrimaryButton>
                        </TokenAllowanceGuard>
                        :
                        <NeedsWarmupDetails />
                    }
                </Box>
            </Box>
        </Modal>
    );
};

export default StakeConfirmationModal;
