import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import NextLink from 'next/link';
import { AddRounded, FilterAltRounded, SearchRounded } from '@mui/icons-material';

import {
  PUBLISH_DESTINATION_TYPES,
  SETTINGS_STATUS_DISABLED,
  SETTINGS_STATUS_DISCONNECTED,
  SETTINGS_STATUS_ENABLED,
} from '../../../Destination/constants';
import { FILTER_TYPE_PLATFORM, FILTER_TYPE_STATUS } from '../../constants';
import { PCN_POST_DESTINATIONS } from '@/modules/@common/acl/constants';

import { FilterOptionType, FilterType } from '../../types';

import * as selectors from '../../redux/selectors';
import { getDestinationsAction, getPublishersAction, setFilterParamAction } from '../../redux/slices';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';

import FilterSuggester from './FilterSuggester';
import {
  Autocomplete,
  Button,
  Divider,
  IconButton,
  InputAdornment,
  Menu,
  MenuItem,
  Stack,
  TextField,
  Typography,
} from '@/mui/components';

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

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

  const publishers = useSelector(selectors.publishersSelector);
  const search = useSelector(selectors.searchSelector);
  const page = useSelector(selectors.pageSelector);
  const pageSize = useSelector(selectors.pageSizeSelector);
  const status = useSelector(selectors.statusSelector);
  const sortBy = useSelector(selectors.sortBySelector);
  const sortOrder = useSelector(selectors.sortOrderSelector);
  const platform = useSelector(selectors.platformSelector);
  const publisherId = useSelector(selectors.publisherIdSelector);
  const userPermissions = useSelector(getUserPermissionsSelector);
  const [anchorEl, setAnchorEl] = useState<(EventTarget & HTMLButtonElement) | null>(null);

  const handleAddButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => setAnchorEl(event.currentTarget);

  const handleCloseAddButton = () => setAnchorEl(null);

  const open = Boolean(anchorEl);

  const query = {
    search,
    page,
    pageSize,
    status,
    sortBy,
    sortOrder,
    platform,
    publisherId,
  };

  const handleGetDestination = (params = {}) => dispatch(getDestinationsAction({ ...query, ...params }));

  const handleFilterChange = (filterType: string, filterValue: string | null) => {
    dispatch(
      setFilterParamAction({
        [filterType]: filterValue,
      }),
    );

    handleGetDestination({
      [filterType]: filterValue,
      page: 1,
    });
  };

  const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    handleGetDestination({
      search: event.target.value,
    });
  };

  const handleSearchClick = () => {
    handleGetDestination();
  };

  const filters: FilterType[] = [
    {
      type: FILTER_TYPE_PLATFORM,
      placeholder: 'Platform',
      options: [
        {
          label: 'YouTube',
          value: 'YOUTUBE',
        },
        {
          label: 'Facebook',
          value: 'FACEBOOK',
        },
      ],
      value: query.platform as string,
    },
    {
      type: FILTER_TYPE_STATUS,
      placeholder: 'Status',
      options: [
        {
          label: 'Enabled',
          value: SETTINGS_STATUS_ENABLED,
        },
        {
          label: 'Disabled',
          value: SETTINGS_STATUS_DISABLED,
        },
        {
          label: 'Disconnected',
          value: SETTINGS_STATUS_DISCONNECTED,
        },
      ],
      value: query.status as string,
    },
  ];

  const suggesters = [
    {
      type: 'publisherId',
      label: 'Hub',
      options: publishers,
      onSearch: (searchText = '') => dispatch(getPublishersAction(searchText)),
      value: query.publisherId,
    },
  ];

  return (
    <>
      <Stack className={styles.WrapperTitle} direction="row" alignItems="center">
        <Typography variant="h6" component="div" align="left">
          Publish Destinations
        </Typography>
      </Stack>
      <Stack spacing={2} alignItems="center" direction="row" className={styles.Filter}>
        <div>
          <TextField
            placeholder="Search"
            defaultValue=""
            size="small"
            onChange={handleSearchChange}
            className={styles.Search}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  <IconButton onClick={handleSearchClick}>
                    <SearchRounded />
                  </IconButton>
                </InputAdornment>
              ),
            }}
          />
        </div>
        <Stack spacing={1} direction="row" alignItems="center">
          <Divider orientation="vertical" flexItem />
          <FilterAltRounded fontSize="medium" />
        </Stack>
        {filters.map((filter) => (
          <Autocomplete
            key={filter.type}
            className={styles.StatusSelect}
            value={filter.options.find((s) => s.value === filter.value) ?? null}
            options={filter.options}
            size="small"
            onChange={(e, selected$) => {
              const selected = selected$ as FilterOptionType | null;
              const value$ = (selected?.value ?? null) as FilterOptionType['value'] | null;
              return handleFilterChange(filter.type, value$);
            }}
            renderInput={(params) => <TextField {...params} placeholder={filter.placeholder} />}
          />
        ))}
        {suggesters.map((filter) => (
          <div key={filter.type}>
            <FilterSuggester onChange={handleFilterChange} {...filter} />
          </div>
        ))}

        {hasPermission(PCN_POST_DESTINATIONS, userPermissions) && (
          <div className={styles.AddButtonWrapper}>
            <Button onClick={handleAddButtonClick} data-id="add-button" startIcon={<AddRounded />} size="small">
              Add
            </Button>
            <Menu open={open} anchorEl={anchorEl} elevation={15} onClose={handleCloseAddButton}>
              {PUBLISH_DESTINATION_TYPES.map((dest) => (
                <MenuItem
                  component={NextLink}
                  key={`${dest.value}${dest.label}`}
                  href={`/publishing/${dest.value.toLowerCase()}/new`}
                >
                  {dest.label}
                </MenuItem>
              ))}
            </Menu>
          </div>
        )}
      </Stack>
    </>
  );
}

export default DestinationListHeader;
