import React, { useEffect, useState } from "react";
import { useRecoilValue, useSetRecoilState } from "recoil";
import {
    Box,
    Checkbox,
    Divider,
    FormControlLabel,
    Grid,
    IconButton,
    InputAdornment,
    Table,
    TableBody,
    TableCell,
    TableContainer,
    TableHead,
    TableRow,
    TextField,
    Theme,
    Typography,
    useMediaQuery,
} from "@mui/material";
import { makeStyles } from "@mui/styles";
import { pendingTransactionDetailChanges } from "../../../state/transactions";
import { accountsSeenByUser } from "../../../state/accounts";
import { ShareInput } from "../../ShareInput";
import { Clear, Search as SearchIcon } from "@mui/icons-material";
import { ClearingAccountIcon, PersonalAccountIcon } from "../../style/AbrechnungIcons";

const useStyles = makeStyles((theme: Theme) => ({
    shareValue: {
        marginTop: 8,
        marginBottom: 9,
    },
    checkboxLabel: {
        marginTop: 7,
        marginBottom: 7,
    },
    listItem: {
        paddingLeft: 0,
    },
    divider: {
        marginLeft: 0,
    },
    tableLink: {
        color: theme.palette.text.primary,
        textDecoration: "none",
        display: "block",
        height: "100%",
        width: "100%",
        padding: "16px 0",
    },
    tableLinkCell: {
        padding: "0 16px",
    },
}));

function AccountTableRow({
    transaction,
    account,
    showAdvanced,
    debitorShareValueForAccount,
    showPositions,
    positionValueForAccount,
    debitorValueForAccount,
    updateDebShare,
}) {
    const transactionHasPositions =
        transaction.positions != null && transaction.positions.find((item) => !item.deleted) !== undefined;

    return (
        <TableRow hover>
            <TableCell>
                <Grid container direction="row" alignItems="center">
                    <Grid item>{account.type === "personal" ? <PersonalAccountIcon /> : <ClearingAccountIcon />}</Grid>
                    <Grid item sx={{ ml: 1 }}>
                        <Typography variant="body2" component="span">
                            {account.name}
                        </Typography>
                    </Grid>
                </Grid>
            </TableCell>
            <TableCell width="100px">
                {showAdvanced ? (
                    <ShareInput
                        onChange={(value) => updateDebShare(account.id, value)}
                        value={debitorShareValueForAccount(account.id)}
                    />
                ) : (
                    <Checkbox
                        name={`${account.name}-checked`}
                        checked={transaction.debitor_shares.hasOwnProperty(account.id)}
                        onChange={(event) => updateDebShare(account.id, event.target.checked ? 1.0 : 0)}
                    />
                )}
            </TableCell>
            {showPositions || transactionHasPositions ? (
                <>
                    <TableCell align="right">
                        {positionValueForAccount(account.id).toFixed(2)} {transaction.currency_symbol}
                    </TableCell>
                    <TableCell></TableCell>
                    <TableCell align="right">
                        {debitorValueForAccount(account.id).toFixed(2)} {transaction.currency_symbol}
                    </TableCell>
                    <TableCell></TableCell>
                    <TableCell width="100px" align="right">
                        {(debitorValueForAccount(account.id) + positionValueForAccount(account.id)).toFixed(2)}{" "}
                        {transaction.currency_symbol}
                    </TableCell>
                </>
            ) : (
                <TableCell width="100px" align="right">
                    {(debitorValueForAccount(account.id) + positionValueForAccount(account.id)).toFixed(2)}{" "}
                    {transaction.currency_symbol}
                </TableCell>
            )}
        </TableRow>
    );
}

