import * as React from "react";
import { useEffect, useState } from "react";
import Box from "@mui/material/Box";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TablePagination from "@mui/material/TablePagination";
import TableRow from "@mui/material/TableRow";
import Typography from "@mui/material/Typography";
import Paper from "@mui/material/Paper";
import Checkbox from "@mui/material/Checkbox";
import IconButton from "@mui/material/IconButton";
import InfoIcon from "@mui/icons-material/Info";
import { makeStyles } from "@mui/styles";
import { TextField } from "@mui/material";
import { Link } from "react-router-dom";
import EnhancedTableToolbar from "./components/enchancedTableToolbar";
import EnhancedTableHead from "./components/enchancedTableHead";
import { stableSort } from "./helpers/sorters";
import { getComparator } from "./helpers/comparators";
import { deleteGamerun, fetchGameruns } from "../../helpers/gameruns";

const rowsPerPage = 6;

const useStyles = makeStyles({
  ellipsis: {
    maxWidth: 200,
    whiteSpace: "nowrap",
    overflow: "hidden",
    textOverflow: "ellipsis",
  },
});

const headCells = [
  {
    id: "id",
    numeric: true,
    disablePadding: true,
    label: "ID",
  },
  {
    id: "player_name",
    numeric: false,
    disablePadding: false,
    label: "Username",
  },
  {
    id: "start_time",
    numeric: false,
    disablePadding: false,
    label: "Start time",
  },
  {
    id: "end_time",
    numeric: false,
    disablePadding: false,
    label: "End time",
  },
];

