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

import { TYPE_ERROR } from '@/modules/@common/notify/constants';
import { DND_MAIN_LIST_OF_VIDEO_TYPE, DND_PLAYLIST_VIDEO_TYPE } from '@/modules/editorial/constants/dnd';
import { QUERY_PARAM_TAB, TAB_PLAYLIST } from '@/modules/editorial/constants/routing';

import { playlistIdSelector, playlistsSelector } from '../../selectors';
import { updatePlaylistAction } from '../../slices';
import { dragAndDropEndSelector, videosSelector } from '@/modules/editorial/editorialSearchResults/redux/selectors';
import { dragAndDropEndAction } from '@/modules/editorial/editorialSearchResults/redux/slices';
import { parseDndId } from '@/modules/editorial/helpers/createDndId';
import { reorderVideos } from '@/modules/editorial/RightSideBar/common/helpers';
import { showNotificationAction } from '@/modules/layout/redux/slices';

export default (action$, state$) =>
  action$.pipe(
    ofType(dragAndDropEndAction.type),
    filter(() => Router.query[QUERY_PARAM_TAB] === TAB_PLAYLIST),
    mergeMap(() => {
      const videos = videosSelector(state$.value);
      const { active, over } = dragAndDropEndSelector(state$.value);

      const activeMetadata = active?.id ? parseDndId(active.id) : {};
      const overMetadata = over?.id ? parseDndId(over.id) : {};

      const playlists = playlistsSelector(state$.value);
      const playlistId = playlistIdSelector(state$.value);
      const playlist = playlists.find((playlist$) => playlist$.id === playlistId);

      const actions = [];

      // dnd videos inside playlist
      // metadataObject = { type, distributionId, itemIndex }
      if (activeMetadata.type === DND_PLAYLIST_VIDEO_TYPE && overMetadata.type === DND_PLAYLIST_VIDEO_TYPE) {
        const items = reorderVideos(playlist.videos ?? [], activeMetadata.itemIndex, overMetadata.itemIndex);

        actions.push(
          of(
            updatePlaylistAction({
              clips: items?.map((item) => item?.distributionId) ?? [],
              publisherId: playlist.publisherId,
            }),
          ),
        );
      }

      // dnd video from search results to channel
      // metadataObject = { type, videUid, distributionId, itemIndex }
      if (activeMetadata.type === DND_MAIN_LIST_OF_VIDEO_TYPE && overMetadata.type === DND_PLAYLIST_VIDEO_TYPE) {
        const targetClip =
          videos.find(({ uid }) => uid === activeMetadata.videoUid) ??
          playlist.videos.find(({ distributionId }) => distributionId === activeMetadata.distributionId);
        const canDropToPlaylist = ['ACTIVE', 'PROCESSING'].find((status) => targetClip.status === status);

        if (playlist?.clips?.includes(activeMetadata.distributionId)) {
          return of(showNotificationAction({ type: TYPE_ERROR, message: 'The video is already in the playlist' }));
        }

        if (!canDropToPlaylist) {
          return of(showNotificationAction({ type: TYPE_ERROR, message: 'The video cannot be added' }));
        }

        const newClips = [...(playlist?.clips ?? [])];
        newClips.splice(overMetadata.itemIndex, 0, targetClip.distributionId);

        actions.push(of(updatePlaylistAction({ clips: newClips, publisherId: playlist.publisherId })));
      }

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