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

import { UPDATE_USER } from '@/graphql/services/users/constants';
import { TYPE_SUCCESS } from '@/modules/@common/notify/constants';
import { API } from '@/modules/@common/user/constants/rolesType';

import { PAYLOAD_NAME } from '@/graphql/services/users/types/payload/item';

import * as selectors from '../selectors';
import { updateItemAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { showNotificationAction } from '@/modules/layout/redux/slices';

const query = `mutation ${UPDATE_USER}($payload: ${PAYLOAD_NAME}) {
  ${UPDATE_USER}(payload: $payload) {
    id
  }
}`;

export default (action$, state$) =>
  action$.pipe(
    ofType(updateItemAction.type),
    switchMap(({ payload: id }) => {
      const firstName = selectors.firstNameSelector(state$.value);
      const lastName = selectors.lastNameSelector(state$.value);
      const enable2fa = selectors.enable2faSelector(state$.value);
      const role = selectors.roleSelector(state$.value);
      const timezone = selectors.timezoneSelector(state$.value);
      const department = selectors.departmentSelector(state$.value);

      const defaultHub = selectors.defaultHubSelector(state$.value);
      const publisherIds = selectors.publisherIdsSelector(state$.value);
      const allSites = selectors.allSitesSelector(state$.value);
      const status = selectors.statusSelector(state$.value);
      const account = selectors.accountSelector(state$.value);

      const payload = {
        id,
        accountId: account?.id || null,
        firstName,
        lastName,
        enable2fa,
        roleId: role.id,
        timezone,
        departmentId: department?.id ?? null,
        defaultHub: defaultHub || null,
        publisherIds: publisherIds || [],
        allSites: !!allSites,
        status,
      };

      if (role.type === API) {
        const contentOwner = selectors.contentOwnerSelector(state$.value);

        payload.contentOwnerId = contentOwner.id;
      }

      const stream$ = gqlRequest({
        query,
        variables: {
          payload,
        },
      }).pipe(
        switchMap((response) => {
          if (!response.errors.length) {
            Router.push('/users');

            return of(
              showNotificationAction({
                type: TYPE_SUCCESS,
                message: 'User updated successfully',
              }),
            );
          }

          return EMPTY;
        }),
      );

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