import {
    Box,
    Link,
    SvgIcon,
    Table,
    TableBody,
    TableCell,
    TableContainer,
    TableHead,
    TableRow,
    Typography,
    useMediaQuery
} from "@mui/material";
import { NavLink, useParams } from "react-router-dom";
import ArrowUp from "../../../assets/icons/arrow-up.svg?react";

import BondDiscount from "./BondDiscount";
import BondDuration from "./BondDuration";
import BondInfoText from "./BondInfoText";
import BondPrice from "./BondPrice";

import { useScreenSize } from "../../../hooks/useScreenSize";
import { sortBondsByDiscount, formatNumber } from "../../../helpers";
import TokenStack from "../../../components/TokenStack/TokenStack";
import { TertiaryButton } from "../../../components/Button";

export const BondList = ({ bonds, secondsTo, chainId }) => {
    const isSmallScreen = useScreenSize("md");
    const { network } = useParams();

    if (bonds.length === 0) {
        return (
            <Box display="flex" justifyContent="center">
                <Typography variant="h4">No active bonds</Typography>
            </Box>
        );
    }

    if (isSmallScreen) {
        return (
            <>
                <Box my="24px" textAlign="center">
                    <BondInfoText />
                </Box>

                {sortBondsByDiscount(bonds).map(bond => (
                    <BondCard key={bond.id} secondsTo={secondsTo} bond={bond} chainName={network} />
                ))}
            </>
        );
    }

    return (
        <>
            <BondTable>
                {sortBondsByDiscount(bonds).map(bond => (
                    <BondRow key={bond.id} bond={bond} secondsTo={secondsTo} chainName={network} />
                ))}
            </BondTable>

            <Box mt="24px" textAlign="center" width="70%" mx="auto">
                <BondInfoText />
            </Box>
        </>
    );
};

const BondCard = ({ bond, secondsTo, chainName }) => {
    const quoteTokenName = bond.quoteToken.name;
    const baseTokenName = bond.baseToken.name;

    return (
        <Box key={bond.id} id={bond.id + `--bond`} mt="32px">
            <Box display="flex" alignItems="center">
                <TokenStack tokens={bond.quoteToken.icons} />

                <Box display="flex" flexDirection="column" ml="8px">
                    <Typography>{bond.quoteToken.name}</Typography>

                    <Link href={bond.quoteToken.purchaseUrl} target="_blank" rel="noopener noreferrer">
                        <Box display="flex" alignItems="center">
                            <Typography>Get Asset</Typography>

                            <Box ml="4px">
                                <SvgIcon component={ArrowUp} />
                            </Box>
                        </Box>
                    </Link>
                </Box>
            </Box>

            <Box display="flex" justifyContent="space-between" mt="16px">
                <Typography>Price</Typography>

                <Typography component={'span'}>
                    {bond.isSoldOut ? (
                        "--"
                    ) : (
                        <BondPrice price={bond.price.inUsd} />
                    )}
                </Typography>
            </Box>

            <Box display="flex" justifyContent="space-between" mt="8px">
                <Typography>Discount</Typography>
                <Typography component={'span'}>{
                    bond.isSoldOut
                        ? "--"
                        : <BondDiscount discount={bond.discount} />
                }</Typography>
            </Box>

            <Box display="flex" justifyContent="space-between" mt="8px">
                <Typography>Max Payout</Typography>

                <Typography>
                    {`${payoutTokenCapacity(bond)}${
                        bond.baseToken.name !== bond.quoteToken.name ? ` (${quoteTokenCapacity(bond)})` : ``
                    }`}
                </Typography>
            </Box>

            <Box display="flex" justifyContent="space-between" mt="8px">
                <Typography>Duration</Typography>

                <Typography component={'span'}>
                    <BondDuration secondsTo={secondsTo} duration={bond.duration} />
                </Typography>
            </Box>

            <Box mt="16px">
                <Link
                    component={NavLink}
                    to={`/${chainName}/bonds/${bond.id}`}
                    sx={{ pointerEvents: bond.isSoldOut ? 'none' : 'auto' }}
                >
                    <TertiaryButton fullWidth disabled={bond.isSoldOut}>
                        {bond.isSoldOut ? "Sold Out" : `Bond`}
                    </TertiaryButton>
                </Link>
            </Box>
        </Box>
    );
};

