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

import { setInitialAction } from '../../../editor/redux/slices';
import * as formsSelector from '../selectors';
import { getFormsAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';

const query = `
  query GetForms(
    $sortBy: String
    $sortOrder: String
    $page: Int
    $pageSize: Int
    $searchText: String
    $publisherId: Int
    $status: Int
    $searchIn: [String]
  ) {
    getForms(
      sortBy: $sortBy
      sortOrder: $sortOrder
      page: $page
      pageSize: $pageSize
      searchText: $searchText
      publisherId: $publisherId
      status: $status
      searchIn: $searchIn
    ) {
      records {
        id
        name
        publisherId
        status
        title
        createdAt
        createdBy
        updatedAt
        updatedBy
        publisher {
          id
          name
        }
      }
      recordsTotal
    }
  }
`;

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

export default (action$, state$) =>
  action$.pipe(
    ofType(getFormsAction.type),
    debounce(() => {
      const search = formsSelector.searchSelector(state$.value);
      return timer(search.length > 1 ? 1000 : 0);
    }),
    switchMap(() => {
      const state = state$.value;

      const page = formsSelector.pageSelector(state);
      const pageSize = formsSelector.rowsPerPageSelector(state);
      const searchText = formsSelector.searchSelector(state);
      const sortBy = formsSelector.sortBySelector(state);
      const sortOrder = formsSelector.sortOrderSelector(state);
      const status = formsSelector.statusSelector(state);
      const site = formsSelector.siteSelector(state);

      const variables = {
        sortBy,
        sortOrder,
        page,
        pageSize,
        searchText,
        status,
      };

      if (site?.value) {
        variables.publisherId = +site.value;
      }

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

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

          return EMPTY;
        }),
      );

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