import { ofType } from 'redux-observable';
import { concat, of } from 'rxjs';
import { filter, switchMap } from 'rxjs/operators';

import { DEMAND_TAG_PAGE, SUPPLY_SITE_PAGE, SUPPLY_TAG_PAGE } from '../../constants';

import * as selectors from '../selectors';
import {
  getTotalAction,
  refreshPageDataByIntervalAction,
  setFieldAction,
  setFilterByCountryAction,
  setFilterByDateAction,
  setFilterByDeviceAction,
  setFilterByPlayerAction,
} from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';
import { formatFilterSelector } from '@/modules/marketplace/dashboard/redux/selectors';
import { setFilterFormatAction } from '@/modules/marketplace/dashboard/redux/slices';

export default (action$, state$) =>
  action$.pipe(
    ofType(
      getTotalAction.type,
      setFilterByCountryAction.type,
      setFilterByDeviceAction.type,
      setFilterByDateAction.type,
      setFilterByPlayerAction.type,
      refreshPageDataByIntervalAction.type,
      setFilterFormatAction.type,
    ),
    filter(() => {
      const state = state$.value;

      const pageConfig = selectors.pageConfigSelector(state);

      return !!pageConfig;
    }),
    switchMap(() => {
      const state = state$.value;

      const pageConfig = selectors.pageConfigSelector(state);
      const filterByDate = selectors.filterByDateSelector(state);
      const filterByCountry = selectors.filterByCountrySelector(state);
      const filterByDevice = selectors.filterByDeviceSelector(state);
      const filterByPlayer = selectors.filterByPlayerSelector(state);
      const timezone = getUserTimezoneSelector(state);

      const formatFilter = formatFilterSelector(state);

      const { isCustomPeriod, ...filterByDateRest } = filterByDate;
      const { change, dimension, changeDimension, ...range } = filterByDateRest;
      let filters = {};

      if (dimension) {
        filters = {
          ...filters,
          dimension,
        };
      }

      if (change) {
        filters = {
          ...filters,
          changeRanges: [
            {
              ...change,
              timezone,
            },
          ],
        };
      }

      if (changeDimension) {
        filters = {
          ...filters,
          changeDimension,
        };
      }

      if (formatFilter && !(pageConfig?.type === DEMAND_TAG_PAGE || pageConfig?.type === SUPPLY_TAG_PAGE)) {
        filters = {
          ...filters,
          ...formatFilter,
        };
      }

      if (pageConfig?.type === SUPPLY_SITE_PAGE && filterByCountry) {
        filters = {
          ...filters,
          geo: filterByCountry,
        };
      }

      if (pageConfig?.type === SUPPLY_SITE_PAGE && filterByDevice) {
        filters = {
          ...filters,
          device: filterByDevice,
        };
      }

      if (pageConfig?.type === SUPPLY_SITE_PAGE && filterByPlayer?.value) {
        filters = {
          ...filters,
          widgetId: filterByPlayer.value,
        };
      }

      const stream$ = gqlRequest({
        query: pageConfig.totalQuery,
        variables: {
          id: pageConfig.id,
          fields: pageConfig.totalFields,
          filters: {
            ranges: [{ ...range, timezone }],
            ...filters,
          },
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          let actions = [];

          if (!errors.length) {
            actions = [
              of(
                setFieldAction({
                  total:
                    {
                      ...data.supplyAccountDataById,
                      ...data.siteDataById,
                      ...data.supplyTagDataById,
                      ...data.demandAccountDataById,
                      ...data.advertiserDataById,
                      ...data.demandTagDataById,
                    }.fields || {},
                }),
              ),
            ];
          }

          return concat(...actions);
        }),
      );

      return concat(stream$);
    }),
  );
