import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import classNames from 'clsx';
import dayjs from 'dayjs';
import { useRouter } from 'next/router';
import { AddRounded, DataObjectRounded, FilterAltRounded } from '@mui/icons-material';

import { HB_CONNECTOR_STATUSES, HB_FORMATS } from '../constants';

import * as selectors from '../redux/selectors';
import * as actions from '../redux/slices';
import { capitalizeFirstLetter } from '@/modules/@common/helpers/string';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';

import {
  Box,
  Button,
  Dialog,
  DialogContent,
  DialogTitle,
  Divider,
  MenuItem,
  Select,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TablePagination,
  TableRow,
  TableScroll,
  TextField,
  Typography,
} from '@/mui/components';

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

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

  const userTimezone = useSelector(getUserTimezoneSelector);

  const connectors = useSelector(selectors.connectorsSelector);
  const totalCount = useSelector(selectors.totalCountSelector);
  const page = useSelector(selectors.pageSelector);
  const rowsPerPage = useSelector(selectors.rowsPerPageSelector);
  const search = useSelector(selectors.searchSelector);
  const filterStatus = useSelector(selectors.filterStatusSelector);
  const filterFormat = useSelector(selectors.filterFormatSelector);

  const router = useRouter();
  const [openDialog, setOpenDialog] = useState(false);
  const [dialogName, setDialogName] = useState(null);
  const [dialogContent, setDialogContent] = useState(null);

  useEffect(() => {
    dispatch(actions.getConnectorsAction());
  }, []);

  const handleClickOpenDialog = (name, params) => {
    import('prismjs').then((Prism$) => {
      setDialogContent({
        __html: Prism$.default.highlight(
          JSON.stringify({ params }, null, 2) || '',
          Prism$.default.languages.javascript,
          'javascript',
        ),
      });
    });

    setDialogName(`${name} Parameters`);
    setOpenDialog(true);
  };

  const handleCloseDialog = () => {
    setOpenDialog(false);
    setDialogName(null);
  };

  // todo: migrate to <CommonList />
  return (
    <div className={styles.Wrapper}>
      <Stack direction="column" fullWidth justifyContent="center" className={styles.Title}>
        <Typography component="div" variant="h6" noWrap>
          HB Connectors
        </Typography>
      </Stack>
      <Stack
        spacing={1}
        fullWidth
        direction="row"
        alignItems="center"
        justifyContent="space-between"
        className={styles.Controls}
      >
        <Stack spacing={2} fullWidth alignItems="center" direction="row">
          <div className={styles.Search}>
            <TextField
              data-id="search"
              value={search}
              variant="outlined"
              size="small"
              placeholder="Search"
              onChange={({ target: { value } }) => {
                dispatch(actions.setFieldAction({ search: value, page: 0 }));
                dispatch(actions.getConnectorsAction());
              }}
            />
          </div>
          <Stack spacing={1} direction="row" alignItems="center">
            <Divider orientation="vertical" flexItem />
            <FilterAltRounded color="shades.900" fontSize="medium" />
          </Stack>
          <div className={styles.Suggester}>
            <Select
              id="statusFilter"
              size="small"
              value={filterStatus}
              onChange={(event) => {
                dispatch(
                  actions.setFieldAction({
                    filterStatus: event.target.value,
                    page: 0,
                  }),
                );
                dispatch(actions.getConnectorsAction());
              }}
            >
              {Object.entries(HB_CONNECTOR_STATUSES).map(([key, value]) => (
                <MenuItem key={key} value={value}>
                  {value.split(' ').map(capitalizeFirstLetter).join(' ')}
                </MenuItem>
              ))}
            </Select>
          </div>
          <div className={styles.Suggester}>
            <Select
              id="format"
              size="small"
              value={filterFormat}
              onChange={(event) => {
                dispatch(
                  actions.setFieldAction({
                    filterFormat: event.target.value,
                    page: 0,
                  }),
                );
                dispatch(actions.getConnectorsAction());
              }}
            >
              {HB_FORMATS.map((item) => (
                <MenuItem key={item.key} value={item.value}>
                  {item.label}
                </MenuItem>
              ))}
            </Select>
          </div>
        </Stack>
        <Stack spacing={2} justifyContent="flex-end" alignItems="center" direction="row">
          <Button
            variant="contained"
            size="small"
            color="primary"
            startIcon={<AddRounded />}
            onClick={() => {
              dispatch(actions.resetFormAction());
              router.push('/hb-connectors/new');
            }}
          >
            Connector
          </Button>
        </Stack>
      </Stack>
      <div className={styles.TableWrapper}>
        <TableContainer>
          <TableScroll>
            <Table className={styles.Table} size="large" aria-label="connectors table">
              <TableHead>
                <TableRow>
                  <TableCell>Id</TableCell>
                  <TableCell>Name</TableCell>
                  <TableCell>Code</TableCell>
                  <TableCell align="center">Parameters</TableCell>
                  <TableCell>Ad Format</TableCell>
                  <TableCell>Comments</TableCell>
                  <TableCell>Updated By</TableCell>
                  <TableCell>Last Update</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {connectors.map(
                  ({ id, numericId, name, code, params, format, comments, user, updatedBy, created, updated }) => (
                    <TableRow
                      key={id}
                      className={styles.Row}
                      onClick={() => {
                        dispatch(actions.resetFormAction());
                        dispatch(
                          actions.setFieldAction({
                            name,
                            code,
                            params,
                            format,
                            comments,
                          }),
                        );
                        router.push(`/hb-connectors/${id}`);
                      }}
                    >
                      <TableCell component="th" scope="row">
                        {numericId}
                      </TableCell>
                      <TableCell>{name}</TableCell>
                      <TableCell>{code}</TableCell>
                      <TableCell align="center">
                        <Button
                          variant="contained"
                          square
                          size="small"
                          color="neutral"
                          onClick={(event) => {
                            event.stopPropagation();
                            handleClickOpenDialog(name, params);
                          }}
                          startIcon={<DataObjectRounded />}
                        />
                      </TableCell>
                      <TableCell>{capitalizeFirstLetter(format)}</TableCell>
                      <TableCell>{comments}</TableCell>
                      <TableCell>{user || updatedBy}</TableCell>
                      <TableCell>
                        {dayjs(updated || created)
                          .tz(userTimezone)
                          .format('DD-MMM-YY HH:mm A')}
                      </TableCell>
                    </TableRow>
                  ),
                )}
              </TableBody>
            </Table>
          </TableScroll>
          <TablePagination
            component="div"
            rowsPerPageOptions={[10, 25, 50, 100, 200]}
            count={totalCount}
            rowsPerPage={rowsPerPage}
            page={page + 1}
            onPageChange={(event, newPage) => {
              dispatch(actions.setFieldAction({ page: newPage - 1 }));
              dispatch(actions.getConnectorsAction());
            }}
            onRowsPerPageChange={(event) => {
              dispatch(actions.setFieldAction({ rowsPerPage: +event.target.value }));
              dispatch(actions.getConnectorsAction());
            }}
          />
        </TableContainer>
      </div>
      <Dialog open={openDialog} onClose={handleCloseDialog}>
        <DialogTitle onClose={handleCloseDialog}>{dialogName}</DialogTitle>
        <DialogContent>
          <Box className={styles.CodeWrapper}>
            <pre>
              <code
                className={classNames(styles.Code, 'language-javascript')}
                dangerouslySetInnerHTML={dialogContent}
              />
            </pre>
          </Box>
        </DialogContent>
      </Dialog>
    </div>
  );
}

export default HBConnectors;
