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

import { MODE_LIST, MODE_PLAYLIST } from '../../../../common/constants';
import { TYPE_ERROR } from '@/modules/@common/notify/constants';
import { QUERY_PARAM_PLAYLIST } from '@/modules/editorial/constants/routing';

import { playersSelector, playlistsSelector } from '../../selectors';
import {
  getPlaylistByIdAction,
  setModeAction,
  setPlaylistIdAction,
  setPlaylistsAction,
  updatePlaylistAction,
} from '../../slices';
import { addQueriesAction, removeQueriesAction } from '@/modules/@common/location/redux/slices';
import { gqlRequest } from '@/modules/@common/request';
import { showNotificationAction } from '@/modules/layout/redux/slices';

const TYPE = 'EDITORIAL';

const queryGQL = `
  query getPlaylistById(
    $id: Int!,
  ) {
    getPlaylistById(
      id: $id,
    ){
      id
      playerId
      status
      isPrefix
      name
      url
      createdAt
      updatedAt
      createdBy
      updatedBy
      clips
      shuffle
      playerAlias
      widgetName
      pubName
      publisherId
      publisherName
      playerAspectRatio
      type
      isFallback
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(getPlaylistByIdAction.type),
    concatMap(({ payload }) => {
      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          id: payload?.id,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

          if (!errors.length) {
            if (data.getPlaylistById.type !== TYPE) {
              return of(
                showNotificationAction({
                  type: TYPE_ERROR,
                  message: `Playlist ${data.getPlaylistById.id} doesn't exist`,
                }),
              );
            }

            const playlists = playlistsSelector(state$.value);
            const players = playersSelector(state$.value);

            // this queries gets from wordpress mode
            const { title } = Router.query;

            const player = players.find((item) => item?.id === data.getPlaylistById.playerId);

            // convert from dayjs to milliseconds
            const createdAt = dayjs(data.getPlaylistById.createdDate).valueOf();
            const updatedAt = data.getPlaylistById.updatedDate
              ? dayjs(data.getPlaylistById.updatedDate).valueOf()
              : data.getPlaylistById.updatedDate;

            const newPlaylist = {
              ...data.getPlaylistById,
              createdAt,
              updatedAt,
              isStatusUpdateDisabled: !data.getPlaylistById.status && !player,
              displayEmbedCode: player?.displayEmbedCode,
            };

            const newPlaylists = [...playlists];
            const playlistIndex = newPlaylists.findIndex((playlist$) => playlist$.id === newPlaylist.id);
            if (playlistIndex !== -1) {
              newPlaylists.splice(playlistIndex, 1, { ...newPlaylists[playlistIndex], ...newPlaylist });
            } else {
              newPlaylists.unshift(newPlaylist);
            }

            actions.push(
              of(setPlaylistIdAction(data.getPlaylistById.id)),
              of(addQueriesAction({ [QUERY_PARAM_PLAYLIST]: data.getPlaylistById.id })),
              of(setModeAction(MODE_PLAYLIST)),
              of(setPlaylistsAction(newPlaylists)),
            );

            // update name for wordpress mode
            if (payload?.isInitial && title && title !== data.getPlaylistById.name) {
              actions.push(of(updatePlaylistAction({ name: title, publisherId: data.getPlaylistById.publisherId })));
            }
          } else {
            actions.push(of(removeQueriesAction(QUERY_PARAM_PLAYLIST)), of(setModeAction(MODE_LIST)));
          }

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

      return concat(stream$);
    }),
  );
