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

import { GET_USER } from '@/graphql/services/users/constants';
import { TYPE_ERROR, TYPE_WARNING } from '@/modules/@common/notify/constants';
import { ACCOUNT } from '@/modules/@common/user/constants/rolesType';

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

import { getItemAction, setAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getUserRoleTypeSelector } from '@/modules/@common/user/redux/selectors';
import { showNotificationAction } from '@/modules/layout/redux/slices';

const query = `
  query ${GET_USER}($payload: ${PAYLOAD_NAME}) {
    ${GET_USER}(payload: $payload) {
      id
      email
      firstName
      lastName
      status
      enable2fa
      allSites
      contentOwner {
        id
        name
      }
      updateDate
      updatedBy
      account {
        id
        name
        type
        publishers {
          id
          name
        }
      }
      role {
        id
        name
        type
        displayName
        readOnlyInSelfServe
      }
      timezone
      defaultHub
      publisherIds
      department {
        id
        name
      }
    }
  }
`;

const getResponse = ({ data }) => {
  const user = data[GET_USER];

  return {
    ...user,
    contentOwner: user.contentOwner
      ? {
          ...user.contentOwner,
          label: user.contentOwner.name,
          value: user.contentOwner.id,
        }
      : user.role,
    role: user.role
      ? {
          ...user.role,
          label: user.role.displayName,
          value: user.role.id,
        }
      : user.role,
    account: user.account
      ? {
          ...user.account,
          label: user.account.name,
          value: user.account.id,
        }
      : user.account,
  };
};

export default (action$, state$) =>
  action$.pipe(
    ofType(getItemAction.type),
    switchMap((action) => {
      const hasAccount = getUserRoleTypeSelector(state$.value) === ACCOUNT;

      const stream$ = gqlRequest(
        {
          query,
          variables: {
            payload: {
              id: action.payload.id,
            },
          },
        },
        {
          showNotificationMessage: false,
        },
      ).pipe(
        switchMap((response) => {
          const actions = [];

          if (response.errors.length) {
            actions.push(
              of(
                showNotificationAction({
                  type: TYPE_ERROR,
                  message: "Can't open user for edit",
                }),
              ),
            );

            Router.push('/users');
          } else {
            const data = getResponse(response);

            if (hasAccount && data.role.readOnlyInSelfServe) {
              Router.push('/users');

              actions.push(
                of(
                  showNotificationAction({
                    type: TYPE_WARNING,
                    message: "You can't open the user for edit",
                  }),
                ),
              );
            } else {
              actions.push(
                of(
                  setAction({
                    ...data,
                    initialEmail: data.email,
                    initialStatus: data.status,
                    initialRoleType: data.role?.type ?? null,
                    initialRoleName: data.role?.name ?? null,
                  }),
                ),
              );
            }
          }

          return concat(...actions);
        }),
      );

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