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

import { parseHistogram } from '../../../common/helpers/histogram';
import * as selectors from '../selectors';
import {
  getPerformanceHistogramAction,
  setDeviceAction,
  setFilterFormatAction,
  setGeoAction,
  setPerformanceFilterAction,
  setPerformanceHistogramAction,
} from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';

const query = `
  query SupplyAccountHistogramQuery(
    $fields: [String],
    $interval: String,
    $timezone: String,
    $filters: [MarketplaceFiltersInputType]
  ) {
    supplyAccountHistogram(
      fields: $fields,
      interval: $interval,
      timezone: $timezone,
      filters: $filters
    ) {
      totalCount
      data {
        name
        buckets {
          time
          fields {
            SUPPLY_REQUESTS_FILL {
              value
              change
            }
            SUPPLY_REQUESTS {
              value
              change
            }
            IMPRESSIONS {
              value
              change
            }
          }
        }
      }
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(
      getPerformanceHistogramAction.type,
      setPerformanceFilterAction.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 performanceFilter = selectors.performanceFilterSelector(state);
      const formatFilter = selectors.formatFilterSelector(state);
      const device = selectors.deviceSelector(state);
      const geo = selectors.geoSelector(state);

      const timezone = getUserTimezoneSelector(state$.value);

      const { interval, dimension, ...ranges } = performanceFilter;

      let filters = {};

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

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

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

      const stream$ = gqlRequest({
        query,
        variables: {
          timezone,
          fields: ['SUPPLY_REQUESTS_FILL', 'SUPPLY_REQUESTS', 'IMPRESSIONS'],
          interval,
          filters: [{ ranges: [ranges], dimension, ...filters }],
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          let actions = [];
          const { supplyAccountHistogram } = data;

          if (!errors.length) {
            const histogram = parseHistogram(supplyAccountHistogram.data[0], timezone);

            actions = [of(setPerformanceHistogramAction(histogram))];
          }

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

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