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

import { MODULE_CHAPTERS, MODULE_HIGHLIGHTS, MODULE_SLIDES } from '../../constants';

import { setAction as chaptersSetAction } from '../../../Chapters/redux/slices';
import { setAction as highlightsSetAction } from '../../../Highlights/redux/slices';
import { setAction as slidesSetAction } from '../../../Slides/redux/slices';
import { activeModuleSelector, selectedVideoSelector } from '../selectors';
import { setAction, warnEditAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';

import {
  getCallback,
  removeCallback,
  setCallback,
} from '@/modules/editorial/aiWorkbench/AiWorkbench/components/ConfirmWarnEdit/ConfirmWarnEdit';

const queryGQL = `
  query AiWorkbenchWarnEditConfirm(
    $videoId: String!,
    $activeModule: String!
  ) {
    aiWorkbenchWarnEditConfirm(
      videoId: $videoId,
      activeModule: $activeModule,
    ) {
      shouldWarn
      updatedBy
      updatedAt
    }
  }
`;

const SET_STATE_ACTION = {
  [MODULE_SLIDES]: slidesSetAction,
  [MODULE_CHAPTERS]: chaptersSetAction,
  [MODULE_HIGHLIGHTS]: highlightsSetAction,
};

export default (action$, state$) =>
  action$.pipe(
    ofType(warnEditAction.type),
    switchMap((action) => {
      const video = selectedVideoSelector(state$.value);
      const activeModule = activeModuleSelector(state$.value);
      const setStateAction = SET_STATE_ACTION[activeModule] || (() => null);

      setCallback(action.payload);

      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          videoId: video.uid,
          activeModule,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];
          const { shouldWarn, updatedBy, updatedAt } = data.aiWorkbenchWarnEditConfirm;

          if (!errors?.length) {
            actions.push(
              of(
                setAction({
                  shouldShowWarnEditConfirm: shouldWarn,
                  updatedBy,
                  updatedAt,
                }),
              ),
            );

            if (!shouldWarn) {
              const callback = getCallback();
              callback();

              removeCallback();
            } else {
              actions.push(of(setStateAction({ isLoading: false })));
            }
          }

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

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