import React, { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import dayjs from 'dayjs';
import { CheckCircle, KeyboardArrowDown, KeyboardArrowUp, RemoveCircle, TuneOutlined } from '@mui/icons-material';

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

import * as selectors from '../../../../redux/selectors';
import * as actions from '../../../../redux/slices';
import { debounce } from '@/modules/@common/helpers/events';

import { DialogCalendarRange } from '@/modules/analytics/common/components';
import FiltersDialog from '../FiltersDialog';
import { Button, Chip, FormControl, InputLabel, MenuItem, Select } from '@/mui/components';

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

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

  const period = useSelector(selectors.periodSelector);
  const periodCustomStartDate = useSelector(selectors.periodCustomStartDateSelector);
  const periodCustomEndDate = useSelector(selectors.periodCustomEndDateSelector);
  const isReadOnly = useSelector(selectors.isReadOnlySelector);
  const filters = useSelector(selectors.filtersSelector);

  const [isCalendarOpen, setIsCalendarOpen] = useState(false);
  const [isFiltersDialogOpen, setIsFiltersDialogOpen] = useState(false);
  const [isHideFilters, setIsHideFilters] = useState(false);
  const [isShowingMore, setIsShowingMore] = useState(false);

  const ref = useRef(null);

  const filtersValues = FILTERS_LIST.reduce((acc, cur) => {
    const valuesFromProps = filters[`${cur.name}_FILTER_VALUES`];
    const values = Array.isArray(valuesFromProps) ? valuesFromProps : [valuesFromProps]; // some filter is not multiple
    if (valuesFromProps && values?.length) {
      const fullInfoValues = values.map((item) => ({
        ...item,
        action: filters[`${cur.name}_FILTER_ACTION`],
        name: cur.name,
        filterLabel: cur.label,
        filterName: cur.name,
      }));
      return [...acc, ...fullInfoValues];
    }
    return acc;
  }, []);

  useEffect(() => {
    setIsShowingMore(false);
  }, [filtersValues?.length]);

  useEffect(() => {
    let delayedCheck = null;

    const check = () => {
      if (ref.current) {
        const { offsetHeight, scrollHeight } = ref.current;

        setIsHideFilters(!!offsetHeight && !!scrollHeight && offsetHeight < scrollHeight);
      }
    };

    check();

    delayedCheck = debounce(check, 1000);

    window.addEventListener('resize', delayedCheck);

    return () => {
      window.removeEventListener('resize', delayedCheck);
    };
  }, [filtersValues?.length]);

  const handleFilterSetCalendar = (newPeriod) => {
    dispatch(
      actions.setFieldAction({
        period: newPeriod,
      }),
    );

    if (newPeriod === CALENDAR_FILTER_VALUE.custom) {
      setIsCalendarOpen(true);
    }
  };

  const handleMenuItemClick = (itemValue) => {
    if (itemValue === CALENDAR_FILTER_VALUE.custom) {
      setIsCalendarOpen(true);
    }
  };

  const handleDeleteFilter = (filter) => {
    if (filter?.filterName) {
      const prevValues = filters[`${filter.filterName}_FILTER_VALUES`];
      dispatch(
        actions.setFieldAction({
          [`${filter.filterName}_FILTER_VALUES`]: prevValues.filter((item) => item.value !== filter.value),
        }),
      );
    }
  };

  return (
    <div className={styles.Filters}>
      <div className={styles.Controls}>
        <Button
          variant="outlined"
          size="small"
          color="neutral"
          shape="rounded"
          startIcon={<TuneOutlined />}
          onClick={() => {
            setIsFiltersDialogOpen(true);
          }}
          disabled={isReadOnly}
        >
          Filters
        </Button>

        <div className={styles.Divider} />

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

      {!!filtersValues?.length && !isReadOnly && (
        <div>
          <div
            ref={ref}
            style={{
              overflow: !isShowingMore ? 'hidden' : 'auto',
              maxHeight: !isShowingMore ? '36px' : 'none',
            }}
          >
            {filtersValues.map((item, index) => (
              <Chip
                key={`${+index}-${item.value}`}
                className={styles.FiltersValue}
                variant="filled"
                color="neutral"
                size="small"
                shape="circular"
                icon={
                  item.action === 'INCLUDE' ? (
                    <CheckCircle fontSize="small" htmlColor="success.main" className={styles.FiltersValueIconCheck} />
                  ) : (
                    <RemoveCircle
                      fontSize="small"
                      htmlColor="text.secondary"
                      className={styles.FiltersValueIconRemove}
                    />
                  )
                }
                onDelete={() => {
                  handleDeleteFilter(item);
                }}
                label={`${item.filterLabel}: ${item.label}`}
              />
            ))}
          </div>
          {isHideFilters && (
            <Button
              className={styles.FiltersValuesButton}
              variant="text"
              size="xSmall"
              color="neutral"
              shape="rounded"
              startIcon={!isShowingMore ? <KeyboardArrowDown /> : <KeyboardArrowUp />}
              onClick={() => {
                setIsShowingMore((prev) => !prev);
              }}
            >
              {`Show ${!isShowingMore ? 'more' : 'less'} filters`}
            </Button>
          )}
        </div>
      )}

      <FiltersDialog
        open={isFiltersDialogOpen}
        onClose={() => {
          setIsFiltersDialogOpen(false);
        }}
        onSubmit={() => {
          setIsFiltersDialogOpen(false);
        }}
      />

      <DialogCalendarRange
        open={isCalendarOpen}
        onClose={() => {
          setIsCalendarOpen(false);
          dispatch(
            actions.setFieldAction({
              period: CALENDAR_FILTER_VALUE.thisMonth,
            }),
          );
        }}
        onDateSubmit={({ dateStart, dateEnd }) => {
          dispatch(
            actions.setFieldAction({
              periodCustomStartDate: dateStart,
              periodCustomEndDate: dateEnd,
            }),
          );

          setIsCalendarOpen(false);
        }}
        minDate={dayjs(new Date()).diff(dayjs(new Date(new Date().getFullYear() - 1, 0, 1)), 'day')}
      />
    </div>
  );
}

export default Filters;
