/* eslint-disable react/prop-types */
import React from 'react';
import PropTypes from 'prop-types';
import dayjs from 'dayjs';

import { AD_FORMATS, CALENDAR_FILTER, CALENDAR_FILTER_VALUE, DEVICES } from '../../constants';

import SpecialPopper from './components/SpecialPopper';
import {
  Autocomplete,
  Box,
  Button,
  Checkbox,
  FormControl,
  InputLabel,
  MenuItem,
  Select,
  Stack,
  TextField,
} from '@/mui/components';

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

const SELECT_ALL_VALUE = 'SELECT_ALL_VALUE';

function Filters(props) {
  const selectAllOption = { label: 'Select All', value: SELECT_ALL_VALUE };

  const isAllOptionsSelected = (options, value) => value?.length === options?.length;

  const handleOnChange = ({ filterName, selectedOptions, options, prevValue }) => {
    const isSelectedOptionsContainsAllOption = selectedOptions.some((option) => option.value === SELECT_ALL_VALUE);
    let newValues = [];
    if (!(isAllOptionsSelected(options, prevValue) && isSelectedOptionsContainsAllOption)) {
      newValues = isSelectedOptionsContainsAllOption ? [...options] : [...selectedOptions];
    }

    props.handleFilterChange(filterName, newValues);
  };

  return (
    <Stack spacing={2} direction="row" className={styles.Filters} fullWidth>
      <FormControl fullWidth className={styles.FixedFilter}>
        <InputLabel>Ad Format</InputLabel>
        <Select
          size="small"
          label="Ad Format"
          value={props.adFormat}
          data-id="adFormat"
          variant="outlined"
          displayEmpty
          onChange={({ target }) => {
            props.handleFilterChange('adFormat', target.value);
          }}
        >
          {AD_FORMATS.map((format) => (
            <MenuItem key={format.value} value={format.value}>
              {format.label}
            </MenuItem>
          ))}
        </Select>
      </FormControl>

      <FormControl fullWidth className={styles.FixedFilter}>
        <InputLabel>Period</InputLabel>
        <Select
          size="small"
          label="Period"
          value={props.calendar}
          renderValue={
            props.calendar === CALENDAR_FILTER_VALUE.custom &&
            props.calendarCustom?.dateStart &&
            props.calendarCustom?.dateEnd
              ? () =>
                  `${dayjs(props.calendarCustom.dateStart).format('MMM DD YY')} - ${dayjs(props.calendarCustom.dateEnd).format('MMM DD YY')}`
              : false
          }
          data-id="period"
          variant="outlined"
          onChange={({ target }) => props.handleFilterSetCalendar(target.value)}
        >
          {CALENDAR_FILTER.map((origin) => (
            <MenuItem key={origin.value} value={origin.value} onClick={() => props.handleMenuItemClick(origin.value)}>
              {origin.label}
            </MenuItem>
          ))}
        </Select>
      </FormControl>

      <Autocomplete
        data-id="demandSources"
        size="small"
        multiple
        limitTags={1}
        checkboxes
        optionValueKey="label"
        disableCloseOnSelect
        options={[selectAllOption, ...props.demandSourcesOptions]}
        value={props.demandSources}
        onChange={(event, newValue) => {
          handleOnChange({
            filterName: 'demandSources',
            options: props.demandSourcesOptions,
            prevValue: props.demandSources,
            selectedOptions: newValue,
          });
        }}
        renderOption={(optionProps, option, { selected }) => (
          <Box component="li" {...optionProps}>
            <Checkbox
              size="small"
              color="primary"
              checked={
                option.value === SELECT_ALL_VALUE
                  ? isAllOptionsSelected(props.demandSourcesOptions, props.demandSources)
                  : selected
              }
            />
            {option.label}
          </Box>
        )}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Demand Source"
            placeholder={props.demandSources.length ? '' : 'Select Source'}
            InputProps={{
              ...params.InputProps,
              classes: {
                ...params.InputProps.classes,
                input: styles.TextFieldInput,
              },
            }}
            size="small"
            variant="outlined"
            onChange={(e) => {
              props.handleFilterInputChange('demandSources', e.target.value);
            }}
          />
        )}
        slots={{
          popper: SpecialPopper,
        }}
        classes={{
          option: styles.FilterOption,
        }}
      />

      <Autocomplete
        data-id="players"
        size="small"
        multiple
        limitTags={1}
        checkboxes
        disableCloseOnSelect
        options={[selectAllOption, ...props.playersOptions]}
        value={props.players}
        onChange={(event, newValue) => {
          handleOnChange({
            filterName: 'players',
            options: props.playersOptions,
            prevValue: props.players,
            selectedOptions: newValue,
          });
        }}
        renderOption={(optionProps, option, { selected }) => (
          <Box component="li" {...optionProps}>
            <Checkbox
              size="small"
              color="primary"
              checked={
                option.value === SELECT_ALL_VALUE ? isAllOptionsSelected(props.playersOptions, props.players) : selected
              }
            />
            {option.label}
          </Box>
        )}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Player"
            placeholder={props.players?.length ? '' : 'Type to search players'}
            InputProps={{
              ...params.InputProps,
              classes: {
                ...params.InputProps.classes,
                input: styles.TextFieldInput,
              },
            }}
            size="small"
            variant="outlined"
            onChange={(e) => {
              props.handleFilterInputChange('players', e.target.value);
            }}
          />
        )}
        slots={{
          popper: SpecialPopper,
        }}
        classes={{
          option: styles.FilterOption,
        }}
      />

      <Autocomplete
        data-id="domains"
        size="small"
        multiple
        limitTags={1}
        checkboxes
        optionValueKey="label"
        disableCloseOnSelect
        options={[selectAllOption, ...props.domainsOptions]}
        value={props.domains}
        onChange={(event, newValue) => {
          handleOnChange({
            filterName: 'domains',
            options: props.domainsOptions,
            prevValue: props.domains,
            selectedOptions: newValue,
          });
        }}
        renderOption={(optionProps, option, { selected }) => (
          <Box component="li" {...optionProps}>
            <Checkbox
              size="small"
              color="primary"
              checked={
                option.value === SELECT_ALL_VALUE ? isAllOptionsSelected(props.domainsOptions, props.domains) : selected
              }
            />
            {option.label}
          </Box>
        )}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Domain"
            placeholder={props.domains.length ? '' : 'Type to search domains'}
            InputProps={{
              ...params.InputProps,
              classes: {
                ...params.InputProps.classes,
                input: styles.TextFieldInput,
              },
            }}
            size="small"
            variant="outlined"
            onChange={(e) => {
              props.handleFilterInputChange('domains', e.target.value);
            }}
          />
        )}
        slots={{
          popper: SpecialPopper,
        }}
        classes={{
          option: styles.FilterOption,
        }}
      />

      <Autocomplete
        data-id="countries"
        size="small"
        multiple
        limitTags={1}
        checkboxes
        optionValueKey="label"
        disableCloseOnSelect
        options={[selectAllOption, ...props.countriesOptions]}
        value={props.countries}
        onChange={(event, newValue) => {
          handleOnChange({
            filterName: 'countries',
            options: props.countriesOptions,
            prevValue: props.countries,
            selectedOptions: newValue,
          });
        }}
        renderOption={(optionProps, option, { selected }) => (
          <Box component="li" {...optionProps}>
            <Checkbox
              size="small"
              color="primary"
              checked={
                option.value === SELECT_ALL_VALUE
                  ? isAllOptionsSelected(props.countriesOptions, props.countries)
                  : selected
              }
            />
            {option.label}
          </Box>
        )}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Country"
            placeholder={props.countries.length ? '' : 'Select Country'}
            InputProps={{
              ...params.InputProps,
              classes: {
                ...params.InputProps.classes,
                input: styles.TextFieldInput,
              },
            }}
            size="small"
            variant="outlined"
          />
        )}
        slots={{
          popper: SpecialPopper,
        }}
        classes={{
          option: styles.FilterOption,
        }}
      />

      <Autocomplete
        data-id="devices"
        className={styles.FixedFilter}
        size="small"
        multiple
        limitTags={1}
        checkboxes
        optionValueKey="label"
        disableCloseOnSelect
        options={[selectAllOption, ...DEVICES]}
        value={props.devices}
        onChange={(event, newValue) => {
          handleOnChange({
            filterName: 'devices',
            options: DEVICES,
            prevValue: props.devices,
            selectedOptions: newValue,
          });
        }}
        renderOption={(optionProps, option, { selected }) => (
          <Box component="li" {...optionProps}>
            <Checkbox
              size="small"
              color="primary"
              checked={option.value === SELECT_ALL_VALUE ? isAllOptionsSelected(DEVICES, props.devices) : selected}
            />
            {option.label}
          </Box>
        )}
        renderInput={(params) => (
          <TextField
            {...params}
            label="Device"
            placeholder={props.devices.length ? '' : 'Select Device'}
            InputProps={{
              ...params.InputProps,
              classes: {
                ...params.InputProps.classes,
                input: styles.TextFieldInput,
              },
            }}
            size="small"
            variant="outlined"
          />
        )}
        slots={{
          popper: SpecialPopper,
        }}
        classes={{
          option: styles.FilterOption,
        }}
      />

      <div className={styles.Button}>
        <Button
          variant="contained"
          size="small"
          color="primary"
          shape="circular"
          onClick={() => {
            props.resetFilters();
          }}
        >
          Reset all
        </Button>
      </div>
    </Stack>
  );
}

Filters.propTypes = {
  calendar: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({})]).isRequired,
  calendarCustom: PropTypes.shape({}).isRequired,
  handleFilterSetCalendar: PropTypes.func.isRequired,
  handleMenuItemClick: PropTypes.func.isRequired,

  countries: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      value: PropTypes.string.isRequired,
    }),
  ).isRequired,
  countriesOptions: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      value: PropTypes.string.isRequired,
    }),
  ).isRequired,
  demandSources: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      value: PropTypes.string.isRequired,
    }),
  ).isRequired,
  demandSourcesOptions: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      value: PropTypes.string.isRequired,
    }),
  ).isRequired,
  domains: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      value: PropTypes.string.isRequired,
    }),
  ).isRequired,
  domainsOptions: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      value: PropTypes.string.isRequired,
    }),
  ).isRequired,
  devices: PropTypes.arrayOf(
    PropTypes.shape({
      label: PropTypes.string.isRequired,
      value: PropTypes.string.isRequired,
    }),
  ).isRequired,

  handleFilterChange: PropTypes.func.isRequired,
  handleFilterInputChange: PropTypes.func.isRequired,
  resetFilters: PropTypes.func.isRequired,
};

export default Filters;
