import { useState, useMemo, useCallback, useEffect } from "react";
import ReactGA from "react-ga4";

import {
    Box,
    Container,
    TableContainer,
    Table,
    TableRow,
    TableBody,
    TableHead,
    TableCell,
    Typography,
    Link,
    OutlinedInput,
    InputLabel,
    FormControl,
    useMediaQuery,
    useTheme
} from "@mui/material";

import GhostStyledIcon from "../../components/Icon/GhostIcon";
import ArrowUpIcon from "../../assets/icons/arrow-up.svg?react";
import { GHOST_GOVERNANCE_ADDRESSES, GHST_ADDRESSES } from "../../constants/addresses";

import Paper from "../../components/Paper/Paper";
import PageTitle from "../../components/PageTitle/PageTitle";
import { PrimaryButton, TertiaryButton } from "../../components/Button";
import { TokenAllowanceGuard } from "../../components/TokenAllowanceGuard/TokenAllowanceGuard";

import { useTokenSymbol, useBalance } from "../../hooks/tokens";
import { useProposalThreshold, useProposalHash, propose } from "../../hooks/governance";
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";

import ProposalModal from "./components/ProposalModal";
import { parseFunctionCalldata } from "./components/functions/index";
import { MY_PROPOSALS_PREFIX } from "./helpers";

const NewProposal = ({ config, address, connect, chainId }) => {
    const isSemiSmallScreen = useMediaQuery("(max-width: 745px)");
    const isSmallScreen = useMediaQuery("(max-width: 650px)");
    const isVerySmallScreen = useMediaQuery("(max-width: 379px)");

    const theme = useTheme();

    const myStoredProposals = localStorage.getItem(`${MY_PROPOSALS_PREFIX}-${address}`);
    const [myProposals, setMyProposals] = useState(
        myStoredProposals ? JSON.parse(myStoredProposals).map(id => BigInt(id)) : []
    );

    const [isPending, setIsPending] = useState(false);
    const [isModalOpened, setIsModalOpened] = useState(false);
    const [proposalFunctions, setProposalFunctions] = useState([]);

    const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
    const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
    const { balance: ghstBalance } = useBalance(chainId, ghstSymbol, address)
    const { threshold } = useProposalThreshold(chainId, ghstSymbol);
    const {
        proposalHash,
        proposalDescription
    } = useProposalHash(chainId, proposalFunctions);

    useEffect(() => {
        const toStore = JSON.stringify(myProposals.map(id => id.toString()));
        localStorage.setItem(`${MY_PROPOSALS_PREFIX}-${address}`, toStore);
    }, [myProposals]);

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

    const addCalldata = (calldata) => setProposalFunctions(prev => [...prev, calldata]);
    const removeCalldata = (index) => setProposalFunctions(prev => prev.filter((_, i) => i !== index));

    const storeProposal = (proposalId) => setMyProposals(prev => [...prev, proposalId]);
    const removeProposal = (proposalId) => setMyProposals(prev => prev.filter(item => item !== proposalId));

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

    const submitProposal = useCallback(async () => {
        setIsPending(true);

        const result = await propose(chainId, address, proposalFunctions, proposalDescription);
        if (result) {
            storeProposal(proposalHash);
            setProposalFunctions([]);
        }

        setIsPending(false);
    }, [chainId, address, proposalHash, proposalFunctions, proposalDescription]);

    return (
        <>
            <ProposalModal
                nativeCurrency={nativeCurrency}
                ftsoSymbol={ftsoSymbol}
                chainId={chainId}
                addCalldata={addCalldata}
                isOpened={isModalOpened}
                closeModal={() => setIsModalOpened(false)}
            />
            <Box>
                <PageTitle name="Create Proposal" subtitle="Submit your proposal to strengthen the DAO" />
                <Container
                    style={{
                        paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
                        paddingRight: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
                        minHeight: "calc(100vh - 128px)",
                        display: "flex",
                        flexDirection: "column",
                        justifyContent: "center"
                    }}
                >
                    <Box sx={{ mt: "15px" }}>
                        <Paper
                            fullWidth
                            enableBackground
                            headerContent={
                                <Box display="flex" alignItems="center" flexDirection="row" gap="5px">
                                    <Typography variant="h6">
                                        Proposal Functions
                                    </Typography>
                                </Box>
                            }
                            topRight={
                                <PrimaryButton variant="text" href="http://ghostchain.io/governance">
                                    Explore Governance
                                </PrimaryButton>
                            }
                        >
                            <Box>
                                <Box>
                                    {proposalFunctions.length === 0 && <Box
                                        width="100%"
                                        display="flex"
                                        flexDirection="column"
                                        justifyContent="center"
                                        alignItems="center"
                                        marginBottom="50px"
                                        marginTop="25px"
                                    >
                                        <Typography variant="subtitle1">
                                            Create new proposal by adding one or more of the functions below.
                                        </Typography>
                                    </Box>}

                                </Box>
                                <Box display="flex" flexDirection="column" alignItems="center">
                                    <Box sx={{ width: isSemiSmallScreen ? "100%" : "350px" }}>
                                        <TokenAllowanceGuard
                                            spendAmount={threshold}
                                            tokenName={ghstSymbol}
                                            owner={address}
                                            spender={GHOST_GOVERNANCE_ADDRESSES[chainId]}
                                            decimals={ghstBalance._decimals}
                                            approvalText={`Approve ${ghstSymbol}`}
                                            approvalPendingText={"Approving..."}
                                            connect={connect}
                                            isVertical
                                        >
                                            <Box display="flex" flexDirection="column" alignItems="center">
                                                <TertiaryButton
                                                    sx={{ maxWidth: isSemiSmallScreen ? "100%" : "350px" }}
                                                    fullWidth
                                                    disabled={isPending}
                                                    onClick={() => setIsModalOpened(true)}
                                                >
                                                    Add New Function
                                                </TertiaryButton>
                                                <PrimaryButton
                                                    disabled={
                                                        proposalFunctions.length === 0 ||
                                                        ghstBalance.lt(threshold) ||
                                                        isPending
                                                    }
                                                    fullWidth
                                                    onClick={() => submitProposal()}
                                                >
                                                    {isPending ? "Submitting..." : "Submit Proposal"}
                                                </PrimaryButton>
                                            </Box>
                                        </TokenAllowanceGuard>
                                    </Box>
                                </Box>
                            </Box>
                        </Paper>

                        {proposalFunctions.length > 0 && <Paper
                            fullWidth
                            enableBackground
                            headerContent={
                                <Box display="flex" alignItems="center" flexDirection="row" gap="5px">
                                    <Typography variant="h6">
                                        Proposal Functions
                                    </Typography>
                                </Box>
                            }
                        >
                            <TableContainer>
                                <Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}>
                                    <TableHead>
                                        <TableRow>
                                            <TableCell align="center" style={{ padding: "8px 0" }}>Function</TableCell>
                                            <TableCell align="center" style={{ padding: "8px 0" }}>Target</TableCell>
                                            <TableCell align="center" style={{ padding: "8px 0" }}>Calldata</TableCell>
                                            <TableCell align="center" style={{ padding: "8px 0" }}>Value</TableCell>
                                        </TableRow>
                                    </TableHead>
                                    <TableBody>{proposalFunctions.map((metadata, index) => {
                                        return parseFunctionCalldata(metadata, index, chainId, nativeCurrency, removeCalldata);
                                    })}</TableBody>
                                </Table>
                            </TableContainer>
                        </Paper>}
                    </Box>
                </Container>
            </Box>
        </>
    )
}

export default NewProposal;
