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

import { monitoringAction, monitoringDataAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { selectedVideoSelector } from '@/modules/editorial/editorialVideoDetails/redux/selectors';

const queryGQL = `
  query MonitoringQuery($videoId: String!, $size: Float!) {
    monitoring(videoId: $videoId, size: $size) {
      jobs {
        videoId
        childId
        childType
        type
        state
        message
        startTime
        updateTime
        progress
        properties {
          key
          value
        }
      }
    }
  }
`;

const jobTypes = [
  'TAGGING',
  'SCENE_RECOGNITION',
  'VIDEO_ENCODING',
  'VIDEO_PROCESSING',
  'VIDEO_CHILD_PROCESSING',
  'CLOSED_CAPTIONS',
  'THUMBNAIL_PROCESSING',
  'THUMBNAILS_PUBLISHING',
  'THUMBNAILS_CURRENT_FRAME_PROCESSING',
  'SPEECH_RECOGNITION',
  'AUTO_CHAPTERS',
  'VIDEO_VERSIONING',
  'VIDEO_HIGHLIGHTS_PROCESSING',
  'HIGHLIGHTS_VIDEO_PROCESSING',
  'VIDEO_SLIDES_PROCESSING',
  'VIDEO_SLIDES_PDF_PROCESSING',
  'CC_TRANSLATION_PROCESSING',
  'DESCRIPTIONS',
  'PUBLISH_VIDEO_TRANSCRIPT',
];

const getFilteredJobs = (jobs) => jobs.filter((job) => jobTypes.includes(job.type));

const getSelectedVideo = (state) => selectedVideoSelector(state);

const monitoringEpic = (action$, state$) =>
  action$.pipe(
    ofType(monitoringAction.type),
    filter(() => {
      const video = getSelectedVideo(state$.value);
      if (Router.query.aiworkbench && Router.query.videoId) {
        return true;
      }
      return !!video?.uid;
    }),
    switchMap(() => {
      const video = getSelectedVideo(state$.value);
      const videoId = Router.query.aiworkbench && Router.query.videoId ? Router.query.videoId : video.uid;

      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          videoId,
          size: 1000,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

          if (!errors.length) {
            actions.push(of(monitoringDataAction(getFilteredJobs(data.monitoring.jobs))));
          }

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

export default monitoringEpic;
