/* eslint-disable react/prop-types */
import React, { useState } from 'react';
import { CheckRounded, CloseRounded } from '@mui/icons-material';

import { SORT_ASC, SORT_DESC } from '@/modules/@common/constants/sort';
import { DAY_OPTIONS, PERMISSION_OPTIONS, STATUS_OPTIONS } from '@/modules/designSystem/modules/constants';

import { getKeyByState, getPropsString } from '../helpers';

import Playground from '../Playground/Playground';
import {
  Box,
  Checkbox,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  TableScroll,
  TableSortLabel,
} from '@/mui/components';

import fullNames from '@/modules/designSystem/modules/DataGridSection/internal/fullNamesList.json';

const rows = new Array(105).fill(0).map((n, index) => {
  const getItemArray = (array) => array[index % (array.length - 1)];

  return {
    id: index + 1,
    desk: `D-${index}`,
    email: `${getItemArray(fullNames.firstName)}.${getItemArray(fullNames.lastName)}@gmail.com`,
    verified: index % 5 === 0,
    status: getItemArray(STATUS_OPTIONS),
    permissions: [getItemArray(PERMISSION_OPTIONS)],
    day: getItemArray(DAY_OPTIONS),
  };
});

function descendingComparator(a, b, orderBy) {
  if (b[orderBy] < a[orderBy]) {
    return -1;
  }
  if (b[orderBy] > a[orderBy]) {
    return 1;
  }
  return 0;
}

function getComparator(order, orderBy) {
  return order === SORT_DESC
    ? (a, b) => descendingComparator(a, b, orderBy)
    : (a, b) => -descendingComparator(a, b, orderBy);
}

const headCells = [
  {
    id: 'id',
    headerName: 'Id',
  },
  {
    id: 'email',
    headerName: 'Email',
  },
  {
    id: 'verified',
    align: 'center',
    headerName: 'Verified',
  },
  {
    id: 'status',
    headerName: 'Status',
  },
  {
    id: 'day',
    headerName: 'Day',
  },
  {
    id: 'permissions',
    headerName: 'Permissions',
  },
];

