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 { getTemplateByIdAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import parseResponseToState from '@/modules/forms/templateEditor/helpers/parseResponseToState';
import { showNotificationAction } from '@/modules/layout/redux/slices';

const query = `
  query GetTemplateByIdQuery(
    $id: Int!
    $cloneLogo: Boolean
  ) {
    getTemplateById(
      id: $id
      cloneLogo: $cloneLogo
    ) {
      id
      formTemplateCategoryId
      account {
        id
        name
      }
      name
      title
      logo
      metadata
    }
  }
`;

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

export default (action$) =>
  action$.pipe(
    ofType(getTemplateByIdAction.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 = parseResponseToState(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 template for edit. Metadata format is wrong',
                  }),
                ),
              );

              Router.push('/form-templates');
            }

            return concat(...actions);
          }

          return EMPTY;
        }),
      );

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