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

import { TYPE_ERROR } from '@/modules/@common/notify/constants';

import { getFormByIdAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import parseFormResponseToState from '@/modules/forms/editor/helpers/parseResponseToState';
import { showNotificationAction } from '@/modules/layout/redux/slices';

const query = `
  query GetFormByIdQuery(
    $id: Int!
    $cloneLogo: Boolean
  ) {
    formById(
      id: $id
      cloneLogo: $cloneLogo
    ) {
      id
      name
      title
      publisher {
        id
        name
      }
      status
      logo
      scheduleReportEmail
      scheduleReportPeriod
      metadata
      triggerAction
      triggerTime
      triggerApiValue
      activateLimitsPeriod
      frequencyLimitsMaxViewPerUser
      frequencyLimitsPeriod
      frequencyLimitsDisplayOnlyOnceSubmitted
      frequencyLimitsNotShowWhenOnceDisplayed
      watch {
        id
        title
      }
      watchChannel {
        id
        title
      }
       player {
        id
        name
      }
      videoId
      videoName
      playerSizes
      includeDomains
      excludeDomains
      includeDevices
      excludeDevices
      includeGeographies {
        label
        value
      }
      excludeGeographies {
        label
        value
      }
      includeCategory {
        id
        name
      }
      excludeCategory {
        id
        name
      }
      includePeople {
        taxonomyId
        name
      }
      excludePeople {
        taxonomyId
        name
      }
      includeBrands {
        taxonomyId
        name
      }
      excludeBrands {
        taxonomyId
        name
      }
      includeKeywords {
        taxonomyId
        name
      }
      excludeKeywords {
        taxonomyId
        name
      }
      includeBrandSafety
      excludeBrandSafety
      includeLabels {
        groupBy
        labelId
        color
        value
        name
      }
      excludeLabels {
        groupBy
        labelId
        color
        value
        name
      }
      medataFormId
      enableInstantDelivery
    }
  }
`;

const getResponse = ({ data: { formById } }) => formById;

export default (action$) =>
  action$.pipe(
    ofType(getFormByIdAction.type),
    switchMap((action) => {
      const { id, isDuplicate = false } = action.payload;
      const variables = { id };

      if (isDuplicate) {
        variables.cloneLogo = true;
      }

      const stream$ = gqlRequest({
        query,
        variables,
      }).pipe(
        switchMap((response) => {
          if (!response.errors.length) {
            const data = getResponse(response);
            const actions = [];
            try {
              const state = parseFormResponseToState(data, isDuplicate);

              actions.push(of(setFieldAction(state)));
              // eslint-disable-next-line @typescript-eslint/no-unused-vars
            } catch (e) {
              actions.push(
                of(
                  showNotificationAction({
                    type: TYPE_ERROR,
                    message: 'Cant open form for edit. Metadata format is wrong',
                  }),
                ),
              );

              Router.push('/forms');
            }

            return concat(...actions);
          }

          return EMPTY;
        }),
      );

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