import { ArrowBack } from "@mui/icons-material";
import { Box, Link, Skeleton, Typography } from "@mui/material";
import { useEffect, useState, useMemo, useCallback } from "react";
import { Link as RouterLink, useLocation, useParams, useNavigate } from "react-router-dom";
import { useAccount, useSwitchChain } from "wagmi";
import { isAddress } from "viem";
import ReactGA from "react-ga4";

import PageTitle from "../../components/PageTitle/PageTitle";
import Metric from "../../components/Metric/Metric";
import TokenStack from "../../components/TokenStack/TokenStack";

import BondPrice from "./components/BondPrice";
import BondDiscount from "./components/BondDiscount";
import BondInputArea from "./components/BondInputArea";
import BondSettingsModal from "./components/BondSettingsModal";

import NotFound from "../NotFound/NotFound";

import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
import { isNetworkLegacy } from "../../constants";
import { formatCurrency } from "../../helpers";

import { useLocalStorage } from "../../hooks/localstorage";
import { useLiveBonds } from "../../hooks/bonds";
import { useFtsoPrice } from "../../hooks/prices";

const BondModalContainer = ({ chainId, address, config, connect }) => {
    const { id, network } = useParams();
    const { liveBonds } = useLiveBonds(chainId, network);
    const bond = liveBonds.find(bond => bond.id === Number(id));

    if (!bond) return <NotFound />;

    return <BondModal config={config} chainId={chainId} bond={bond} address={address} connect={connect} />;
};

export const BondModal = ({ bond, chainId, address, config, connect }) => {
    const navigate = useNavigate();
    const { network } = useParams();
    const { pathname } = useLocation();

    const [isSettingsOpen, setSettingsOpen] = useState(false);
    const { getStorageValue, setStorageValue } = useLocalStorage();

    const [slippage, setSlippage] = useState(() => getStorageValue(chainId, address, "bond-slippage", "10"));
    const [formatDecimals, setFormatDecimals] = useState(() => getStorageValue(chainId, address, "bond-decimals", "5"));
    const [recipientAddress, setRecipientAddressInner] = useState(() => getStorageValue(chainId, address, "bond-recipient", address));

    useEffect(() => {
        ReactGA.send({ hitType: "pageview", page: pathname });
    }, [])

    const setRecipientAddress = useCallback((value) => {
        setRecipientAddressInner(value);
        if (isAddress(value)) {
            setStorageValue(chainId, address, "bond-recipient", value);
        }
    }, [chainId, address]);

    const setSlippageInner = useCallback((value) => {
        const maybeValue = parseFloat(value);
        if (!maybeValue || parseFloat(value) <= 100) {
            setSlippage(value);
            setStorageValue(chainId, address, "bond-slippage", value);
        }
    }, [chainId, address]);

    const setFormatDecimalsInner = useCallback((value) => {
        if (Number(value) <= 17) {
            setFormatDecimals(value);
            setStorageValue(chainId, address, "bond-decimals", value);
        }
    }, [chainId, address]);

    useEffect(() => {
        const handleKeyDown = (event) => {
            if (event.key === "Escape") isSettingsOpen ? setSettingsOpen(false) : navigate(`/${network}/bonds`);
        };
        window.addEventListener("keydown", handleKeyDown);
        return () => window.removeEventListener("keydown", handleKeyDown);
    }, [network, navigate, isSettingsOpen]);

    const chainSymbol = useMemo(() => {
        const chainSymbol = config?.getClient()?.chain?.nativeCurrency?.symbol;
        if (chainSymbol) return chainSymbol;
        return "WTF";
    }, [config]);

    const preparedQuoteToken = useMemo(() => {
        if (isNetworkLegacy(chainId)) {
            return {
                address: bond.quoteToken.quoteTokenAddress,
                icons: bond.quoteToken.icons,
                name: bond.quoteToken.name,
            }
        }
        return { address: undefined, icons: [chainSymbol], name: chainSymbol };
    }, [bond, chainSymbol, chainId])

    return (
        <Box>
            <PageTitle
                name={
                    <Box display="flex" flexDirection="row" alignItems="center">
                        <Link component={RouterLink} to={`/${network}/bonds`}>
                            <Box display="flex" flexDirection="row">
                                <ArrowBack />
                                <Typography fontWeight="500" marginLeft="9.5px" marginRight="18px">
                                    Back
                                </Typography>
                            </Box>
                        </Link>

                        <TokenStack tokens={preparedQuoteToken.icons} sx={{ fontSize: "27px" }} />
                        <Box display="flex" flexDirection="column" ml={1} justifyContent="center" alignItems="center">
                            <Typography variant="h4" fontWeight={500}>
                                {preparedQuoteToken.name}
                            </Typography>
                        </Box>
                    </Box>
                }
            />

            <Box display="flex" flexDirection="column" alignItems="center">
                <BondSettingsModal
                    open={isSettingsOpen}
                    handleClose={() => setSettingsOpen(false)}
                    slippage={slippage}
                    recipientAddress={recipientAddress}
                    formatDecimals={formatDecimals}
                    onRecipientAddressChange={event => setRecipientAddress(event.currentTarget.value)}
                    onSlippageChange={event => setSlippageInner(event.currentTarget.value)}
                    onDecimalsChange={event => setFormatDecimalsInner(event.currentTarget.value)}
                />

                <Box display="flex" flexDirection="row" justifyContent="space-between" width={["100%", "70%"]} mt="24px">
                    <Metric
                        label={`Bond Price`}
                        metric={
                            bond.isSoldOut ? (
                                "--"
                            ) : (
                                <BondPrice
                                    price={bond.price.inUsd}
                                />
                            )
                        }
                        />
                    <Metric
                        label="Market Price"
                        metric={<TokenPrice priceInUsd={bond.price.marketPriceInUsd} />}
                    />
                    <Metric
                        label="Discount"
                        metric={<BondDiscount discount={bond.discount} textOnly />}
                    />
                </Box>

                <Box width="100%" mt="24px">
                    <BondInputArea
                        chainId={chainId}
                        bond={bond}
                        config={config}
                        connect={connect}
                        address={address}
                        slippage={slippage}
                        recipientAddress={recipientAddress}
                        preparedQuoteToken={preparedQuoteToken}
                        handleSettingsOpen={() => setSettingsOpen(true)}
                        formatDecimals={formatDecimals}
                    />
                </Box>
            </Box>
        </Box>
    );
};

const TokenPrice = ({ priceInUsd }) => {
    return priceInUsd ? (
        <>{formatCurrency(priceInUsd, 2)}</>
    ) : (
        <Skeleton width={60} />
    );
};

export default BondModalContainer;
