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

import { TEMPLATE_CATEGORY_ALL } from '@/modules/forms/constants';

import * as templateSelectors from '../selectors';
import { getTemplatesAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';

const query = `
  query GetFormTemplates(
    $sortBy: [String]
    $sortOrder: [String]
    $page: Int
    $pageSize: Int
    $searchText: String
    $searchIn: [String]
    $formTemplateCategoryIds: [Int]
  ) {
    getFormTemplates(
      sortBy: $sortBy
      sortOrder: $sortOrder
      page: $page
      pageSize: $pageSize
      searchText: $searchText
      searchIn: $searchIn
      formTemplateCategoryIds: $formTemplateCategoryIds
    ) {
      records {
        id
        formTemplateCategory {
          id
          name
        }
        account {
          id
          name
        }
        name
        title
        updatedAt
        updatedBy
      }
      recordsTotal
    }
  }
`;

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

export default (action$, state$) =>
  action$.pipe(
    ofType(getTemplatesAction.type),
    debounce(() => {
      const searchText = templateSelectors.searchTextSelector(state$.value);
      return timer(searchText.length > 1 ? 1000 : 0);
    }),
    switchMap(() => {
      const state = state$.value;
      const page = templateSelectors.pageSelector(state);
      const pageSize = templateSelectors.pageSizeSelector(state);
      const searchIn = templateSelectors.searchInSelector(state);
      const searchText = templateSelectors.searchTextSelector(state);
      const sortBy = templateSelectors.sortBySelector(state);
      const sortOrder = templateSelectors.sortOrderSelector(state);
      const formTemplateCategoryId = templateSelectors.formTemplateCategoryIdSelector(state);

      const variables = {
        sortBy: [sortBy],
        sortOrder: [sortOrder],
        page,
        pageSize,
        searchIn,
        searchText,
      };

      if (formTemplateCategoryId !== TEMPLATE_CATEGORY_ALL) {
        variables.formTemplateCategoryIds = [formTemplateCategoryId];
      }

      const stream$ = gqlRequest({
        query,
        variables,
      }).pipe(
        switchMap((response) => {
          if (!response.errors.length) {
            const data = getResponse(response);

            return of(
              setFieldAction({
                templates: data.records,
                totalCount: data.recordsTotal,
              }),
            );
          }

          return EMPTY;
        }),
      );

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