import * as React from 'react';
import { useTheme } from '@mui/material/styles';
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 TableFooter from '@mui/material/TableFooter';
import TablePagination from '@mui/material/TablePagination';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';
import IconButton from '@mui/material/IconButton';
import FirstPageIcon from '@mui/icons-material/FirstPage';
import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft';
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
import LastPageIcon from '@mui/icons-material/LastPage';
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle,
  TableHead
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import DeleteDialog from '../Shared/DeleteDialog';
import Drug from '../../interfaces/Drug';
import { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import axios from 'axios';
import { loadDrugs } from '../../redux/slices/drugSlice';
import { getWebSocket } from '../../redux/selectors';

interface TablePaginationActionsProps {
  count: number;
  page: number;
  rowsPerPage: number;
  onPageChange: (
    event: React.MouseEvent<HTMLButtonElement>,
    newPage: number
  ) => void;
}

function TablePaginationActions(props: TablePaginationActionsProps) {
  const theme = useTheme();
  const { count, page, rowsPerPage, onPageChange } = props;

  const handleFirstPageButtonClick = (
    event: React.MouseEvent<HTMLButtonElement>
  ) => {
    onPageChange(event, 0);
  };

  const handleBackButtonClick = (
    event: React.MouseEvent<HTMLButtonElement>
  ) => {
    onPageChange(event, page - 1);
  };

  const handleNextButtonClick = (
    event: React.MouseEvent<HTMLButtonElement>
  ) => {
    onPageChange(event, page + 1);
  };

  const handleLastPageButtonClick = (
    event: React.MouseEvent<HTMLButtonElement>
  ) => {
    onPageChange(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1));
  };

  return (
    <Box sx={{ flexShrink: 0, ml: 2.5 }}>
      <IconButton
        onClick={handleFirstPageButtonClick}
        disabled={page === 0}
        aria-label='first page'
      >
        {theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
      </IconButton>
      <IconButton
        onClick={handleBackButtonClick}
        disabled={page === 0}
        aria-label='previous page'
      >
        {theme.direction === 'rtl' ? (
          <KeyboardArrowRight />
        ) : (
          <KeyboardArrowLeft />
        )}
      </IconButton>
      <IconButton
        onClick={handleNextButtonClick}
        disabled={page >= Math.ceil(count / rowsPerPage) - 1}
        aria-label='next page'
      >
        {theme.direction === 'rtl' ? (
          <KeyboardArrowLeft />
        ) : (
          <KeyboardArrowRight />
        )}
      </IconButton>
      <IconButton
        onClick={handleLastPageButtonClick}
        disabled={page >= Math.ceil(count / rowsPerPage) - 1}
        aria-label='last page'
      >
        {theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
      </IconButton>
    </Box>
  );
}

const DrugTable = () => {
  const dispatch = useDispatch();
  const [page, setPage] = useState(
    sessionStorage.getItem('page')
      ? parseInt(sessionStorage.getItem('page') as string)
      : 0
  );
  const ws = useSelector(getWebSocket);

  const [sort, setSort] = useState('');
  const [open, setOpen] = useState(-1);
  const [drugs, setDrugs] = useState<Drug[]>([]);
  const [total, setTotal] = useState(0);
  const [error, setError] = useState(false);

  const navigate = useNavigate();

  const handleViewClick = (id: number) => {
    navigate(`/details/${id}`);
  };
  const handleUpdateClick = (id: number) => {
    navigate(`/update/${id}`);
  };

  const handleDeleteClick = (id: number) => {
    setOpen(id);
  };

  const [rowsPerPage, setRowsPerPage] = React.useState(
    sessionStorage.getItem('rowsPerPage')
      ? parseInt(sessionStorage.getItem('rowsPerPage') as string, 10)
      : 5
  );

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

  const handleChangePage = (
    _event: React.MouseEvent<HTMLButtonElement> | null,
    newPage: number
  ) => {
    setPage(newPage);
    sessionStorage.setItem('page', newPage.toString());
  };

  const handleChangeRowsPerPage = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(0);
    sessionStorage.setItem('rowsPerPage', event.target.value);
  };

  const fetchData = useCallback(async () => {
    try {
      const response = await axios.get(
        `https://silkroadapi.azurewebsites.net/Drug/get-drugs?Page=${
          page + 1
        }&PageSize=${rowsPerPage}&sorting=${sort}`,
        { withCredentials: true }
      );
      dispatch(loadDrugs(response.data.items));
      setDrugs(response.data.items);
      setTotal(response.data.total);
    } catch (err) {
      console.error(err);
      setError(true);
    }
  }, [dispatch, page, rowsPerPage, sort]);

  useEffect(() => {
    fetchData();
  }, [page, sort, dispatch, rowsPerPage, fetchData]);

  useEffect(() => {
    console.log(ws);
    ws?.addEventListener('message', (event) => {
      console.log(event.data);
      fetchData();
    });
  }, [fetchData, ws]);

  return (
    <TableContainer component={Paper}>
      <Table sx={{ minWidth: 500 }} aria-label='custom pagination table'>
        <TableHead>
          <TableRow>
            <TableCell
              data-asc={'false'}
              onClick={(e) => {
                setSort(
                  e.currentTarget.dataset.asc === 'false' ? 'name' : 'name_desc'
                );
                e.currentTarget.dataset.asc =
                  e.currentTarget.dataset.asc === 'false' ? 'true' : 'false';
              }}
              sx={{ cursor: 'pointer' }}
            >
              Name
            </TableCell>
            <TableCell
              align='right'
              onClick={(e) => {
                setSort(
                  e.currentTarget.dataset.asc === 'false'
                    ? 'manufacturer'
                    : 'manufacturer_desc'
                );
                e.currentTarget.dataset.asc =
                  e.currentTarget.dataset.asc === 'false' ? 'true' : 'false';
              }}
              sx={{ cursor: 'pointer' }}
            >
              Manufacturer
            </TableCell>
            <TableCell
              align='right'
              onClick={(e) => {
                setSort(
                  e.currentTarget.dataset.asc === 'false'
                    ? 'price'
                    : 'price_desc'
                );
                e.currentTarget.dataset.asc =
                  e.currentTarget.dataset.asc === 'false' ? 'true' : 'false';
              }}
              sx={{ cursor: 'pointer' }}
            >
              Price (USD)
            </TableCell>
            <TableCell align='right'>View</TableCell>
            <TableCell align='right'>Update</TableCell>
            <TableCell align='right'>Delete</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {drugs.map((drug) => (
            <TableRow key={drug.id}>
              <TableCell component='th' scope='row'>
                {drug.name}
              </TableCell>
              <TableCell style={{ width: 160 }} align='right'>
                {drug.manufacturer}
              </TableCell>
              <TableCell style={{ width: 160 }} align='right'>
                ${drug.price}
              </TableCell>
              <TableCell style={{ width: 160 }} align='right'>
                <Button
                  variant='outlined'
                  onClick={() => {
                    handleViewClick(drug.id);
                  }}
                >
                  View
                </Button>
              </TableCell>
              <TableCell style={{ width: 160 }} align='right'>
                <Button
                  variant='outlined'
                  onClick={() => {
                    handleUpdateClick(drug.id);
                  }}
                >
                  Update
                </Button>
              </TableCell>
              <TableCell style={{ width: 160 }} align='right'>
                <Button
                  variant='outlined'
                  onClick={() => {
                    handleDeleteClick(drug.id);
                  }}
                >
                  Delete
                </Button>
              </TableCell>
            </TableRow>
          ))}
          {emptyRows > 0 && (
            <TableRow style={{ height: 53 * emptyRows }}>
              <TableCell colSpan={6} />
            </TableRow>
          )}
        </TableBody>
        <TableFooter>
          <TableRow>
            <TablePagination
              rowsPerPageOptions={[5, 10, 25]}
              colSpan={3}
              count={total}
              rowsPerPage={rowsPerPage}
              page={page}
              slotProps={{
                select: {
                  inputProps: {
                    'aria-label': 'rows per page'
                  },
                  native: true
                }
              }}
              onPageChange={handleChangePage}
              onRowsPerPageChange={handleChangeRowsPerPage}
              ActionsComponent={TablePaginationActions}
            />
          </TableRow>
        </TableFooter>
      </Table>
      <DeleteDialog
        id={open}
        handleClose={() => {
          setOpen(-1);
        }}
        handleAgree={async () => {
          await axios.delete(
            `https://silkroadapi.azurewebsites.net/Drug/delete-drug/${open}`,
            { withCredentials: true }
          );
          await fetchData();
          setOpen(-1);
        }}
      />
      <Dialog
        open={error}
        aria-labelledby='alert-dialog-title'
        aria-describedby='alert-dialog-description'
      >
        <DialogTitle id='alert-dialog-title'>{'Error'}</DialogTitle>
        <DialogContent>
          <DialogContentText id='alert-dialog-description'>
            Error while connecting
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button
            onClick={() => {
              setError(false);
            }}
            color='primary'
          >
            Close
          </Button>
        </DialogActions>
      </Dialog>
    </TableContainer>
  );
};

export default DrugTable;
