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

import { DOWNLOAD_TIMEOUT } from '../../constants';

import createCustomReportRequestBody from '../../helpers/createCustomReportRequestBody';
import { checkDownloadReportAction, runDownloadReportAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';

const query = `
  mutation CustomReportDownloadRun(
    $id: Int!,
    $timeZone: String,
    $downloadTimeout: Int,
    $requestFullInfo: Boolean,
    $name: String,
    $scheduled: Boolean,
    $scheduleType: String,
    $recipients: [String],
    $scheduleValue: AnalyticsCustomReportScheduleValueInputType,
    $period: String,
    $periodCustomStartDate: String,
    $periodCustomEndDate: String,
    $dimensions: [AnalyticsCustomReportDimensionInputType],
    $filters: [AnalyticsCustomReportFilterInputType],
    $metrics: [AnalyticsCustomReportMetricInputType]
  ) {
    customReportDownloadRun(
      id: $id,
      timeZone: $timeZone,
      downloadTimeout: $downloadTimeout,
      requestFullInfo: $requestFullInfo,
      name: $name,
      scheduled: $scheduled,
      scheduleType: $scheduleType,
      recipients: $recipients,
      scheduleValue: $scheduleValue,
      period: $period,
      periodCustomStartDate: $periodCustomStartDate,
      periodCustomEndDate: $periodCustomEndDate,
      dimensions: $dimensions,
      filters: $filters,
      metrics: $metrics
    ) {
       reportId
       operationId
       status
       message
       file
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(runDownloadReportAction.type),
    filter(({ payload }) => payload.id),
    switchMap(({ payload }) => {
      const timezone = getUserTimezoneSelector(state$.value);
      const state = state$.value;

      // eslint-disable-next-line no-useless-assignment
      let body = {};

      if (payload.requestFullInfo) {
        body = {
          requestFullInfo: payload.requestFullInfo,
        };
      } else {
        body = {
          ...createCustomReportRequestBody(state),
        };
      }

      const stream$ = gqlRequest({
        query,
        variables: {
          id: payload.id,
          timeZone: timezone,
          downloadTimeout: DOWNLOAD_TIMEOUT,
          ...body,
        },
      }).pipe(
        switchMap(({ data: { customReportDownloadRun = {} }, errors }) => {
          let actions = [];

          if (!errors.length && customReportDownloadRun?.operationId && customReportDownloadRun?.reportId) {
            const { operationId, reportId } = customReportDownloadRun;
            actions = [
              of(
                checkDownloadReportAction({
                  operationId,
                  reportId,
                  fileName: payload.name,
                }),
              ),
            ];
          }

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

      return concat(of(setFieldAction({ isDownloading: true })), stream$);
    }),
  );
