import Router from 'next/router';
import { ofType, StateObservable } from 'redux-observable';
import { concat, EMPTY, Observable, of } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { exhaustMap, filter, switchMap } from 'rxjs/operators';
import type { Action } from '@reduxjs/toolkit';

import { LOGIN_PAGE } from '@/modules/@common/router/constants';
import { REDIRECT_URL_STORAGE_NAME } from '@/modules/@common/storage/constants';

import { getToken, isLoginPage } from '../../helpers';
import { logOutEventAction } from '../slices';
import { clearStorage, setSessionStorageItem } from '@/modules/@common/storage/helpers';
import { getUserAccountSelector } from '@/modules/@common/user/redux/selectors';

const clearLocalStorage = () => {
  clearStorage();
};

type LogOutEventType = {
  payload: {
    logOutPage: string;
    logoutFrom: string;
  };
};

export default (action$: Observable<Action>, state$: unknown) =>
  action$.pipe(
    ofType(logOutEventAction.type),
    filter(() => !isLoginPage(Router.pathname) && !window.ac_redirecting),
    exhaustMap(({ payload: logOutEvent }: LogOutEventType) => {
      const state$$ = state$ as StateObservable<RootState>;
      const userAccount = getUserAccountSelector(state$$.value);
      const accountCustomLoginPage = userAccount?.customLoginPageUrl;

      const token = getToken();

      clearLocalStorage();

      const authStream = ajax({
        method: 'POST',
        url: '/api/auth/logout',
        crossDomain: true,
        withCredentials: true,
        headers: {
          Authorization: token,
        },
      }).pipe(
        switchMap(() => {
          const pushLink = window.location.href;
          const isLogOutRedirect = !!logOutEvent?.logOutPage;

          const paramsHistory = {
            pathname: LOGIN_PAGE.path,
            from: isLogOutRedirect ? logOutEvent.logoutFrom : pushLink,
          };

          if (accountCustomLoginPage) {
            // prevent double logout execution
            window.ac_redirecting = true;

            window.location.replace(`${accountCustomLoginPage}?olp=${encodeURIComponent(paramsHistory.from)}`);
          } else if (isLogOutRedirect) {
            setSessionStorageItem(REDIRECT_URL_STORAGE_NAME, paramsHistory.from);
            window.location.replace(`${paramsHistory.pathname}?redirectTo=${paramsHistory.from}`);
          } else {
            setSessionStorageItem(REDIRECT_URL_STORAGE_NAME, paramsHistory.from);
            window.location.replace(paramsHistory.pathname);
          }

          return EMPTY;
        }),
      );

      return concat(of({ type: 'RESET_STORE' }), authStream);
    }),
  );
