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

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

import { getPlaylistVideosAction, setPlaylistVideosEntitiesAction } 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';

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;
};

export default (action$) =>
  action$.pipe(
    ofType(getPlaylistVideosAction.type),
    switchMap(({ payload: clips }) => {
      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          clipIds: clips,
          size: clips?.length ?? 10,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

          if (!errors.length) {
            const videosList = data.clipSearch.videos.map((video$) => ({
              ...video$,
              startTime: 0,
              endTime: video$.videoLength || 0,
              videoStatus: video$.status,
              distributionStatus: video$.status,
              keywords: video$.keywords,
            }));

            const videos = clips.map((id) => {
              const video = videosList.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 = !videosList.find(({ distributionId }) => distributionId === id);

              return {
                ...video,
                distributionId: id,
                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',
              };
            });

            const videosMap = videos.reduce(
              (acc, curr) => ({
                ...acc,
                [`${curr.distributionId}`]: curr,
              }),
              {},
            );

            actions.push(of(setPlaylistVideosEntitiesAction(videosMap)));
          }

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

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