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

import { ACCESS_LEVEL_ENUM } from '@/modules/editorial/shareAndAccess/constants';
import { UPLOAD_STATUS_COMPLETE, UPLOAD_STATUS_FAILED } from '@/modules/uploaderNew/constants';

import { getContentOwnersList } from '../../helpers/getContentOwnersList';
import { getCurrentUploadStateFromQueue, processedUploadQueueIdSelector } from '../selectors';
import {
  createVideoFromCsvAction,
  errorAction,
  isOpenAction,
  loadingAction,
  loadingProgressAction,
  ownerAction,
  setProcessUploadStatusAction,
  startUploadFromQueueAction,
} from '../slices';
import { clearAction as clearCcFilesModuleBeforeUnmount } from '@/modules/@common/ccFiles/redux/slices';
import { gqlRequest } from '@/modules/@common/request';
import { getUserContentOwnersSelector } from '@/modules/@common/user/redux/selectors';

const queryGQL = `
  mutation videoCsvCreateMutation($video: VideoCsvInputType!) {
    videoCsvCreate(video: $video) {
      uid
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(createVideoFromCsvAction.type),
    switchMap(() => {
      const userContentOwners = getUserContentOwnersSelector(state$.value);
      const processedUploadQueueId = processedUploadQueueIdSelector(state$.value);
      const state = getCurrentUploadStateFromQueue(state$.value);
      const { feed, uploadCsv, language, evergreen, notes, accessLevel, sites } = state;

      const videoData = {
        videoUrl: uploadCsv.downloadUrl,
        lang: [language.value],
        evergreen,
        access: {
          level: accessLevel,
        },
      };

      if (accessLevel === ACCESS_LEVEL_ENUM.site) {
        videoData.access.sites = sites.map((site) => site.value.toString());
      }

      if (state.ccFiles.length) {
        videoData.ccFiles = state.ccFiles;
      }

      if (feed) {
        videoData.feedId = feed.value;
      }

      if (notes.length) {
        videoData.notes = notes;
      }

      const stream$ = gqlRequest({
        query: queryGQL,
        variables: { video: videoData },
      }).pipe(
        switchMap(({ errors }) => {
          const actions = [];

          if (!errors.length) {
            const contentOwners = getContentOwnersList(userContentOwners);

            actions.push(
              of(
                loadingProgressAction({
                  percentage: 1,
                  processedUploadQueueId,
                }),
              ),
              of(ownerAction(contentOwners[0])),
              of(isOpenAction(false)),
              of(clearCcFilesModuleBeforeUnmount()),
              of(
                setProcessUploadStatusAction({
                  status: UPLOAD_STATUS_COMPLETE,
                  processedUploadQueueId,
                }),
              ),
              of(startUploadFromQueueAction()),
            );
          } else {
            actions.push(
              of(
                setProcessUploadStatusAction({
                  status: UPLOAD_STATUS_FAILED,
                  processedUploadQueueId,
                }),
              ),
              of(startUploadFromQueueAction()),
            );
          }

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

      return concat(stream$, of(loadingAction(false)), of(errorAction({})));
    }),
  );
