import React, { useEffect, useState } 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 { AddRounded, ExpandMoreRounded, FilterAltRounded, SearchRounded } from '@mui/icons-material';

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

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

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

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

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

function getValue(options, value) {
  return options.find((option) => option.value === value)?.label ?? 'Unknown';
}

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

  const [actions, setActions] = useState('');

  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 search = useSelector(selectors.searchSelector);
  const status = useSelector(selectors.statusSelector);

  const selected = useSelector(selectors.selectedSelector);
  const shouldShowEmpty = useSelector(computedState.shouldShowEmpty);

  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="Content Owners"
      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(bulkDisableOrActiveAction(STATUSES_ACTIVE));
                  setActions('');
                }}
              >
                Active
              </MenuItem>
              <MenuItem
                onClick={() => {
                  dispatch(bulkDisableOrActiveAction(STATUSES_INACTIVE));
                  setActions('');
                }}
              >
                Disable
              </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.StatusSelect}
            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" />}
          />
        </Stack>
      }
      renderActions={
        <Tooltip title="Add Content Owner">
          <Button
            size="small"
            variant="contained"
            color="primary"
            startIcon={<AddRounded />}
            onClick={() => router.push('/content-owners/new')}
          >
            Content Owner
          </Button>
        </Tooltip>
      }
    >
      {shouldShowEmpty ? (
        <Empty />
      ) : (
        <CommonTable
          configHeaders={getConfigHeaders()}
          enableBulkActions
          configRenderRow={(row, selectedRows, onSelectDeselectRow) => {
            const isItemSelected = selectedRows.includes(row.id);

            return (
              <TableRow
                className={styles.Row}
                key={row.id}
                hover
                role="checkbox"
                aria-checked={isItemSelected}
                selected={isItemSelected}
                onClick={() => router.push(`/content-owners/${row.id}`)}
              >
                <TableCell padding="checkbox" align="center">
                  <Checkbox
                    color="primary"
                    checked={isItemSelected}
                    onClick={(event) => {
                      event.stopPropagation();
                      onSelectDeselectRow(row.id);
                    }}
                  />
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.id}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.name}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{getValue(STATUSES_OPTIONS, row.status)}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{getValue(TYPES_OPTIONS, row.type)}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.CommentsWrap}>
                    <Typography rows={1} title={row.comments}>
                      {row.comments}
                    </Typography>
                  </div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{`${row.activeFeedsCount} / ${row.feedsCount}`}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.salesforce_id}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{getValue(CALL_TO_ACTIONS_OPTIONS, row.call_to_action)}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{getValue(PLAY_FROM_CO_OPTIONS, row.play_from_co)}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{getValue(IS_PUBLIC_OPTIONS, row.isPublic)}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{dayjs(row.update_date).format('MMM D, YYYY hh:mm A')}</div>
                </TableCell>
                <TableCell>
                  <div className={styles.NoWrap}>{row.updated_by}</div>
                </TableCell>
              </TableRow>
            );
          }}
          data={data || []}
          selected={selected}
          sortBy={sortBy}
          sortOrder={sortOrder}
          totalCount={totalCount}
          page={page}
          rowsPerPage={pageSize}
          onSelectDeselectAllRows={handleSelectDeselectAllRows}
          onSelectDeselectRow={handleSelectDeselectRow}
          onFilter={handleFilter}
        />
      )}
    </CommonList>
  );
}

export default List;