function TableSection() {
  const [order, setOrder] = useState(SORT_ASC);
  const [orderBy, setOrderBy] = useState('id');
  const [selected, setSelected] = useState([]);
  const [page, setPage] = useState(1);
  const [rowsPerPageOptions] = useState([10, 15, 25]);
  const [rowsPerPage, setRowsPerPage] = useState(rowsPerPageOptions[0]);

  const handleClick = (name) => {
    const selectedIndex = selected.indexOf(name);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, name);
    } 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);
  };

  // Avoid a layout jump when reaching the last page with empty rows.
  const indexStart = (page - 1) * rowsPerPage;
  const indexEnd = indexStart + rowsPerPage;

  return (
    <Playground
      title="Table"
      fullWidth
      initialState={[
        {
          type: 'select',
          stateId: 'size',
          options: ['small', 'large'],
          selected: 'large',
        },
        {
          type: 'checkbox',
          stateId: 'inverseScroll',
          selected: false,
        },
        {
          type: 'checkbox',
          stateId: 'inverseYScroll',
          selected: false,
        },
        {
          type: 'checkbox',
          stateId: 'stickyHeader',
          selected: false,
        },
      ]}
      renderCallback={(state) => {
        const props = {
          ...state,
          inverseScroll: undefined,
        };

        const propsString = getPropsString(props);

        return {
          component: (
            <Box key={getKeyByState(state)} sx={{ width: '100%', height: 550 }}>
              <TableContainer>
                <TableScroll inverseScroll={state.inverseScroll} inverseYScroll={state.inverseYScroll}>
                  <Table {...props}>
                    <TableHead>
                      <TableRow>
                        <TableCell padding="checkbox" align="center">
                          <Checkbox
                            color="primary"
                            indeterminate={selected.length > 0 && selected.length < rows.length}
                            checked={rows.length > 0 && selected.length === rows.length}
                            onChange={(event) => {
                              setSelected(event.target.checked ? rows.map((n) => n.id) : []);
                            }}
                            inputProps={{
                              'aria-label': 'select all desserts',
                            }}
                          />
                        </TableCell>
                        {headCells.map((headCell) => (
                          <TableCell
                            key={headCell.id}
                            align={headCell.align}
                            padding={headCell.padding}
                            sortDirection={orderBy === headCell.id ? order : false}
                          >
                            <TableSortLabel
                              active={orderBy === headCell.id}
                              direction={orderBy === headCell.id ? order : SORT_ASC}
                              onClick={() => {
                                const isAsc = orderBy === headCell.id && order === SORT_ASC;
                                setOrder(isAsc ? SORT_DESC : SORT_ASC);
                                setOrderBy(headCell.id);
                              }}
                            >
                              {headCell.headerName}
                            </TableSortLabel>
                          </TableCell>
                        ))}
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {rows
                        .sort(getComparator(order, orderBy))
                        .slice(indexStart, indexEnd)
                        .map((row) => {
                          const isItemSelected = selected.includes(row.id);

                          return (
                            <TableRow
                              key={row.id}
                              hover
                              role="checkbox"
                              aria-checked={isItemSelected}
                              selected={isItemSelected}
                            >
                              <TableCell padding="checkbox" align="center">
                                <Checkbox
                                  color="primary"
                                  checked={isItemSelected}
                                  onClick={() => handleClick(row.id)}
                                />
                              </TableCell>
                              <TableCell>{row.id}</TableCell>
                              <TableCell>{row.email}</TableCell>
                              <TableCell align="center">{row.verified ? <CheckRounded /> : <CloseRounded />}</TableCell>
                              <TableCell noWrap>{row.status}</TableCell>
                              <TableCell>{row.day}</TableCell>
                              <TableCell>{row.permissions.map(({ label }) => label).join(', ')}</TableCell>
                            </TableRow>
                          );
                        })}
                    </TableBody>
                  </Table>
                </TableScroll>
                <TablePagination
                  size={state.size === 'small' ? 'small' : 'medium'}
                  rowsPerPageOptions={rowsPerPageOptions}
                  component="div"
                  count={rows.length}
                  rowsPerPage={rowsPerPage}
                  page={page}
                  onPageChange={(event, newPage) => setPage(newPage)}
                  onRowsPerPageChange={(event) => {
                    setRowsPerPage(parseInt(event.target.value, 10));
                    setPage(1);
                  }}
                />
              </TableContainer>
            </Box>
          ),
          code: `  const [order, setOrder] = useState(SORT_ASC);
  const [orderBy, setOrderBy] = useState('id');
  const [selected, setSelected] = useState([]);
  const [page, setPage] = useState(1);
  const [rowsPerPageOptions] = useState([10, 20, 50]);
  const [rowsPerPage, setRowsPerPage] = useState(rowsPerPageOptions[0]);

  const handleClick = (name) => {
    const selectedIndex = selected.indexOf(name);
    let newSelected = [];

    if (selectedIndex === -1) {
      newSelected = newSelected.concat(selected, name);
    } 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);
  };

<TableContainer>
  <TableScroll>
  <Table${propsString}>
    <TableHead>
      <TableRow>
        <TableCell padding="checkbox" align="center">
          <Checkbox
            color="primary"
            indeterminate={selected.length > 0 && selected.length < rows.length}
            checked={rows.length > 0 && selected.length === rows.length}
            onChange={(event) => {
              setSelected(event.target.checked ? rows.map((n) => n.id) : []);
            }}
            inputProps={{
              'aria-label': 'select all desserts',
            }}
          />
        </TableCell>
        {headCells.map((headCell) => (
          <TableCell
            key={headCell.id}
            align={headCell.align}
            padding={headCell.padding}
            sortDirection={orderBy === headCell.id ? order : false}
          >
            <TableSortLabel
              active={orderBy === headCell.id}
              direction={orderBy === headCell.id ? order : SORT_ASC}
              onClick={() => {
                const isAsc = orderBy === headCell.id && order === SORT_ASC;
                setOrder(isAsc ? SORT_DESC : SORT_ASC);
                setOrderBy(headCell.id);
              }}
            >
              {headCell.headerName}
            </TableSortLabel>
          </TableCell>
        ))}
      </TableRow>
    </TableHead>
    <TableBody>
      {rows.map((row) => {
          const isItemSelected = selected.includes(row.id);

          return (
            <TableRow
              key={row.id}
              hover
              role="checkbox"
              aria-checked={isItemSelected}
              selected={isItemSelected}
            >
              <TableCell padding="checkbox" align="center">
                <Checkbox
                  color="primary"
                  checked={isItemSelected}
                  onClick={() => handleClick(row.id)}
                />
              </TableCell>
              <TableCell>
                {row.id}
              </TableCell>
              <TableCell>
                {row.email}
              </TableCell>
              <TableCell align="center">
                {row.verified ? <CheckRounded /> : <CloseRounded />}
              </TableCell>
              <TableCell noWrap>
                {row.status}
              </TableCell>
              <TableCell>
                {row.day}
              </TableCell>
              <TableCell>
                {row.permissions.map(({ label }) => label).join(', ')}
              </TableCell>
            </TableRow>
          );
        })}
    </TableBody>
  </Table>
</TableScroll>
<TablePagination
  size="${props.size}"
  rowsPerPageOptions={rowsPerPageOptions}
  component="div"
  count={rows.length}
  rowsPerPage={rowsPerPage}
  page={page}
  onPageChange={(event, newPage) => setPage(newPage)}
  onRowsPerPageChange={(event) => {
    setRowsPerPage(parseInt(event.target.value, 10));
    setPage(1);
  }}
/>
</TableContainer>`,
        };
      }}
    />
  );
}

export default TableSection;
