import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import {
  Checkbox,
  Table,
  TableBody,
  TableCell,
  TableFooter,
  TablePagination,
  TableRow,
} from "@material-ui/core";
import clsx from "clsx";

import { useVehicleContext } from "../../Contexts/VehicleContext";
import { useStatusContext } from "../../Contexts/StatusContext";
import { LocalDateTimeString } from "../../../utils/dates";
import TableHeaderSortable from "../../Table/HeaderSortable";
import { logger } from "../../../services/monitoring";
import ConnectedIcon from "../../Controls/ConnectedIcon";
import ECUList from "../../Controls/ECUList";
import {useLocalStorage} from "../../useLocalStorage";

const tableColumns = [
  {
    id: "vin",
    label: "VIN",
  },
  {
    id: "model",
    label: "Model",
  },
  {
    id: "year",
    label: "Year",
  },
  {
    id: "trim",
    label: "Trim",
  },
  {
    id: "created_at",
    label: "Created",
  },
  {
    id: "updated_at",
    label: "Updated",
  },
];

const PAGE_SIZE = "CAR_SELECTION_TABLE_PAGE_SIZE";

const CarSelectionTable = (props) => {
  const {
    token,
    classes,
    search,
    multiSelect,
    selected,
    onSelect,
    onSelectAll,
  } = props;
  const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10);
  const [pageIndex, setPageIndex] = useState(0);
  const [orderBy, setOrderBy] = useState("vin");
  const [order, setOrder] = useState("asc");
  const { getVehicles, vehicles, totalVehicles } = useVehicleContext();
  const { setMessage } = useStatusContext();
  const { search: searchTerm } = search;
  const sortHandler = (_event, property) => {
    if (property === orderBy) {
      if (order === "asc") {
        setOrder("desc");
      } else {
        setOrder("asc");
      }
    } else {
      setOrderBy(property);
      setOrder("asc");
    }
  };

  const handleChangePageIndex = (_event, newIndex) => {
    setPageIndex(newIndex);
  };

  const handleChangePageSize = (event) => {
    setPageSize(parseInt(event.target.value, 10));
    setPageIndex(0);
  };

  const handleSelectAll = (event) => {
    if (!onSelectAll) return;

    const newSelected = [];
    if (event.target.checked) {
      vehicles.forEach((car) => {
        newSelected.push(car.vin);
      });
    }

    onSelectAll(newSelected);
  };

  const handleSelect = (event, key) => {
    if (!onSelect) return;

    onSelect(event, key);
  };

  useEffect(() => {
    const options = {
      limit: pageSize,
      offset: pageSize * pageIndex,
      order: `${orderBy} ${order}`,
    };
    (async () => {
      try {
        await getVehicles(Object.assign(options, search), token);
      } catch (e) {
        setMessage(e.message);
        logger.warn(e.stack);
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [pageIndex, pageSize, orderBy, order, search, token]);

  useEffect(() => {
    setPageIndex(0);
  }, [search]);

  return (
    <div className={clsx(classes.paper, classes.tableSize)}>
      <Table>
        <TableHeaderSortable
          classes={classes}
          orderBy={orderBy}
          order={order}
          columnData={tableColumns}
          onSortRequest={sortHandler}
          multiSelect={multiSelect}
          onSelectAll={handleSelectAll}
          selectCount={selected ? selected.length : 0}
          rowCount={vehicles ? vehicles.length : 0}
        />
        <TableBody>
          {vehicles.map((row) => {
            const isSelected = selected
              ? selected.indexOf(row.vin) !== -1
              : false;
            return (
              <TableRow key={row.vin}>
                {multiSelect && (
                  <TableCell padding="checkbox">
                    <Checkbox
                      checked={isSelected}
                      onChange={(event) => handleSelect(event, row.vin)}
                    />
                  </TableCell>
                )}
                <TableCell align="center">
                  <ConnectedIcon
                    connected={row.connected}
                    style={{ marginRight: 5 }}
                  />
                  <Link to={`/vehicle-status/${row.vin}`}>{row.vin}</Link>
                  {row.ecu_list && (
                    <>
                      <br />
                      <ECUList
                        list={row.ecu_list}
                        search={searchTerm}
                        searchedOnly={true}
                      />
                    </>
                  )}
                </TableCell>
                <TableCell align="center">{row.model}</TableCell>
                <TableCell align="center">{row.year}</TableCell>
                <TableCell align="center">{row.trim || ""}</TableCell>
                <TableCell align="center">
                  {LocalDateTimeString(row.created)}
                </TableCell>
                <TableCell align="center">
                  {LocalDateTimeString(row.updated)}
                </TableCell>
              </TableRow>
            );
          })}
        </TableBody>
        <TableFooter>
          <TableRow>
            <TablePagination
              rowsPerPageOptions={[5, 10, 25, 100]}
              colSpan={7}
              count={totalVehicles}
              rowsPerPage={pageSize}
              page={pageIndex}
              SelectProps={{
                inputProps: { "aria-label": "rows per page" },
                native: true,
              }}
              onPageChange={handleChangePageIndex}
              onRowsPerPageChange={handleChangePageSize}
            />
          </TableRow>
        </TableFooter>
      </Table>
    </div>
  );
};

CarSelectionTable.propTypes = {
  token: PropTypes.string.isRequired,
  classes: PropTypes.object.isRequired,
  search: PropTypes.object.isRequired,
  multiSelect: PropTypes.bool.isRequired,
  selected: PropTypes.array,
  onSelect: PropTypes.func,
  onSelectAll: PropTypes.func,
  connectionStatus: PropTypes.bool,
};

export default CarSelectionTable;
