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

import * as selectors from '../selectors';
import {
  getTotalAction,
  setDeviceAction,
  setFilterDateAction,
  setFilterFormatAction,
  setGeoAction,
  setTotalAction,
} from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';

const query = `
  query SupplyAccountTotalQuery(
    $fields: [String],
    $filters: MarketplaceFiltersInputType
  ) {
    supplyAccountTotal(
      fields: $fields,
      filters: $filters
    ) {
      fields {
        PLAYER_LOADS {
          value
          change
        }
        SUPPLY_REQUESTS {
          value
          change
        }
        IMPRESSIONS {
          value
          change
        }
        SUPPLY_REQUESTS_FILL {
          value
          change
        }
        REVENUE {
          value
          change
        }
        GROSS_RPM {
          value
          change
        }
        PUB_AD_RPM {
          value
          change
        }
        GROSS_PLAYER_ERPM {
          value
          change
        }
        GROSS_REVENUE {
          value
          change
        }
        MEDIA_MARGIN {
          value
          change
        }
        MEDIA_MARGIN_PERCENT {
          value
          change
        }
        AC_AD_RPM {
          value
          change
        }
      }
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(
      getTotalAction.type,
      setFilterDateAction.type,
      setFilterFormatAction.type,
      setDeviceAction.type,
      setGeoAction.type,
    ),
    filter(() => {
      const state = state$.value;

      const pageConfig = selectors.pageConfigSelector(state);

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

      const filterDate = selectors.filterDateSelector(state);
      const formatFilter = selectors.formatFilterSelector(state);
      const device = selectors.deviceSelector(state);
      const geo = selectors.geoSelector(state);

      const timezone = getUserTimezoneSelector(state$.value);
      const { isCustomPeriod, ...filterDateRest } = filterDate;
      const { change, dimension, changeDimension, ...range } = filterDateRest;
      let filters = {};

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

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

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

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

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

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

      const stream$ = gqlRequest({
        query,
        variables: {
          fields: [
            'PLAYER_LOADS',
            'SUPPLY_REQUESTS',
            'IMPRESSIONS',
            'SUPPLY_REQUESTS_FILL',
            'REVENUE',
            'GROSS_RPM',
            'PUB_AD_RPM',
            'GROSS_PLAYER_ERPM',
            'GROSS_REVENUE',
            'MEDIA_MARGIN',
            'MEDIA_MARGIN_PERCENT',
            'AC_AD_RPM',
          ],
          filters: {
            ranges: [{ ...range, timezone }],
            ...filters,
          },
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          let actions = [];

          if (!errors.length) {
            actions = [of(setTotalAction(data.supplyAccountTotal.fields || {}))];
          }

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

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