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

import { LUMINOUS_SOURCE_TYPE } from '@/modules/@common/constants/file';
import { mapApiError } from '@/modules/@common/constants/mapApiError';
import { TYPE_SUCCESS } from '@/modules/@common/notify/constants';

import convertSecToMs from '../../helpers/converSecToMs';
import {
  endTrimTimeSelector,
  nameSelector,
  originalVideoIdSelector,
  originalVideoSelector,
  startTrimTimeSelector,
} from '../selectors';
import { makeTrimAction, setStateAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { showNotificationAction } from '@/modules/layout/redux/slices';

const query = `
  mutation addChildVideo(
    $videoId: String!,
    $name: String!,
    $startTime: Float!,
    $endTime: Float!,
    $origin: String!
    $type: String,
  ) {
    addChildVideo(
      videoId: $videoId,
      name: $name,
      startTime: $startTime,
      endTime: $endTime,
      origin: $origin,
      type: $type,
    ) {
      refId
       access {
          level
          users {
            id
            role
            name
            email
            firstName
            lastName
          }
        }
      type
      status
      name
      created
      updated
      videoUrl
      sourceVideoFile {
        width
        height
        file
        sizeInBytes
      }
      videoFiles {
        width
        height
        file
        sizeInBytes
      }
      ccUrl
      thumbnailUrl
      thumbnailFiles {
        width
        height
        file
        sizeInBytes
      }
      contentOwner
      videoCreationDate
      feedSource
      feedDescription
      videoLength
      plot
      uid
      originalName
      releaseYear
      publisherLink
      landingPageLink
      approval {
        status
        updated
        refUserId
      }
      lang
      videoParent
      iab {
        data
      }
      keywords {
        category
        value
        probability
        version
        id
      }
      label {
        labelId
        name
        value
        color
      }
      distributionId
      aspectRatio
      evergreen
      origin
      defaultVideoUrl
    }
  }
`;

const parseResponse = ({ data: { addChildVideo } }) => addChildVideo;

export default (action$, state$) =>
  action$.pipe(
    ofType(makeTrimAction.type),
    switchMap(() => {
      const startTrimTime = startTrimTimeSelector(state$.value);
      const endTrimTime = endTrimTimeSelector(state$.value);
      const name = nameSelector(state$.value);
      const originalVideoId = originalVideoIdSelector(state$.value);
      const originalVideo = originalVideoSelector(state$.value);

      const stream$ = gqlRequest(
        {
          query,
          variables: {
            videoId: originalVideoId,
            startTime: convertSecToMs(startTrimTime),
            endTime: convertSecToMs(endTrimTime),
            name,
            origin: LUMINOUS_SOURCE_TYPE,
            playbackImmediately: true,
            type: 'TRIM',
          },
        },
        {
          mapError: mapApiError(),
        },
      ).pipe(
        switchMap((response) => {
          if (!response.errors.length) {
            const actions = [];

            const trimedVideo = parseResponse(response);

            let accessUsers = trimedVideo.access.users;
            if (originalVideo.access.users?.length) {
              accessUsers = accessUsers.concat(originalVideo.access.users.filter((user) => user.role !== 'OWNER'));
            }

            trimedVideo.access = {
              ...trimedVideo.access,
              users: accessUsers,
            };

            actions.push(
              of(
                showNotificationAction({
                  type: TYPE_SUCCESS,
                  message: 'New video created successfully',
                }),
              ),
              of(setStateAction({ trimedVideo, isShowShare: true })),
            );

            return concat(...actions);
          }

          return EMPTY;
        }),
      );

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