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

import { EVENT_STATUS_ACTIVE } from '../../constants';

import {
  getLiveEventByIdAction,
  getPublisherPlayersAction,
  setIsLoadingAction,
  setLiveEventDataAction,
  setLiveStreamDataAction,
} from '../slices';
import { gqlRequest } from '@/modules/@common/request';

dayjs.extend(durationPlugin);

const queryGQL = `
  query getLiveEventById($id: Int!) {
    getLiveEventById(id: $id) {
      id
      name,
      description,
      guid,
      streamId,
      timezone,
      indicationText,
      indicationColor,
      playerId,
      preEventText,
      preEventType,
      preEventId,
      postEventText,
      postEventType,
      postEventId,
      transitionText,
      countdown,
      liveEventSchedules {
        id
        title
        startTime
        endTime
        durationIn
      },
      player {
        name,
        id,
        publisher {
          name,
          id
        }
      },
      aspectRatio,
      status,
      recurrent,
      recurrentEndDate,
      displayViewersCounter,
      forcePoster,
      forcePosterType,
    }
  }
`;

export default (action$) =>
  action$.pipe(
    ofType(getLiveEventByIdAction.type),
    switchMap((action) => {
      const { copy } = action.payload;

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

          if (!errors.length) {
            const { getLiveEventById } = data;

            if (!Object.keys(getLiveEventById).length) {
              Router.push('/live');
            } else {
              const liveEventSchedules = copy
                ? getLiveEventById.liveEventSchedules.filter((schedule) => schedule.startTime > Date.now())
                : getLiveEventById.liveEventSchedules;

              const liveEventSchedulesResult = liveEventSchedules.map((schedule) => {
                const duration = dayjs
                  .duration(schedule.endTime - schedule.startTime)
                  .as(schedule.durationIn.toLowerCase());

                return {
                  ...schedule,
                  duration,
                };
              });

              const liveEvent = {
                ...getLiveEventById,
                eventStatus: copy ? EVENT_STATUS_ACTIVE : getLiveEventById.status,
                id: copy ? null : getLiveEventById.id,
                name: copy ? `Copy of ${getLiveEventById.name}` : getLiveEventById.name,
                streamId: copy ? '' : getLiveEventById.streamId,
                liveEventSchedules: liveEventSchedulesResult,
                description: getLiveEventById.description ?? '',
                guid: getLiveEventById.guid ?? '',
              };

              actions.push(
                of(
                  setLiveEventDataAction({
                    ...liveEvent,
                    prevValue: liveEvent,
                  }),
                ),
                of(
                  setLiveStreamDataAction({
                    repeatRequest: false,
                    copy,
                    streamId: getLiveEventById.streamId,
                  }),
                ),
                of(
                  getPublisherPlayersAction({
                    publisherId: liveEvent.player.publisher.id,
                  }),
                ),
              );
            }
          }

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

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