import { useEffect, useState } from "react";
import PageContainer from "./PageContainer";
import { Box, Grid2 as Grid, TextField, Typography } from "@mui/material";
import { Moment } from "moment";
import { pond } from "protobuf-ts/pond";
import SearchSelect, { Option } from "common/SearchSelect";
import TransactionViewer from "transactions/transactionViewer";
import { TransactionOptions } from "objects/ObjectDescriber";
import { GetDefaultDateRange } from "common/time/DateRange";
import TimeBar from "common/time/TimeBar";
import { useGlobalState, useTransactionAPI } from "providers";
import { Transaction } from "models/Transaction";
import { makeStyles } from "@mui/styles";

const useStyles = makeStyles(() => {
  return ({
    page: {
      padding: 10
    }
  });
});

//this page will have the dropdown selectors to set the variables for query
export default function Transactions() {
  const classes = useStyles();
  const defaultDateRange = GetDefaultDateRange();
  const [startDate, setStartDate] = useState<Moment>(defaultDateRange.start);
  const [endDate, setEndDate] = useState<Moment>(defaultDateRange.end);
  //these two variables are the object type
  const [fromObject, setFromObject] = useState<pond.ObjectType | undefined>(undefined);
  const [toObject, setToObject] = useState<pond.ObjectType | undefined>(undefined);
  //these are simply for controlling what is shown in the select boxes
  const [selectedFromObject, setSelectedFromObject] = useState<Option | null>();
  const [selectedToObject, setSelectedToObject] = useState<Option | null>();
  const transactionOptions = TransactionOptions();
  const transactionAPI = useTransactionAPI();
  const [isLoading, setIsLoading] = useState(false);
  const [totalTransactions, setTotalTransactions] = useState<Transaction[]>([]);
  const [filteredTransactions, setFilteredTransactions] = useState<Transaction[]>([]);
  const [objectNames, setObjectNames] = useState<Map<string, string>>(new Map());
  const [fromName, setFromName] = useState("");
  const [toName, setToName] = useState("");
  const [{as}] = useGlobalState();

  const updateDateRange = (newStartDate: any, newEndDate: any) => {
    let range = GetDefaultDateRange();
    range.start = newStartDate;
    range.end = newEndDate;
    setStartDate(newStartDate);
    setEndDate(newEndDate);
  };

  //useEffect to filter the transactions to show based on the dropdown for object and text boxes for name entry
  useEffect(() => {
    let temp: Transaction[] = [];
    totalTransactions.forEach(trans => {
      if (
        (!fromObject || trans.transaction.fromObject === fromObject) &&
        (!toObject || trans.transaction.toObject === toObject) &&
        (fromName === "" ||
          objectNames
            .get(trans.transaction.fromKey)
            ?.toLowerCase()
            .includes(fromName.toLowerCase())) &&
        (toName === "" ||
          objectNames
            .get(trans.transaction.toKey)
            ?.toLowerCase()
            .includes(toName.toLowerCase()))
      ) {
        temp.push(trans);
      }
    });
    setFilteredTransactions(temp);
  }, [fromObject, toObject, totalTransactions, fromName, toName, objectNames]);

  //useEffect to get the transactions when the timeframe changes
  useEffect(() => {
    if (!isLoading) {
      setIsLoading(true);
      transactionAPI
        .transactionPageData(startDate.toISOString(), endDate.toISOString(), as)
        .then(resp => {
          setTotalTransactions(
            resp.data.transactions.map((t: pond.Transaction) => Transaction.create(t))
          );
          let tempMap: Map<string, string> = new Map();
          Object.keys(resp.data.nameMap).forEach(key => {
            tempMap.set(key, resp.data.nameMap[key]);
          });
          setObjectNames(tempMap);
        })
        .catch(err => {
          console.log("There was a problem loading your inventory transactions");
        })
        .finally(() => {
          setIsLoading(false);
        });
    }
  }, [transactionAPI, startDate, endDate]); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <PageContainer>
      <Box className={classes.page}>
        <TimeBar startDate={startDate} endDate={endDate} updateDateRange={updateDateRange} />
        <Typography>Type</Typography>
        <Grid container direction="row" spacing={2} style={{ margin: 10 }}>
          <Grid>
            <SearchSelect
              style={{ width: 175 }}
              label="From"
              selected={selectedFromObject}
              options={transactionOptions}
              changeSelection={op => {
                setSelectedFromObject(op);
                setFromObject(op?.value);
              }}
            />
          </Grid>
          <Grid>
            <SearchSelect
              style={{ width: 175 }}
              label="To"
              selected={selectedToObject}
              options={transactionOptions}
              changeSelection={op => {
                setSelectedToObject(op);
                setToObject(op?.value);
              }}
            />
          </Grid>
        </Grid>
        <Typography>Name</Typography>
        <Grid container direction="row" spacing={2} style={{ margin: 10 }}>
          <Grid>
            <TextField
              label="From"
              variant="outlined"
              style={{ width: 175 }}
              value={fromName}
              onChange={e => {
                setFromName(e.target.value);
              }}
            />
          </Grid>
          <Grid>
            <TextField
              label="To"
              variant="outlined"
              style={{ width: 175 }}
              value={toName}
              onChange={e => {
                setToName(e.target.value);
              }}
            />
          </Grid>
        </Grid>
        <TransactionViewer
          transactions={filteredTransactions}
          loading={isLoading}
          objectNames={objectNames}
        />
      </Box>
    </PageContainer>
  );
}
