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

import { EVENT_UX_TYPES_SAME } from '../../constants';
import { TYPE_SUCCESS } from '@/modules/@common/notify/constants';

import { getEventData } from '../../helpers/request';
import { createLiveEventAction, setIsLoadingAction, slice, updateLiveEventFormAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getUserIdSelector } from '@/modules/@common/user/redux/selectors';
import { showNotificationAction } from '@/modules/layout/redux/slices';

const queryGQL = `
  mutation createLiveEvent(
    $name: String!,
    $description: String,
    $guid: String,
    $streamId: String!,
    $timezone: String,
    $indicationText: String,
    $indicationColor: String,
    $playerId: Float!,
    $preEventText: String,
    $preEventType: String,
    $preEventId: String,
    $postEventText: String,
    $postEventType: String,
    $postEventId: String,
    $transitionText: String,
    $countdown: Boolean,
    $liveEventSchedules: [LiveEventSchedulesInputType]!,
    $startTime: Float,
    $endTime: Float,
    $aspectRatio: String!,
    $recurrent: Boolean,
    $recurrentEndDate: Float,
    $displayViewersCounter: Boolean,
    $forcePoster: Boolean,
    $forcePosterType: String,
  ) {
    createLiveEvent(
      name: $name,
      description: $description,
      guid: $guid,
      streamId: $streamId,
      timezone: $timezone,
      indicationText: $indicationText,
      indicationColor: $indicationColor,
      playerId: $playerId,
      preEventText: $preEventText,
      preEventType: $preEventType,
      preEventId: $preEventId,
      postEventText: $postEventText,
      postEventType: $postEventType,
      postEventId: $postEventId,
      transitionText: $transitionText,
      countdown: $countdown,
      liveEventSchedules: $liveEventSchedules,
      startTime: $startTime,
      endTime: $endTime,
      aspectRatio: $aspectRatio,
      recurrent: $recurrent,
      recurrentEndDate: $recurrentEndDate,
      displayViewersCounter: $displayViewersCounter,
      forcePoster: $forcePoster,
      forcePosterType: $forcePosterType,
    ) {
      id
      name,
      description,
      guid,
      streamId,
      timezone,
      indicationText,
      indicationColor,
      playerId,
      preEventText,
      preEventType,
      preEventId,
      postEventText,
      postEventType,
      postEventId,
      transitionText,
      countdown,
      liveEventSchedules {
        title
        startTime
        endTime
        durationIn
      },
      aspectRatio,
      status,
      recurrent,
      recurrentEndDate,
      displayViewersCounter,
      forcePoster,
      forcePosterType,
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(createLiveEventAction.type),
    switchMap((action) => {
      const userId = getUserIdSelector(state$.value);
      const body = getEventData(state$.value[slice.name], false, userId);

      if (body.postEventType === EVENT_UX_TYPES_SAME) {
        body.postEventType = body.preEventType;
      }

      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          ...action.payload,
          ...body,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [of(setIsLoadingAction(false))];

          if (!errors.length) {
            actions.push(
              of(
                updateLiveEventFormAction({
                  id: data.createLiveEvent.id,
                }),
              ),
              of(
                showNotificationAction({
                  type: TYPE_SUCCESS,
                  message: 'Event saved',
                }),
              ),
            );
          }

          return concat(...actions);
        }),
        tap(({ payload }) => {
          if (payload?.id) {
            Router.replace(`/live/${payload.id}`);
          }
        }),
      );

      return concat(of(setIsLoadingAction(true)), stream$);
    }),
  );
