import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import dayjs from 'dayjs';
import timezonePlugin from 'dayjs/plugin/timezone';
import utcPlugin from 'dayjs/plugin/utc';
import { useRouter } from 'next/router';
import { AccessTime, Add, ContentCopy, DeleteRounded, Download, SearchRounded } from '@mui/icons-material';

import { NAME_MAX_LENGTH, TABLE_HEADERS } from '../constants';
import { SORT_ASC, SORT_DESC } from '@/modules/@common/constants/sort';

import * as selectors from '../redux/selectors';
import * as actions from '../redux/slices';
import { getUserEmailSelector, getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';

import {
  Box,
  Button,
  IconButton,
  InputAdornment,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  TableScroll,
  TableSortLabel,
  TextField,
  Tooltip,
  Typography,
} from '@/mui/components';

import styles from './CustomReports.module.scss';

dayjs.extend(utcPlugin);
dayjs.extend(timezonePlugin);

function CustomReports() {
  const dispatch = useDispatch();

  const userTimezone = useSelector(getUserTimezoneSelector);
  const userEmail = useSelector(getUserEmailSelector);

  const searchText = useSelector(selectors.searchTextSelector);
  const page = useSelector(selectors.pageSelector);
  const pageSize = useSelector(selectors.pageSizeSelector);
  const sortBy = useSelector(selectors.sortBySelector);
  const sortOrder = useSelector(selectors.sortOrderSelector);
  const records = useSelector(selectors.recordsSelector);
  const recordsTotal = useSelector(selectors.recordsTotalSelector);
  const isDownloading = useSelector(selectors.isDownloadingSelector);

  const router = useRouter();

  const fetchData = (payload) => {
    dispatch(actions.getCustomReportsAction(payload));
  };

  useEffect(() => {
    fetchData();
  }, []);

  const handleRowClick = (id) => {
    router.push(`/custom-reports-new/${id}`);
  };

  const onSearch = (value) => {
    dispatch(
      actions.setFieldAction({
        searchText: value,
        page: 0,
      }),
    );
    fetchData(value);
  };

  const handleSorting = (id) => {
    const isAsc = sortBy === id && sortOrder === 'ASC';

    dispatch(
      actions.setFieldAction({
        sortOrder: isAsc ? 'DESC' : 'ASC',
        sortBy: id,
        page: 0,
      }),
    );

    fetchData();
  };

  return (
    <div className={styles.Wrapper}>
      <Stack direction="column" fullWidth justifyContent="center" className={styles.Title}>
        <Typography component="div" variant="h6" noWrap>
          Custom Reports
        </Typography>
      </Stack>
      <Stack
        spacing={1}
        fullWidth
        direction="row"
        alignItems="center"
        justifyContent="space-between"
        className={styles.Controls}
      >
        <TextField
          className={styles.Search}
          placeholder="Search by report name or owner"
          value={searchText}
          onChange={(event) => onSearch(event.target.value)}
          InputProps={{
            endAdornment: (
              <InputAdornment position="end">
                <IconButton onClick={() => onSearch(searchText)}>
                  <SearchRounded />
                </IconButton>
              </InputAdornment>
            ),
          }}
          variant="outlined"
          size="small"
        />

        <Stack spacing={2} justifyContent="flex-end" alignItems="center" direction="row">
          <Button
            data-id="add-new-report"
            size="small"
            onClick={() => {
              router.push('/custom-reports-new/new');
            }}
            startIcon={<Add />}
          >
            Report
          </Button>
        </Stack>
      </Stack>
      <div className={styles.TableWrap}>
        <TableContainer>
          <TableScroll>
            <Table aria-label="table">
              <TableHead>
                <TableRow>
                  {TABLE_HEADERS.map((header, index) => (
                    <TableCell key={`${header.id}-${index + 1}`} className={styles.Cell}>
                      {header.isSortable && (
                        <TableSortLabel
                          active={sortBy === header.id}
                          direction={sortBy === header.id ? sortOrder?.toLowerCase() : SORT_ASC}
                          onClick={() => {
                            handleSorting(header.id);
                          }}
                        >
                          {header.label}
                          {sortBy === header.id ? (
                            <Box component="span" className={styles.VisibilityHidden}>
                              {sortOrder === SORT_DESC ? 'sorted descending' : 'sorted ascending'}
                            </Box>
                          ) : null}
                        </TableSortLabel>
                      )}
                      {!header.isSortable && header.label}
                    </TableCell>
                  ))}
                </TableRow>
              </TableHead>
              <TableBody>
                {records?.map(({ id, name, createdAt, updatedAt, createdBy, lastDelivery, nextDelivery }) => (
                  <TableRow
                    className={styles.Row}
                    key={id}
                    onClick={() => {
                      handleRowClick(id);
                    }}
                  >
                    <TableCell className={styles.Cell}>
                      {name?.length > NAME_MAX_LENGTH ? (
                        <Tooltip title={name} placement="top">
                          {`${name.slice(0, NAME_MAX_LENGTH)}...`}
                        </Tooltip>
                      ) : (
                        name
                      )}
                    </TableCell>
                    <TableCell className={styles.Cell}>{createdBy}</TableCell>
                    <TableCell className={styles.Cell}>
                      {dayjs(createdAt).tz(userTimezone).format('MMM DD, YYYY, hh:mm A')}
                    </TableCell>
                    <TableCell className={styles.Cell}>
                      {updatedAt ? dayjs(updatedAt).tz(userTimezone).format('MMM DD, YYYY, hh:mm A') : ''}
                    </TableCell>
                    <TableCell>
                      <AccessTime htmlColor={nextDelivery ? 'success.main' : 'error.main'} />
                    </TableCell>
                    <TableCell className={styles.Cell}>
                      {lastDelivery ? dayjs(lastDelivery).tz(userTimezone).format('MMM DD, YYYY, hh:mm A') : ''}
                    </TableCell>
                    <TableCell className={styles.Cell}>
                      {nextDelivery ? dayjs(nextDelivery).tz(userTimezone).format('MMM DD, YYYY, hh:mm A') : ''}
                    </TableCell>
                    <TableCell>
                      <div className={styles.RowButtons}>
                        {userEmail === createdBy && (
                          <IconButton
                            size="small"
                            onClick={(e) => {
                              e.stopPropagation();
                              dispatch(
                                actions.runDownloadReportAction({
                                  id,
                                  name,
                                  requestFullInfo: true,
                                }),
                              );
                            }}
                            disabled={isDownloading}
                          >
                            <Download />
                          </IconButton>
                        )}

                        <IconButton
                          size="small"
                          onClick={(e) => {
                            e.stopPropagation();
                            router.push(`/custom-reports-new/${id}?duplicate=true`);
                          }}
                        >
                          <ContentCopy />
                        </IconButton>

                        {userEmail === createdBy && (
                          <IconButton
                            size="small"
                            color="error"
                            onClick={(e) => {
                              e.stopPropagation();
                              dispatch(actions.deleteCustomReportAction({ id }));
                            }}
                          >
                            <DeleteRounded />
                          </IconButton>
                        )}
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableScroll>
          <TablePagination
            component="div"
            rowsPerPageOptions={[10, 25, 50]}
            count={recordsTotal}
            rowsPerPage={pageSize}
            page={page}
            onPageChange={(event, newPage) => {
              dispatch(actions.setFieldAction({ page: newPage }));
              fetchData();
            }}
            onRowsPerPageChange={(event) => {
              dispatch(
                actions.setFieldAction({
                  pageSize: +event.target.value,
                  page: 0,
                }),
              );
              fetchData();
            }}
          />
        </TableContainer>
      </div>
    </div>
  );
}

export default CustomReports;
