import dayjs from 'dayjs';
import utcPlugin from 'dayjs/plugin/utc';
import { ofType } from 'redux-observable';
import { concat, of, timer } from 'rxjs';
import { debounce, filter, switchMap } from 'rxjs/operators';

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

import { getTimeOption } from '../../helpers';
import * as selectors from '../selectors';
import { getLiveEventByIdAction, getLiveEventsAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { getToken } from '@/modules/@common/token/helpers';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';

dayjs.extend(utcPlugin);

const queryGQL = `
  query analyticsLiveEvents(
    $search: String,
    $eventFilter: String,
    $page: Int,
    $pageSize: Int,
    $sortBy: String,
    $sortOrder: String,
    $status: String,
    $startTime: Float,
    $endTime: Float
  ) {
    analyticsLiveEvents(
      search: $search,
      eventFilter: $eventFilter,
      page: $page,
      pageSize: $pageSize,
      sortBy: $sortBy,
      sortOrder: $sortOrder,
      status: $status,
      startTime: $startTime,
      endTime: $endTime
    ) {
      total
      page
      pageSize
      results {
        id
        name
        timezone
        startTime
        endTime
      }
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(getLiveEventsAction.type),
    debounce((action) => timer(action.payload?.search ? 1000 : 0)),
    filter(() => !!getToken()),
    switchMap((action) => {
      const timezone = getUserTimezoneSelector(state$.value);

      const state = state$.value;

      const calendar = selectors.calendarSelector(state);
      const calendarCustom = selectors.calendarCustomSelector(state);

      let requestParams = {};

      if (calendar === CALENDAR_FILTER_VALUE.custom) {
        const startTime = dayjs(calendarCustom.dateStart).utc().valueOf();
        const endTime = dayjs(calendarCustom.dateEnd).utc().valueOf();

        requestParams = {
          startTime,
          endTime,
        };
      } else if (calendar.value) {
        const startTime = dayjs().subtract(1, calendar.value).utc().valueOf();
        const endTime = dayjs().utc().valueOf();

        requestParams = {
          startTime,
          endTime,
        };
      }

      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          ...requestParams,
          page: 1,
          search: action.payload?.search,
          pageSize: 500,
          sortBy: 'endTime',
          sortOrder: 'DESC',
          eventFilter: 'PAST',
          status: 'all',
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

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

            const eventsOptions =
              results?.map((item) => ({
                label: item.name,
                value: item.id,
                time: getTimeOption(item.startTime, item.endTime, timezone),
              })) ?? [];

            actions.push(
              of(
                setFieldAction({
                  eventsOptions,
                }),
              ),
            );

            if (action.payload?.search === undefined && eventsOptions?.length) {
              actions.push(
                of(
                  setFieldAction({
                    event: eventsOptions[0],
                  }),
                ),
                of(getLiveEventByIdAction({ id: eventsOptions[0].value })),
              );
            }
          }
          return concat(...actions);
        }),
      );

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