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

import { playlistsEntitiesSelector } from '../selectors';
import {
  getPlaylistByIdAction,
  getPlaylistVideosAction,
  setPlaylistEntityAction,
  updatePlaylistAction,
} from '../slices';
import { gqlRequest } from '@/modules/@common/request';

const queryGQL = `
  mutation updatePlaylist(
    $playlistId: Int!,
    $publisherId: Int,
    $name: String,
    $clips: [String],
    $playerId: Int,
    $isPrefix: Boolean,
    $status: Boolean
  ) {
    updatePlaylist(
      playlistId: $playlistId,
      publisherId: $publisherId,
      name: $name,
      clips: $clips,
      playerId: $playerId,
      isPrefix: $isPrefix,
      status: $status
    ){
      playlistId
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(updatePlaylistAction.type),
    filter(({ payload }) => payload.publisherId),
    concatMap(({ payload: { playlistId, callBackAction = null, ...restParams } }) => {
      const playlistsEntities = playlistsEntitiesSelector(state$.value);

      const data = { ...restParams };

      if (restParams.clips) {
        data.clips = restParams.clips.filter((id) => id);
      }

      const playlist = playlistsEntities[playlistId];
      const updatedPlaylist = { ...playlist, ...data };

      if (restParams.aiPlaylist) {
        updatedPlaylist.clips = [`${restParams.aiPlaylist}`, ...updatedPlaylist.clips];
      }

      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          ...data,
          playlistId,
        },
      }).pipe(
        concatMap(() => {
          const actions = [];

          if (callBackAction) {
            actions.push(of(callBackAction()));
          }

          if (!playlist) {
            return concat(...actions, of(getPlaylistByIdAction({ playlistId })));
          }

          if (updatedPlaylist?.clips?.length) {
            return concat(...actions, of(getPlaylistVideosAction(updatedPlaylist.clips)));
          }

          return EMPTY;
        }),
      );

      return concat(of(setPlaylistEntityAction({ [playlist.id]: updatedPlaylist })), stream$);
    }),
  );
