import {
  Box,
  Button,
  Card,
  Drawer,
  Grid2 as Grid,
  IconButton,
  LinearProgress,
  Theme,
  Typography
} from "@mui/material";
import ContractTransactionGraph from "contract/contractTransactionGraph";
import ContractVisualizer from "contract/contractVisualizer";
import { useMobile, useThemeType } from "hooks";
// import { MatchParams } from "navigation/Routes";
import { useContractAPI } from "providers/pond/contractAPI";
import React, { useEffect, useState } from "react";
// import { Redirect, useRouteMatch } from "react-router";
import PageContainer from "./PageContainer";
import { Contract as IContract } from "models/Contract";
import ObjectControls from "common/ObjectControls";
import ContractActions from "contract/contractActions";
import { useGlobalState, useUserAPI } from "providers";
import { pond } from "protobuf-ts/pond";
import { Scope } from "models";
import { Transaction } from "models/Transaction";
import ContractTransactionTable from "contract/contractTransactionTable";
import GrainTransaction from "grain/GrainTransaction";
import NotesIcon from "@mui/icons-material/Notes";
import Chat from "chat/Chat";
import ContractsIcon from "products/CommonIcons/contractIcon";
import { makeStyles } from "@mui/styles";
import { useParams } from "react-router-dom";

interface TabPanelProps {
  children?: React.ReactNode;
  index: any;
  value: any;
}

function TabPanelMine(props: TabPanelProps) {
  const { children, value, index, ...other } = props;

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      aria-labelledby={`simple-tab-${index}`}
      {...other}>
      {value === index && <React.Fragment>{children}</React.Fragment>}
    </div>
  );
}

const useStyles = makeStyles((theme: Theme) => {
  const themeType = useThemeType();
  return ({
    inactiveButton: {
      color: themeType === "light" ? theme.palette.common.black : theme.palette.common.white,
      backgroundColor: "transparent",
      width: theme.spacing(5),
      height: theme.spacing(5),
      border: "1px solid",
      borderColor: theme.palette.divider
    },
    activeButton: {
      color: themeType === "light" ? theme.palette.common.black : theme.palette.common.white,
      backgroundColor: theme.palette.primary.main,
      width: theme.spacing(5),
      height: theme.spacing(5),
      border: "1px solid",
      borderColor: theme.palette.divider
    },
    drawerPaper: {
      height: "100%",
      width: "30%"
    }
  });
});

