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

import {
  TITLE_VIDEO_IS_SPONSORED,
  TOOLTIP_VIDEO_IS_SPONSORED,
} from '@/modules/editorial/RightSideBar/common/constants';

import { getPlaylistVideosAction, setPlaylistVideosAction } from '../../slices';
import { getDuration } from '@/modules/@common/helpers/time';
import { gqlRequest } from '@/modules/@common/request';
import { isVideoUnsafe } from '@/modules/editorial/editorialVideoInfo/helpers';
import { isVideoAvailable } from '@/modules/editorial/RightSideBar/common/helpers';
import { playlistIdSelector } from '@/modules/editorial/RightSideBar/TabPlaylist/redux/selectors';
import { updateLiveEventFormAction } from '@/modules/liveEvents/liveEvent/redux/slices';

const queryGQL = `
  query clipSearch($clipIds: [String], $size: Int) {
    clipSearch(clipIds: $clipIds, size: $size){
      totalCount
      videos {
        uid
        distributionId
        name
        thumbnailUrl
        thumbnailFiles {
          width
          height
          file
        }
        videoLength
        status
        contentOwner
        keywords {
          category
          value
        }
        approval {
          status
        }
        aspectRatio
        access {
          level
        }
        targetingStatus
        sponsored {
          sponsored
        }
      }
    }
  }
`;

const defineThumbnail = (thumbnailUrl, thumbnailFiles) => {
  const thumbnail360 = thumbnailFiles?.find((thumbnail) => thumbnail.height === 360)?.file;

  return thumbnail360 ?? thumbnailUrl;
};

const getResponse = ({ data: { clipSearch } }) => {
  const videos = clipSearch?.videos;
  return {
    videos: videos?.map((video) => ({
      ...video,
      startTime: 0,
      endTime: video.videoLength || 0,
      videoStatus: video.status,
      distributionStatus: video.status,
      keywords: video.keywords,
    })),
  };
};

export default (action$, state$) =>
  action$.pipe(
    ofType(getPlaylistVideosAction.type),
    filter((action) => action.payload?.clips?.length && action.payload?.playlistId),
    switchMap(({ payload: { clips, eventImages, playlistId } }) => {
      const playlistId$ = playlistIdSelector(state$.value);

      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          clipIds: clips.map((clip) => clip.toString()),
          size: clips?.length ?? 10,
        },
      }).pipe(
        switchMap((response) => {
          const actions = [];

          if (!response.errors.length) {
            const videoList = getResponse(response);

            const videosListSorted = clips
              .map((clip) => videoList.videos.find((listItem) => clip === listItem.distributionId))
              .filter((video) => video);

            if (eventImages) {
              return concat(of(updateLiveEventFormAction({ [eventImages]: videosListSorted[0]?.thumbnailFiles })));
            }

            const videos = clips.map((id) => {
              const video = videosListSorted.find(({ distributionId }) => distributionId === id) || {};
              const isAvailable = isVideoAvailable(video);

              let videoAlertMessage = '';
              let videoAlertMessageTooltip = '';

              if (!isAvailable) {
                videoAlertMessage = 'Video was archived';
              }

              if (video.videoStatus === 'PROCESSING') {
                videoAlertMessage = 'Video analysis still in progress';
              }

              if (video?.access?.level === 'PRIVATE') {
                videoAlertMessage = 'Private video, access controlled by its owner';
              }

              if (video?.sponsored?.sponsored) {
                videoAlertMessage = TITLE_VIDEO_IS_SPONSORED;
                videoAlertMessageTooltip = TOOLTIP_VIDEO_IS_SPONSORED;
              }

              const isDeleted = !videoList.videos.find(({ distributionId }) => distributionId === id);

              return {
                ...video,
                distributionId: Number.isNaN(parseInt(id, 10)) ? id : parseInt(id, 10),
                isAvailable,
                isDeleted,
                isUnsafe: isVideoUnsafe(video),
                isHasTargeting: video.targetingStatus === 'ON',
                videoName: video.name ?? '',
                videoAlertMessage,
                videoAlertMessageTooltip,
                videoThumbnailUrl: defineThumbnail(video.thumbnailUrl, video.thumbnailFiles) || '',
                videoTime: video?.endTime ? getDuration(video.endTime - video.startTime) : '00:00',
              };
            });

            actions.push(of(setPlaylistVideosAction({ playlistId: playlistId ?? playlistId$, videos })));
          }

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

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