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

import { selectedVideoSelector } from '../../../AiWorkbench/redux/selectors';
import { addTranslationFileAction, setAction, uploadAction } from '../slices';
import { gqlRequest, uploadS3 } from '@/modules/@common/request';

const queryGetLinksGQL = `
  query Query($name: String, $filename: String!, $thumbnail: String, $contentOwnerId: Float!) {
    S3UploadLink(name: $name, filename: $filename, thumbnail: $thumbnail, contentOwnerId: $contentOwnerId) {
      uploadUrl
      downloadUrl
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(uploadAction.type),
    switchMap((action) => {
      const selectedVideo = selectedVideoSelector(state$.value);
      const contentOwnerId = selectedVideo.contentOwner;
      const { file, language } = action.payload;
      const filename = file.name.replace(/\s/g, '_');

      const stream$ = gqlRequest({
        query: queryGetLinksGQL,
        variables: {
          contentOwnerId,
          filename,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const { uploadUrl, downloadUrl } = data.S3UploadLink;
          const actions = [];

          if (!errors?.length) {
            const uploadStream$ = uploadS3(uploadUrl, file).pipe(
              switchMap((response) => {
                if (!response.errors.length) {
                  return concat(
                    of(
                      addTranslationFileAction({
                        file: downloadUrl,
                        lang: language,
                      }),
                    ),
                  );
                }

                return concat(of(setAction({ isLoading: false })));
              }),
            );

            actions.push(uploadStream$);
          } else {
            actions.push(of(setAction({ isLoading: false })));
          }

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

      return concat(of(setAction({ isLoading: true })), stream$);
    }),
  );
