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

import { gqlRequest } from '@/modules/@common/request';
import { videosSelector } from '@/modules/editorial/editorialSearchResults/redux/selectors';
import { videosAction as videosActionsForEditorial } from '@/modules/editorial/editorialSearchResults/redux/slices';
import { selectedVideoSelector } from '@/modules/editorial/editorialVideoDetails/redux/selectors';
import { reloadSelectedVideoAction, selectedVideoAction } from '@/modules/editorial/editorialVideoDetails/redux/slices';
import { setIsLoadingAction } from '@/modules/editorial/shareAndAccess/redux/slices';

import videoById from '@/modules/@common/gql/queries/videoById';

export default (action$, state$) =>
  action$.pipe(
    ofType(reloadSelectedVideoAction.type),
    filter(() => selectedVideoSelector(state$.value)?.uid),
    switchMap(() => {
      const state = state$.value;
      const { uid: selectedVideoUid } = selectedVideoSelector(state);

      const stream$ = gqlRequest({
        query: videoById,
        variables: {
          uid: selectedVideoUid,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

          if (!errors.length) {
            const videos = videosSelector(state);

            const newVideos = videos.map((oneVideo$) =>
              oneVideo$.uid !== data.video.uid ? oneVideo$ : { ...oneVideo$, ...data.video },
            );

            if (data.video.uid === selectedVideoUid) {
              actions.push(of(selectedVideoAction(data.video)));
            }

            actions.push(of(videosActionsForEditorial(newVideos)));
          }

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

      return concat(of(setIsLoadingAction(true)), stream$, of(setIsLoadingAction(false)));
    }),
  );