const BondTable = ({ children }) => (
    <TableContainer>
        <Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}>
            <TableHead>
                <TableRow>
                    <TableCell style={{ padding: "8px 0", width: "162px" }}>Bond</TableCell>
                    <TableCell style={{ padding: "8px 0", width: "146px" }}>Price</TableCell>
                    <TableCell style={{ padding: "8px 0", width: "92px" }}>Discount</TableCell>
                    <TableCell style={{ padding: "8px 0" }}>Max Payout</TableCell>
                    <TableCell style={{ padding: "8px 0" }}>Duration</TableCell>
                </TableRow>
            </TableHead>

            <TableBody>{children}</TableBody>
        </Table>
    </TableContainer>
);

const quoteTokenCapacity = (bond) => {
    const quoteTokenCapacity = bond.maxPayout.inQuoteToken.lt(bond.capacity.inQuoteToken)
        ? bond.maxPayout.inQuoteToken
        : bond.capacity.inQuoteToken;
    return `${formatNumber(quoteTokenCapacity, 4)} ${bond.quoteToken.name}`;
};

const payoutTokenCapacity = (bond) => {
    const payoutTokenCapacity = bond.maxPayout.inBaseToken.lt(bond.capacity.inBaseToken)
        ? bond.maxPayout.inBaseToken
        : bond.capacity.inBaseToken;
    return `${formatNumber(payoutTokenCapacity, 4)} ${bond.baseToken.name}`;
};

const BondRow = ({ bond, secondsTo, chainName }) => {
    const quoteTokenName = bond.quoteToken.name;
    const baseTokenName = bond.baseToken.name;

    return (
        <TableRow id={bond.id + `--bond`} data-testid={bond.id + `--bond`}>
            <TableCell style={{ padding: "8px 0" }}>
                <TokenIcons token={bond.quoteToken} />
            </TableCell>

            <TableCell style={{ padding: "8px 0" }}>
                <Typography>
                    {bond.isSoldOut ? (
                        "--"
                    ) : (
                        <BondPrice price={bond.price.inUsd} />
                    )}
                </Typography>
            </TableCell>

            <TableCell style={{ padding: "8px 0" }}>
                <Typography component="div">
                    {bond.isSoldOut ? "--" : <BondDiscount discount={bond.discount} />}
                </Typography>
            </TableCell>

            <TableCell style={{ padding: "8px 0" }}>
                <Box display="flex" flexDirection={"column"}>
                    <Typography style={{ lineHeight: "20px" }}>{payoutTokenCapacity(bond)}</Typography>
                    {bond.baseToken.name !== bond.quoteToken.name && (
                        <Typography color="textSecondary" style={{ fontSize: "12px", fontWeight: 400, lineHeight: "18px" }}>
                            {quoteTokenCapacity(bond)}
                        </Typography>
                    )}
                </Box>
            </TableCell>

            <TableCell style={{ padding: "8px 0" }}>
                <Typography>{
                    bond.isSoldOut
                    ? "--"
                    : <BondDuration secondsTo={secondsTo} duration={bond.duration} />
                }</Typography>
            </TableCell>

            <TableCell style={{ padding: "8px 0" }}>
                <Link
                    component={NavLink}
                    to={`/${chainName}/bonds/${bond.id}`}
                    sx={{ pointerEvents: bond.isSoldOut ? 'none' : 'auto' }}
                >
                    <TertiaryButton fullWidth disabled={bond.isSoldOut}>
                        {bond.isSoldOut ? "Sold Out" : `Bond`}
                    </TertiaryButton>
                </Link>
            </TableCell>
        </TableRow>
    );
};

const TokenIcons = ({ token, chainId, explorer }) => (
    <Box display="flex" alignItems="center">
        <TokenStack tokens={token.icons} />

        <Box display="flex" flexDirection="column" ml="16px">
            <Typography style={{ fontSize: "12px", fontWeight: 600, lineHeight: "18px" }}>{token.name}</Typography>

            <Link
                color="primary"
                target="_blank"
                href={explorer ? `https://etherscan.io/token/${token.addresses[chainId]}` : token.purchaseUrl}
                >
                <Box display="flex" alignItems="center">
                    <Typography style={{ fontSize: "12px", lineHeight: "18px" }}>
                        {explorer ? `Explorer` : `Get Asset`}
                    </Typography>

                    <Box ml="4px">
                        <SvgIcon component={ArrowUp} />
                    </Box>
                </Box>
            </Link>
        </Box>
    </Box>
);