export default function PurchaseDebitorShares({ group, transaction, showPositions = false }) {
    const classes = useStyles();
    const isSmallScreen = useMediaQuery((theme: Theme) => theme.breakpoints.down("sm"));

    const accounts = useRecoilValue(accountsSeenByUser(group.id));

    const [searchValue, setSearchValue] = useState("");
    const [filteredAccounts, setFilteredAccounts] = useState([]);

    const [showAdvanced, setShowAdvanced] = useState(false);

    const transactionHasPositions =
        transaction.positions != null && transaction.positions.find((item) => !item.deleted) !== undefined;
    const setLocalTransactionDetails = useSetRecoilState(pendingTransactionDetailChanges(transaction.id));

    useEffect(() => {
        for (const share of Object.values(transaction.debitor_shares)) {
            if (share !== 1) {
                setShowAdvanced(true);
                break;
            }
        }
    }, [transaction]);

    useEffect(() => {
        if (searchValue != null && searchValue !== "") {
            setFilteredAccounts(
                accounts.filter((acc) => {
                    return acc.name.toLowerCase().includes(searchValue.toLowerCase());
                })
            );
        } else {
            setFilteredAccounts(accounts);
        }
    }, [searchValue, accounts]);

    const debitorShareValueForAccount = (accountID) => {
        return transaction.debitor_shares && transaction.debitor_shares.hasOwnProperty(accountID)
            ? transaction.debitor_shares[accountID]
            : 0;
    };

    const debitorValueForAccount = (accountID) => {
        if (!transaction.account_balances.hasOwnProperty(accountID)) {
            return 0.0;
        }
        return transaction.account_balances[accountID].common_debitors;
    };

    const positionValueForAccount = (accountID) => {
        if (!transaction.account_balances.hasOwnProperty(accountID)) {
            return 0.0;
        }
        return transaction.account_balances[accountID].positions;
    };

    const updateDebShare = (accountID, value) => {
        if (value === 0) {
            setLocalTransactionDetails((currState) => {
                let newDebitorShares;
                if (currState.debitor_shares === undefined) {
                    newDebitorShares = {
                        ...transaction.debitor_shares,
                    };
                } else {
                    newDebitorShares = {
                        ...currState.debitor_shares,
                    };
                }
                delete newDebitorShares[accountID];
                return {
                    ...currState,
                    debitor_shares: newDebitorShares,
                };
            });
        } else {
            setLocalTransactionDetails((currState) => {
                let newDebitorShares;
                if (currState.debitor_shares === undefined) {
                    newDebitorShares = {
                        ...transaction.debitor_shares,
                        [accountID]: value,
                    };
                } else {
                    newDebitorShares = {
                        ...currState.debitor_shares,
                        [accountID]: value,
                    };
                }
                return {
                    ...currState,
                    debitor_shares: newDebitorShares,
                };
            });
        }
    };

    return (
        <div>
            <Box className={classes.listItem}>
                <Grid container direction="row" justifyContent="space-between">
                    <Typography variant="subtitle1" className={classes.checkboxLabel}>
                        <Box sx={{ display: "flex", alignItems: "flex-end" }}>For whom</Box>
                    </Typography>
                    {transaction.is_wip && (
                        <FormControlLabel
                            control={<Checkbox name={`show-advanced`} />}
                            checked={showAdvanced}
                            onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
                                setShowAdvanced(event.target.checked)
                            }
                            label="Advanced"
                        />
                    )}
                </Grid>
            </Box>
            <Divider variant="middle" className={classes.divider} />
            <TableContainer sx={{ maxHeight: { md: 400 } }}>
                <Table size="small" stickyHeader>
                    <TableHead>
                        <TableRow>
                            <TableCell>
                                {isSmallScreen ? (
                                    "Account"
                                ) : (
                                    <TextField
                                        placeholder="Search ..."
                                        margin="none"
                                        size="small"
                                        value={searchValue}
                                        onChange={(e) => setSearchValue(e.target.value)}
                                        variant="standard"
                                        InputProps={{
                                            startAdornment: (
                                                <InputAdornment position="start">
                                                    <SearchIcon />
                                                </InputAdornment>
                                            ),
                                            endAdornment: (
                                                <InputAdornment position="end">
                                                    <IconButton
                                                        aria-label="clear search input"
                                                        onClick={(e) => setSearchValue("")}
                                                        edge="end"
                                                    >
                                                        <Clear />
                                                    </IconButton>
                                                </InputAdornment>
                                            ),
                                        }}
                                    />
                                )}
                            </TableCell>
                            <TableCell width="100px">Shares</TableCell>
                            {showPositions || transactionHasPositions ? (
                                <>
                                    <TableCell width="100px" align="right">
                                        Positions
                                    </TableCell>
                                    <TableCell width="3px" align="center">
                                        +
                                    </TableCell>
                                    <TableCell width="100px" align="right">
                                        Shared + Rest
                                    </TableCell>
                                    <TableCell width="3px" align="center">
                                        =
                                    </TableCell>
                                    <TableCell width="100px" align="right">
                                        Total
                                    </TableCell>
                                </>
                            ) : (
                                <TableCell width="100px" align="right">
                                    Shared
                                </TableCell>
                            )}
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {filteredAccounts.map((account) => (
                            <AccountTableRow
                                key={account.id}
                                transaction={transaction}
                                account={account}
                                debitorValueForAccount={debitorValueForAccount}
                                debitorShareValueForAccount={debitorShareValueForAccount}
                                positionValueForAccount={positionValueForAccount}
                                showAdvanced={showAdvanced}
                                showPositions={showPositions}
                                updateDebShare={updateDebShare}
                            />
                        ))}
                    </TableBody>
                </Table>
            </TableContainer>
        </div>
    );
}