import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import classNames from 'clsx';
import { useRouter } from 'next/router';
import { CodeRounded, ContentCopyRounded, Inventory2Rounded, SyncRounded } from '@mui/icons-material';

import { PCN_DELETE_LIVE_EVENTS, PCN_POST_LIVE_EVENTS } from '@/modules/@common/acl/constants';

import {
  embedCodeSelector,
  liveEventsSelector,
  queryParamsSelector,
  selectedEventsSelector,
  statusSelector,
  totalEventsSelector,
} from '../../redux/selectors';
import {
  archiveLiveEventsAction,
  getEmbedCodeAction,
  getLiveEventsAction,
  setEmbedCodeAction,
  setSelectedEventsAction,
} from '../../redux/slices';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';

import EmbedCodePopup from '@/modules/@common/EmbedCodePopup';
import { TableCellActions } from '@/modules/@common/Table';
import Header from './Header';
import Live from './Live';
import {
  Button,
  Checkbox,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TablePagination,
  TableRow,
  TableScroll,
  Tooltip,
} from '@/mui/components';

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

const ARCHIVE_STATUS = -1;

function LiveEventsList() {
  const dispatch = useDispatch();
  const router = useRouter();
  const queryParams = useSelector(queryParamsSelector);
  const embedCode = useSelector(embedCodeSelector);
  const liveEvents = useSelector(liveEventsSelector);
  const totalEvents = useSelector(totalEventsSelector);
  const selectedEvents = useSelector(selectedEventsSelector);
  const status = useSelector(statusSelector);
  const [isDialogOpen, setDialogOpen] = useState(false);
  const [showEmbedPopup, setShowEmbedPopup] = useState(false);
  const [eventId, setEventId] = useState(null);

  const userPermissions = useSelector(getUserPermissionsSelector);

  useEffect(() => {
    dispatch(
      getLiveEventsAction({
        ...queryParams,
        page: 1,
      }),
    );
  }, []);

  const handleRequestSort = (event, property) => {
    const isAsc = queryParams.sortBy === property && queryParams.sortOrder === 'ASC';
    dispatch(
      getLiveEventsAction({
        ...queryParams,
        page: 1,
        sortBy: property,
        sortOrder: isAsc ? 'DESC' : 'ASC',
      }),
    );
  };

  const handleSelectAllClick = (event) => {
    if (event.target.checked) {
      const newSelecteds = liveEvents.map((item) => item.id);
      dispatch(setSelectedEventsAction(newSelecteds));
      return;
    }
    dispatch(setSelectedEventsAction([]));
  };

  const handleCheckClick = (event, id) => {
    if (event.target.checked) {
      dispatch(setSelectedEventsAction([...selectedEvents, id]));
      return;
    }
    const unselected = selectedEvents.filter((item) => item !== id);
    dispatch(setSelectedEventsAction(unselected));
  };

  const showEmbedCode = (id) => {
    dispatch(setEmbedCodeAction(''));
    setShowEmbedPopup(true);
    dispatch(getEmbedCodeAction(id));
  };

  const handleEmbedOptionClick = (id) => {
    showEmbedCode(id);
  };

  const handleArchiveOptionClick = (id) => {
    setEventId(id);
    setDialogOpen(true);
  };

  const handleDialogClose = () => {
    setDialogOpen(false);
    setShowEmbedPopup(false);
  };

  const handleArchiveEventClick = () => {
    setDialogOpen(false);
    dispatch(archiveLiveEventsAction([eventId]));
  };

  const handleChangePage = (event, newPage) => {
    dispatch(
      getLiveEventsAction({
        ...queryParams,
        page: newPage,
      }),
    );
  };

  const handleChangeRowsPerPage = (event) => {
    dispatch(
      getLiveEventsAction({
        ...queryParams,
        page: 1,
        pageSize: parseInt(event.target.value, 10),
      }),
    );
  };

  const handleCellClick = (e, id) => {
    if (e.target.type === 'checkbox') return;

    router.push(`/live/${id}`);
  };

  const isSelected = (id) => !!selectedEvents.find((item) => item === id);

  return (
    <>
      <div className={styles.Wrapper}>
        <TableContainer>
          <TableScroll>
            <Table size="large" className={styles.Table} aria-labelledby="tableTitle" aria-label="enhanced table">
              <Header
                numSelected={selectedEvents.length}
                sortBy={queryParams.sortBy}
                sortOrder={queryParams.sortOrder}
                onSelectAllClick={handleSelectAllClick}
                onRequestSort={handleRequestSort}
                rowCount={liveEvents.length}
              />
              <TableBody>
                {liveEvents.map((row, index) => {
                  const isItemSelected = isSelected(row.id);
                  const labelId = `enhanced-table-checkbox-${index}`;

                  const isArchiveStatus = status === ARCHIVE_STATUS;

                  const options = [
                    {
                      text: 'Embed',
                      icon: CodeRounded,
                      style: 'regular',
                      onClick: () => handleEmbedOptionClick(row.id),
                      show: !isArchiveStatus,
                      title: 'Show Embed code',
                    },
                    {
                      text: 'Duplicate',
                      icon: ContentCopyRounded,
                      onClick: () => router.push(`/live/new?copied=${row.id}`),
                      show: hasPermission(PCN_POST_LIVE_EVENTS, userPermissions),
                      title: 'Duplicate Event',
                    },
                    {
                      text: 'Archive',
                      icon: Inventory2Rounded,
                      onClick: () => handleArchiveOptionClick(row.id),
                      show: !isArchiveStatus && hasPermission(PCN_DELETE_LIVE_EVENTS, userPermissions),
                      title: 'Archive Event',
                    },
                  ].filter((option) => option.show);

                  return (
                    <TableRow
                      hover
                      onClick={(event) => handleCellClick(event, row.id)}
                      role="checkbox"
                      aria-checked={isItemSelected}
                      tabIndex={-1}
                      key={row.id}
                      selected={isItemSelected}
                      className={styles.Row}
                    >
                      <TableCell align="center" padding="checkbox" data-id="cell-checkbox" className={styles.Cell}>
                        <Checkbox
                          color="primary"
                          checked={isItemSelected}
                          onChange={(event) => handleCheckClick(event, row.id)}
                          inputProps={{ 'aria-labelledby': labelId }}
                        />
                      </TableCell>
                      <TableCell component="th" id={labelId} scope="row" data-id="cell-id" className={styles.Cell}>
                        {row.id}
                      </TableCell>
                      <TableCell data-id="cell-name" className={styles.Cell}>
                        {row.name}
                      </TableCell>
                      <TableCell data-id="cell-publisher" className={styles.Cell}>
                        {row.player?.publisher?.name}
                      </TableCell>
                      <TableCell data-id="cell-description" className={styles.Cell}>
                        {row.description}
                      </TableCell>
                      <TableCell data-id="cell-startTime" className={classNames(styles.Cell, styles.Cell___date)}>
                        {!!row.liveEventSchedules.length &&
                          new Date(row.liveEventSchedules[0].startTime).toLocaleString()}{' '}
                        {row.recurrent && row.recurrentEndDate > Date.now() && (
                          <SyncRounded fontSize="small" htmlColor="primary.main" className={styles.CellSyncIndicator} />
                        )}
                      </TableCell>
                      <TableCell data-id="cell-endTime" className={classNames(styles.Cell, styles.Cell___date)}>
                        {!!row.liveEventSchedules.length &&
                          new Date(row.liveEventSchedules[row.liveEventSchedules.length - 1].endTime).toLocaleString()}
                      </TableCell>
                      <TableCell data-id="cell-updatedBy" className={styles.Cell}>
                        {row.updatedBy}
                      </TableCell>
                      <TableCell data-id="cell-live" className={styles.Cell}>
                        <Live
                          indicationColor={row.indicationColor}
                          status={row.status}
                          startTime={row.liveEventSchedules[0]?.startTime}
                          endTime={row.liveEventSchedules[row.liveEventSchedules.length - 1]?.endTime}
                          recurrent={row.recurrent}
                          recurrentEndDate={row.recurrentEndDate}
                        />
                      </TableCell>
                      <TableCell data-id="cell-updatedAt" className={styles.Cell}>
                        {new Date(row.updatedAt).toLocaleString()}
                      </TableCell>
                      <TableCellActions>
                        {options.map((option) => {
                          const Icon = option.icon;

                          return (
                            <Tooltip key={option.text} title={option.title} disableInteractive>
                              <IconButton
                                size="small"
                                onClick={(event) => {
                                  event.stopPropagation();

                                  option.onClick(event);
                                }}
                              >
                                <Icon />
                              </IconButton>
                            </Tooltip>
                          );
                        })}
                      </TableCellActions>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </TableScroll>
          {!!liveEvents.length && (
            <TablePagination
              rowsPerPageOptions={[10, 15, 25]}
              count={totalEvents}
              rowsPerPage={queryParams.pageSize}
              page={queryParams.page}
              onPageChange={handleChangePage}
              onRowsPerPageChange={handleChangeRowsPerPage}
              component="div"
            />
          )}
        </TableContainer>
      </div>
      {isDialogOpen && (
        <Dialog
          maxWidth="sm"
          open={isDialogOpen}
          onClose={handleDialogClose}
          aria-labelledby="alert-dialog-title"
          aria-describedby="alert-dialog-description"
        >
          <DialogTitle onClose={handleDialogClose}>Archive Event Confirmation</DialogTitle>
          <DialogContent>
            Event will be archived permanently from library. Are you sure you would like to archive?
          </DialogContent>
          <DialogActions>
            <Button size="small" onClick={handleDialogClose} variant="outlined">
              Cancel
            </Button>
            <Button size="small" onClick={handleArchiveEventClick} autoFocus>
              Archive
            </Button>
          </DialogActions>
        </Dialog>
      )}
      {showEmbedPopup && (
        <EmbedCodePopup
          isPlayerDisabled
          isAspectRatioDisabled
          title="Live Event Embed Code"
          embedCode={embedCode}
          onClose={handleDialogClose}
        />
      )}
    </>
  );
}

export default LiveEventsList;
