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

import {
  SEARCH_TEXT_MAX_LENGTH,
  STATUSES_ACTIVE,
  STATUSES_ALL,
  STATUSES_INACTIVE,
  STATUSES_OPTIONS,
  TABLE_HEADERS,
  TYPES_OPTIONS,
} from '../constants';

import * as selectors from '../redux/selectors';
import { bulkChangeStatusAction, getDataAction, setAction, setTableAction } from '../redux/slices';
import { omitUndefinedProps } from '@/mui/helpers';

import CommonList from '@/modules/@common/List';
import CommonTable from '@/modules/@common/Table';
import MacrosModal from './MacrosModal/MacrosModal';
import {
  Autocomplete,
  Button,
  Checkbox,
  Divider,
  IconButton,
  InputAdornment,
  Menu,
  MenuItem,
  Select,
  Stack,
  TableCell,
  TableRow,
  TextField,
  Tooltip,
} from '@/mui/components';

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

const getLabelFromValue = (options, value) => options.find((option) => option.value === value)?.label;

function List() {
  const dispatch = useDispatch();
  const router = useRouter();

  const [showMacros, setShowMacros] = useState(null);
  const [actions, setActions] = useState(null);

  const data = useSelector(selectors.dataSelector);
  const page = useSelector(selectors.pageSelector);
  const pageSize = useSelector(selectors.pageSizeSelector);
  const totalCount = useSelector(selectors.totalCountSelector);
  const sortBy = useSelector(selectors.sortBySelector);
  const sortOrder = useSelector(selectors.sortOrderSelector);
  const selected = useSelector(selectors.selectedSelector);

  const search = useSelector(selectors.searchSelector);
  const status = useSelector(selectors.statusSelector);
  const type = useSelector(selectors.typeSelector);

  const shouldShowEmpty = false;

  const handleFilter = (filter) => {
    const { sortBy: sortBy$, sortOrder: sortOrder$, page: page$, pageSize: pageSize$, ...mainState } = filter;

    dispatch(
      setTableAction(
        omitUndefinedProps({
          sortBy: sortBy$,
          sortOrder: sortOrder$,
          page: page$,
          pageSize: pageSize$,
          selected: [],
        }),
      ),
    );

    dispatch(
      setAction({
        ...mainState,
      }),
    );
    dispatch(getDataAction());
  };

  const handleSelectDeselectAllRows = (checked) => {
    dispatch(
      setTableAction({
        selected: checked ? data.map((r) => r.id) : [],
      }),
    );
  };

  const handleSelectDeselectRow = (rowId) => {
    const selectedIndex = selected.indexOf(rowId);
    let newSelected = [];

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

    dispatch(
      setTableAction({
        selected: newSelected,
      }),
    );
  };

  useEffect(() => {
    dispatch(getDataAction());
  }, []);

  return (
    <>
      <CommonList
        title="Ad Servers"
        renderFilters={
          <Stack direction="row" alignItems="center" spacing={2}>
            <Button
              size="small"
              color="neutral"
              variant="outlined"
              disabled={!selected.length}
              endIcon={<ExpandMoreRounded />}
              onClick={(event) => setActions(event.currentTarget)}
            >
              Actions
            </Button>
            {actions && (
              <Menu open anchorEl={actions} onClose={() => setActions('')}>
                <MenuItem
                  onClick={() => {
                    dispatch(bulkChangeStatusAction(STATUSES_ACTIVE));
                    setActions('');
                  }}
                >
                  Active
                </MenuItem>
                <MenuItem
                  onClick={() => {
                    dispatch(bulkChangeStatusAction(STATUSES_INACTIVE));
                    setActions('');
                  }}
                >
                  Inactive
                </MenuItem>
              </Menu>
            )}
            <div>
              <TextField
                className={styles.SearchField}
                size="small"
                placeholder="Search"
                value={search}
                onChange={({ target }) => handleFilter({ search: target.value, page: 1 })}
                inputProps={{
                  autoComplete: 'off',
                  maxLength: SEARCH_TEXT_MAX_LENGTH,
                }}
                InputProps={{
                  endAdornment: (
                    <InputAdornment position="end">
                      <IconButton onClick={() => null}>
                        <SearchRounded />
                      </IconButton>
                    </InputAdornment>
                  ),
                }}
                variant="outlined"
                disabled={shouldShowEmpty}
              />
            </div>
            <Stack spacing={1} direction="row" alignItems="center">
              <Divider orientation="vertical" flexItem />
              <FilterAltRounded color="shades.900" fontSize="medium" />
            </Stack>
            <Autocomplete
              className={styles.Select}
              value={STATUSES_OPTIONS.find((s) => s.value === status) ?? STATUSES_ALL}
              options={STATUSES_OPTIONS}
              size="small"
              onChange={(e, selected$) => handleFilter({ status: selected$?.value ?? STATUSES_ALL, page: 1 })}
              renderInput={(params) => <TextField {...params} placeholder="Status" />}
            />
            <Select
              className={styles.Select}
              size="small"
              variant="outlined"
              placeholder="Type"
              value={type}
              onChange={({ target }) => handleFilter({ type: target.value, page: 1 })}
            >
              {TYPES_OPTIONS.map((option) => (
                <MenuItem value={option.value} key={option.value}>
                  {option.label}
                </MenuItem>
              ))}
            </Select>
          </Stack>
        }
        renderActions={
          <Stack direction="row">
            <Tooltip title="Add Ad Server">
              <Button
                size="small"
                variant="contained"
                color="primary"
                startIcon={<AddRounded />}
                onClick={() => router.push('/ad-servers/new')}
              >
                Ad Server
              </Button>
            </Tooltip>
          </Stack>
        }
      >
        <CommonTable
          configHeaders={TABLE_HEADERS}
          enableBulkActions
          configRenderRow={(row, selectedRows, onSelectDeselectRow) => {
            const isItemSelected = selectedRows.includes(row.id);
            const statusLabel = getLabelFromValue(STATUSES_OPTIONS, row.status);
            const typeLabel = getLabelFromValue(TYPES_OPTIONS, row.placementId);
            return (
              <TableRow
                className={styles.Row}
                key={row.id}
                hover
                role="checkbox"
                aria-checked={isItemSelected}
                selected={isItemSelected}
                onClick={() => router.push(`/ad-servers/${row.id}`)}
              >
                <TableCell padding="checkbox" align="center">
                  <Checkbox
                    color="primary"
                    checked={isItemSelected}
                    onClick={(e) => {
                      e.stopPropagation();
                      onSelectDeselectRow(row.id);
                    }}
                  />
                </TableCell>

                <TableCell>
                  <div className={styles.NoWrap}>{row.name}</div>
                </TableCell>

                <TableCell>
                  <div className={styles.NoWrap}>{row.url}</div>
                </TableCell>

                <TableCell>
                  <div className={styles.NoWrap}>{typeLabel}</div>
                </TableCell>

                <TableCell align="center">
                  <div className={styles.NoWrap}>
                    <Button
                      variant="contained"
                      size="small"
                      color="neutral"
                      shape="rounded"
                      startIcon={<Visibility />}
                      square
                      onClick={(e) => {
                        e.stopPropagation();
                        setShowMacros({ title: row.name, macros: row.macro });
                      }}
                    />
                  </div>
                </TableCell>

                <TableCell>
                  <div className={styles.NoWrap}>{statusLabel}</div>
                </TableCell>

                <TableCell>
                  <div className={styles.NoWrap}>{row.comments}</div>
                </TableCell>

                <TableCell>
                  <div className={styles.NoWrap}>{row.updatedBy}</div>
                </TableCell>

                <TableCell>
                  <div className={styles.NoWrap}>{dayjs(row.updatedAt).format('MMM D, YYYY hh:mm A')}</div>
                </TableCell>
              </TableRow>
            );
          }}
          data={data || []}
          selected={selected}
          sortBy={sortBy}
          sortOrder={sortOrder}
          totalCount={totalCount}
          page={page}
          rowsPerPage={pageSize}
          onSelectDeselectAllRows={handleSelectDeselectAllRows}
          onSelectDeselectRow={handleSelectDeselectRow}
          onFilter={handleFilter}
        />
      </CommonList>
      {showMacros && (
        <MacrosModal
          open={showMacros}
          title={showMacros.title}
          macros={showMacros.macros}
          onClose={() => setShowMacros(null)}
        />
      )}
    </>
  );
}

export default List;
