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

import { PRIVATE, PUBLIC, SITE } from '../../constants';

import * as selectors from '../selectors';
import {
  addAccessSitesAction,
  changeAccessLevelAction,
  deleteAccessSitesAction,
  updateAccessLevelAction,
} from '../slices';

export default (action$, state$) =>
  action$.pipe(
    ofType(updateAccessLevelAction.type),
    switchMap((action) => {
      const { access } = action.payload;
      const accessSites = selectors.accessSitesSelector(state$.value);
      const accessLevel = selectors.accessLevelSelector(state$.value);
      const actions = [];

      if (accessLevel !== access.level && [PRIVATE, PUBLIC].includes(accessLevel)) {
        actions.push(of(changeAccessLevelAction({ level: accessLevel })));
      }

      if (accessLevel !== access.level && accessLevel === SITE) {
        actions.push(
          of(
            changeAccessLevelAction({
              level: accessLevel,
              sites: accessSites.map((site) => site.id),
            }),
          ),
        );
      } else if (accessLevel === access.level && accessLevel === SITE) {
        if (access.sites?.length && accessSites.length) {
          const sitesToDelete = access.sites.filter(
            (siteToDelete) => !accessSites.find((site) => site.id === siteToDelete.id),
          );

          const sitesToAdd = accessSites.filter((siteToAdd) => !access.sites.find((site) => site.id === siteToAdd.id));

          if (sitesToAdd.length) {
            actions.push(of(addAccessSitesAction(sitesToAdd)));
          }

          if (sitesToDelete.length) {
            actions.push(of(deleteAccessSitesAction(sitesToDelete)));
          }
        }
      }

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