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

import { selectedHubSelector, selectedWatchIdSelector, watchesPageSelector, watchesSelector } from '../selectors';
import { getWatchesAction, setSelectedWatchAction, setWatchesAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getToken } from '@/modules/@common/token/helpers';

const queryGQL = `
query hostedWatches(
  $publisherId: Int,
  $searchText: String,
  $page: Int,
) {
  hostedWatches(
    publisherId: $publisherId,
    searchText: $searchText,
    page: $page,
  ) {
    recordsTotal
    page
    pageSize
    records {
      id
      title
      folderName
      watchChannels {
        id
        title
      }
    }
  }
}`;

export default (action$, state$) =>
  action$.pipe(
    ofType(getWatchesAction.type),
    debounce((action) => timer(action.payload?.searchText ? 500 : 0)),
    filter(() => !!getToken()),
    switchMap(({ payload: { searchText = '', isNext = false } = {} }) => {
      const selectedWatchId = selectedWatchIdSelector(state$.value);

      return gqlRequest({
        query: queryGQL,
        variables: {
          publisherId: selectedHubSelector(state$.value).id,
          page: isNext ? watchesPageSelector(state$.value) + 1 : 1,
          searchText,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          let watches = {};

          const actions = [];

          if (!errors.length) {
            watches = data.hostedWatches;
          }

          const watchRecords = isNext
            ? {
                ...watches,
                records: [...watchesSelector(state$.value), ...watches.records],
              }
            : watches;

          actions.push(of(setWatchesAction(watchRecords)));

          if (!watchRecords.records.some((watch) => watch.id === selectedWatchId)) {
            const [firstWatch] = watchRecords.records;

            Router.push(`/watch${firstWatch ? `/${firstWatch.id}` : ''}`);

            const watchData = firstWatch
              ? {
                  id: firstWatch.id,
                  title: firstWatch.title,
                  folderName: firstWatch.folderName,
                }
              : {
                  id: null,
                  title: null,
                  folderName: null,
                };

            actions.push(of(setSelectedWatchAction(watchData)));
          }

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