export default function Contract() {
  // const match = useRouteMatch<MatchParams>();
  // const contractKey = match.params.contractKey;
  const contractKey = useParams<{ contractKey: string }>()?.contractKey ?? "";

  const classes = useStyles();
  const contractAPI = useContractAPI();
  const isMobile = useMobile();
  const [contract, setContract] = useState<IContract>(IContract.create());
  const [validTransactions, setValidTransactions] = useState<Map<string, Transaction>>(new Map());
  //have to use this as the array passed to the bar graph, for whatever reason getting the array from the values of the map causes the labels to not appear
  const [transArray, setTransArray] = useState<Transaction[]>([]);
  const [openGrainTransactionDialog, setOpenGrainTransactionDialog] = useState(false);
  const [displayTab, setDisplayTab] = useState(0);
  const [openNoteDrawer, setOpenNoteDrawer] = useState(false);
  //const [revokedTransactions, setRevokedTransactions] = useState<Transaction[]>([]);
  const userAPI = useUserAPI();
  const [{ user, as }] = useGlobalState();
  const [permissions, setPermissions] = useState<pond.Permission[]>([]);
  const [objectMap, setObjectMap] = useState<Map<string, string>>(new Map());
  const [loading, setLoading] = useState(false);
  // const [invalid, setInvalid] = useState(false);

  useEffect(() => {
    let key = contractKey;
    let kind = "contract";
    if (as) {
      key = as;
      kind = "team";
    }
    userAPI.getUser(user.id(), { key: key, kind: kind } as Scope).then(resp => {
      setPermissions(resp.permissions);
    });
  }, [as, contractKey, userAPI, user]);

  useEffect(() => {
    if (!loading) {
      setLoading(true);
      contractAPI
        .getContractPageData(contractKey, as)
        .then(resp => {
          setContract(IContract.any(resp.data.contract));
          //setValidTransactions(resp.data.transactions.map(t => Transaction.create(t)));
          let valid: Map<string, Transaction> = new Map();
          let tArray: Transaction[] = [];
          resp.data.transactions.forEach(transaction => {
            let t = Transaction.create(transaction);
            if (
              t.transaction.state === pond.TransactionState.TRANSACTION_STATE_VALID ||
              t.transaction.state === pond.TransactionState.TRANSACTION_STATE_CORRECTION
            ) {
              valid.set(t.transaction.key, t);
              tArray.push(t);
            }
            // else {
            //   revoked.push(t);
            // }
          });
          setValidTransactions(valid);
          setTransArray(tArray);
          //setRevokedTransactions(revoked);
          let tempMap: Map<string, string> = new Map();
          Object.keys(resp.data.nameMap).forEach(key => {
            tempMap.set(key, resp.data.nameMap[key]);
          });
          setObjectMap(tempMap);
          setLoading(false);
        })
        .catch(err => {
          //setInvalid(true);
        });
    }
  }, [contractKey, contractAPI, as]); // eslint-disable-line react-hooks/exhaustive-deps

  const contractDisplay = () => {
    return (
      <React.Fragment>
        {isMobile ? (
          <Grid
            container
            alignContent="center"
            alignItems="center"
            direction="row"
            style={{ marginBottom: 15 }}>
            <Grid size={9}>
              <Typography style={{ paddingRight: 20, fontSize: 30, fontWeight: 650 }} noWrap>
                {contract.name()}
              </Typography>
            </Grid>
            <Grid size={3}>
              <Button
                variant="contained"
                color="primary"
                disabled={!permissions.includes(pond.Permission.PERMISSION_WRITE)}
                onClick={e => {
                  setOpenGrainTransactionDialog(true);
                }}>
                + Add Delivery
              </Button>
            </Grid>
          </Grid>
        ) : (
          <Box display="flex" flexDirection="row" marginBottom={2}>
            <Typography style={{ paddingRight: 20, fontSize: 30, fontWeight: 650 }} noWrap>
              {contract.name()}
            </Typography>
            <Button
              variant="contained"
              color="primary"
              disabled={!permissions.includes(pond.Permission.PERMISSION_WRITE)}
              onClick={e => {
                setOpenGrainTransactionDialog(true);
              }}>
              + Add Delivery
            </Button>
          </Box>
        )}

        <Grid container spacing={2} direction={"row"}>
          <Grid size={isMobile ? 12 : 4} style={{ height: isMobile ? 300 : 400 }}>
            <ContractVisualizer contract={contract} />
          </Grid>
          <Grid size={isMobile ? 12 : 8} style={{ height: isMobile ? 300 : 400 }}>
            <ContractTransactionGraph contract={contract} transactions={transArray} />
          </Grid>
          <Grid size={12}>
            <ContractTransactionTable
              permissions={permissions}
              contract={contract}
              transactions={transArray}
              objectNames={objectMap}
              transactionRevokedCallback={t => {
                let vt = validTransactions;
                vt.delete(t);
                setValidTransactions(vt);
                setTransArray(Array.from(vt.values()));
              }}
            />
          </Grid>
        </Grid>
      </React.Fragment>
    );
  };

  return (
    <PageContainer>
      <ObjectControls
        actions={
          <ContractActions
            contract={contract}
            permissions={permissions}
            refreshCallback={() => {}}
          />
        }
        objectButton={
          <IconButton
            size="small"
            style={{
              marginTop: "0.3625rem",
              marginBottom: "0.3625rem",
              marginRight: "0.5rem"
            }}
            onClick={() => {
              setDisplayTab(0);
            }}
            className={displayTab === 0 ? classes.activeButton : classes.inactiveButton}
            component="span">
            <ContractsIcon />
          </IconButton>
        }
        notesButton={
          <IconButton
            onClick={() => {
              if (isMobile) {
                setDisplayTab(1);
              } else {
                setOpenNoteDrawer(true);
              }
            }}
            size="small"
            style={{
              marginTop: "0.3625rem",
              marginBottom: "0.3625rem",
              marginRight: "0.5rem"
            }}
            className={displayTab === 1 ? classes.activeButton : classes.inactiveButton}
            component="span">
            <NotesIcon />
          </IconButton>
        }
      />
      <Box margin={2} marginTop={0}>
        {loading ? (
          <LinearProgress />
        ) : (
          <React.Fragment>
            <TabPanelMine value={displayTab} index={0}>
              {contractDisplay()}
            </TabPanelMine>
            <TabPanelMine value={displayTab} index={1}>
              <Typography style={{ paddingRight: 20, fontSize: 30, fontWeight: 650 }}>
                {contract.name()} - Notes
              </Typography>
              <Card style={{ padding: 10, marginTop: 15 }}>
                <Chat objectKey={contract.key()} type={pond.NoteType.NOTE_TYPE_CONTRACT} />
              </Card>
            </TabPanelMine>
          </React.Fragment>
        )}
      </Box>
      <GrainTransaction
        open={openGrainTransactionDialog}
        mainObject={contract}
        allowAttachmentUploads
        restrictMatching
        asDestination
        close={() => {
          setOpenGrainTransactionDialog(false);
        }}
        callback={t => {
          setOpenGrainTransactionDialog(false);
          if (t) {
            let transactions = validTransactions;
            transactions.set(t.key, Transaction.create(t));
            setValidTransactions(transactions);
            setTransArray(Array.from(transactions.values()));
          }
        }}
      />
      <Drawer
        open={openNoteDrawer}
        onClose={() => {
          setOpenNoteDrawer(false);
        }}
        anchor="right"
        classes={{ paper: classes.drawerPaper }}>
        <Box padding={2}>
          <Typography>Notes</Typography>
          <Card style={{ padding: 10 }}>
            <Chat objectKey={contract.key()} type={pond.NoteType.NOTE_TYPE_CONTRACT} />
          </Card>
        </Box>
      </Drawer>
    </PageContainer>
  );
}
