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

import { TYPE_ERROR } from '@/modules/@common/notify/constants';
import { LOGIN_PAGE } from '@/modules/@common/router/constants';
import { REDIRECT_URL_STORAGE_NAME } from '@/modules/@common/storage/constants';
import { AUTH_TYPES } from '@/modules/auth/SsoLogin/constants';

import { setSessionStorageItem } from '@/modules/@common/storage/helpers';
import { setFormLoadingAction } from '@/modules/auth/common/redux/slices';
import {
  getSsoLinkAction,
  setEmailAction,
  setIsSsoAuthProcessAction,
  setSsoFailedAction,
} from '@/modules/auth/Login/redux/slices';
import { showNotificationAction } from '@/modules/layout/redux/slices';

import { getFromUrlWithoutAccountUserParams } from '@/modules/auth/common/useSsoBackgroundLogin';

const types = {
  [AUTH_TYPES.byEmail]: 'SAML',
  [AUTH_TYPES.byGoogle]: 'Google',
};

export default (action$) =>
  action$.pipe(
    ofType(getSsoLinkAction.type),
    switchMap((action) => {
      const { type, email = '', subdomain, shouldRedirectToLoginPageIfError = false, ssoCheck } = action.payload;

      let url = `${process.env.APP_PCN_API_BASE_URL_FE}/public/props/getSsoRedirectionUrl?provider=${types[type]}`;

      if (email) {
        url = `${url}&email=${encodeURIComponent(email.trim())}`;
      } else if (subdomain) {
        url = `${url}&subdomain=${encodeURIComponent(subdomain.trim())}`;
      }

      const stream$ = ajax({
        method: 'GET',
        url,
        crossDomain: true,
        withCredentials: true,
      }).pipe(
        switchMap(({ response: { ssoLoginUri } }) => {
          const actions = [];

          if (!ssoCheck) {
            const authUrl = encodeURIComponent(ssoLoginUri);
            const redirectUri = encodeURIComponent(`${window.location.origin}/login`);

            actions.push(of(setFormLoadingAction(true)), of(setIsSsoAuthProcessAction(true)));

            window.location.replace(
              `${process.env.APP_ENV_BASE_URL}/auth/cognito?authUri=${authUrl}&redirectUri=${redirectUri}`,
            );
          } else {
            actions.push(
              of(setEmailAction(email)),
              of(setFormLoadingAction(false)),
              of(setIsSsoAuthProcessAction(false)),
            );
          }

          return concat(...actions);
        }),
        catchError(({ response }) => {
          if (shouldRedirectToLoginPageIfError) {
            setSessionStorageItem(REDIRECT_URL_STORAGE_NAME, getFromUrlWithoutAccountUserParams());
            Router.replace(LOGIN_PAGE.path);
          }

          const actions = [
            of(setEmailAction(email)),
            of(setFormLoadingAction(false)),
            of(setIsSsoAuthProcessAction(false)),
          ];

          if (subdomain) {
            actions.push(of(setSsoFailedAction(true)));
          } else {
            actions.push(
              of(
                showNotificationAction({
                  type: TYPE_ERROR,
                  message: response?.message ?? 'Connection error',
                }),
              ),
            );
          }

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

      return concat(of(setFormLoadingAction(!ssoCheck)), of(setIsSsoAuthProcessAction(!ssoCheck)), stream$);
    }),
  );