// Table handling Gameruns
export default function GamerunTable() {
  const classes = useStyles();
  // non searched Gameruns
  const [data, setData] = useState([]);
  // searched Gameruns
  const [searchedData, setSearchedData] = useState([]);
  // keyword
  const [searchedKeyword, setSearchedKeyword] = useState("");
  // selected Gameruns, stored only id of Gamerun
  const [selected, setSelected] = React.useState([]);
  // sorting order = ascending/descending
  const [order, setOrder] = React.useState("asc");
  // which column is used for sorting by default
  const [orderBy, setOrderBy] = React.useState("id");
  // current table page
  const [page, setPage] = React.useState(0);

  // fetch gameruns on render
  useEffect(() => {
    fetchGameruns().then((res) => setData(res));
  }, []);

  // when gameruns are updated (removed or added), search is requested
  useEffect(() => {
    requestSearch();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data, searchedKeyword]);

  const requestSearch = () => {
    setSelected([]); // clear hook with selected Gameruns

    const filteredRows = data.filter((row) => {
      return (
        // search by Gamerun id, player_name, start_time and end_time
        [row.id, row.player_name, row.start_time, row.end_time].filter(
          (text) =>
            !!text &&
            text.toString().toLowerCase().includes(searchedKeyword.toLowerCase())
        ).length > 0
      );
    });

    setSearchedData(filteredRows);
  };

  const handleDeleteSelected = () => {
    let deletedGameruns = [];

    //delete each Gamerun by its id, if successful, add id to deletedEmails
    selected.forEach((gamerun_id) => {
      deleteGamerun(gamerun_id).then(deletedGameruns.push(gamerun_id));
    });

    // filter all Gameruns and check, if they were deleted
    const new_data = data.filter(
      (gamerun) => deletedGameruns.indexOf(gamerun.id) === -1
    );

    setData(new_data);
    setSelected([]);
  };

  // handler for changing order and column used for sorting
  const handleRequestSort = (event, property) => {
    const isAsc = orderBy === property && order === "asc";
    setOrder(isAsc ? "desc" : "asc");
    setOrderBy(property);
  };

  const handleSelectAllClick = (event) => {
    // if checkbox for selecting all Gameruns has been checked
    // add ids of searched Gameruns to selected hook, otherwise clear selected
    if (event.target.checked) {
      const newSelecteds = searchedData.map((n) => n.id);
      setSelected(newSelecteds);
      return;
    }
    setSelected([]);
  };

  // handler for selecting/unselecting row
  const handleClick = (event, id) => {
    const selectedIndex = selected.indexOf(id);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, id);
    } else if (selectedIndex === 0) {
      newSelected = newSelected.concat(selected.slice(1));
    } else if (selectedIndex === selected.length - 1) {
      newSelected = newSelected.concat(selected.slice(0, -1));
    } else if (selectedIndex > 0) {
      newSelected = newSelected.concat(
        selected.slice(0, selectedIndex),
        selected.slice(selectedIndex + 1)
      );
    }

    setSelected(newSelected);
  };

  const handleChangePage = (event, newPage) => {
    setPage(newPage);
  };

  const isSelected = (name) => selected.indexOf(name) !== -1;

  const emptyRows =
    page > 0
      ? Math.max(0, (1 + page) * rowsPerPage - searchedData.length)
      : rowsPerPage - searchedData.length;

  // function used for creating rows in Email table
  const TableCells = (row, isItemSelected) => (
    <React.Fragment>
      {/* TableCell for CheckBox */}
      <TableCell
        padding="checkbox"
        onClick={(event) => handleClick(event, row.id)}
      >
        <Checkbox color="primary" checked={isItemSelected} />
      </TableCell>
      {/* TableCell for gamerun ID */}
      <TableCell
        component="th"
        id={row.id}
        padding="none"
        scope="row"
        align="right"
      >
        <Typography variant="inherit" className={classes.ellipsis}>
          {row.id}
        </Typography>
      </TableCell>
      {/* TableCell for player name */}
      <TableCell>
        <div
          style={{
            overflow: "hidden",
            textOverflow: "ellipsis",
            width: "11rem",
          }}
        >
          {row.player_name}
        </div>
      </TableCell>
      {/* TableCell for start time of Gamerun */}
      <TableCell>
        <Typography variant="inherit" className={classes.ellipsis}>
          {row.start_time}
        </Typography>
      </TableCell>
      {/* TableCell for end time of gamerun */}
      <TableCell>{row.end_time}</TableCell>
      {/* TableCell for InfoIcon, onclick redirects to info page of the Gamerun */}
      <TableCell padding="checkbox">
        <Link to={`gameruns/${row.id}`}>
          <IconButton color="primary">
            <InfoIcon />
          </IconButton>
        </Link>
      </TableCell>
    </React.Fragment>
  );

  return (
    <Box
      justifyContent="center"
      alignContent="center"
      sx={{ display: "flex", width: "100%" }}
    >
      <Paper sx={{ minWidth: "350px", width: "100%" }}>
        <EnhancedTableToolbar
          numSelected={selected.length}
          onDelete={handleDeleteSelected} // handler for deleting rows
          name="Gameruns" // name of table
        />
        {/* Search TextField */}
        <TextField
          style={{ ml: 5 }}
          value={searchedKeyword} // searched keyword
          label="search"
          size="small"
          onChange={(val) => setSearchedKeyword(val.target.value)}
        />
        <TableContainer>
          <Table size="medium">
            <EnhancedTableHead
              numSelected={selected.length}
              order={order}
              orderBy={orderBy}
              onSelectAllClick={handleSelectAllClick}
              onRequestSort={handleRequestSort}
              rowCount={searchedData.length}
              headCells={headCells}
              iconCell={true}
            />

            <TableBody>
              {
                // sort searched Gameruns
                stableSort(searchedData, getComparator(order, orderBy))
                  // get Gameruns for current page
                  .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
                  // map row into cells
                  .map((row) => {
                    // true if row is selected, otherwise false
                    const isItemSelected = isSelected(row.id);

                    return (
                      <TableRow
                        hover
                        role="checkbox"
                        tabIndex={-1}
                        key={row.id}
                        selected={isItemSelected}
                      >
                        {TableCells(row, isItemSelected)}
                      </TableRow>
                    );
                  })
              }
              {
                // generate empty row if there is not enough Gameruns for current page
                emptyRows > 0 && (
                  <TableRow
                    style={{
                      height: 53 * emptyRows,
                    }}
                  >
                    <TableCell colSpan={6} />
                  </TableRow>
                )
              }
            </TableBody>
          </Table>
        </TableContainer>
        <TablePagination
          rowsPerPageOptions={[]}
          labelRowsPerPage=""
          component="div"
          count={data.length}
          rowsPerPage={rowsPerPage}
          page={page}
          onPageChange={handleChangePage}
        />
      </Paper>
    </Box>
  );
}
