import Router from 'next/router';
import { ofType } from 'redux-observable';
import { concat, of } from 'rxjs';
import { filter, mergeMap } from 'rxjs/operators';

import { EDITORIAL_PAGE } from '@/modules/@common/router/constants';
import { namesFilterSelectors } from '@/modules/editorial/editorialSearchFilter/constants';

import { selectedVideoSelector } from '../selectors';
import { addFiltersQueriesAction, selectedVideoAction } from '../slices';
import { isEqual } from '@/modules/@common/helpers';
import { addQueriesAction, removeQueriesAction } from '@/modules/@common/location/redux/slices';
import { configSelector } from '@/modules/editorial/editorialSearchFilter/filterContainer/redux/selectors';

import { getDefaultConfig } from '@/modules/editorial/editorialSearchFilter/filterConfig';

const formatFilterToQueries = (config, defaultConfig) => {
  let result = {};

  Object.keys(config)
    .filter((key) => !isEqual(config[key], defaultConfig[key]))
    .forEach((key) => {
      const value = config[key]?.filters[0]?.value;
      const label = config[key]?.filters[0]?.label;

      if (key === 'time' && label === 'Custom') {
        result = {
          ...result,
          [key]: {
            startDate: value.startDate,
            endDate: value.endDate,
          },
        };
      } else if (key === 'order') {
        result = {
          ...result,
          [key]: {
            value,
            isReversed: config[key]?.isReversed,
          },
        };
      } else if (namesFilterSelectors.includes(key)) {
        result = {
          ...result,
          [key]: value[0]?.value,
        };
      } else {
        result = {
          ...result,
          [key]: value,
        };
      }
    });

  return result;
};

export default (action$, state$) =>
  action$.pipe(
    ofType(selectedVideoAction.type, addFiltersQueriesAction.type),
    filter((action) => {
      if (Router.pathname !== EDITORIAL_PAGE.path) {
        return false;
      }

      if (action.type === selectedVideoAction.type) {
        return action.payload && action.payload.uid;
      }

      return true;
    }),
    mergeMap(({ type }) => {
      if (type === selectedVideoAction.type) {
        const { uid } = selectedVideoSelector(state$.value);
        return concat(of(addQueriesAction({ videoId: uid })));
      }

      const defaultConfig = getDefaultConfig();
      const config = configSelector(state$.value);

      const queriesToRemove = Object.keys(config).filter((key) => isEqual(config[key], defaultConfig[key]));

      if (queriesToRemove?.length) {
        return concat(
          of(addQueriesAction(formatFilterToQueries(config, defaultConfig))),
          of(removeQueriesAction(queriesToRemove)),
        );
      }

      return concat(of(addQueriesAction(formatFilterToQueries(config, defaultConfig))));
    }),
  );
