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

import * as selectors from '../selectors';
import { getChartDataAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';

dayjs.extend(durationPlugin);

const defineInterval = (sessions) => {
  if (sessions.some((session) => dayjs.duration(session.endTime - session.startTime).as('MINUTES') <= 30)) {
    return {
      unit: 'MINUTES',
      value: 1,
    };
  }

  return {
    unit: 'MINUTES',
    value: 5,
  };
};

const prepareChartData = (response, sessions) =>
  response?.map((item) => {
    const data = [...item.data]?.map((point, pointIndex) => {
      const { users, usersInFocus, minutesTotal, minutesTotalInFocus, minutesAvg, minutesAvgInFocus } = point;

      if (pointIndex === 0 || pointIndex === item.data.length - 1) {
        return {
          time: +point.time,
          value: users || minutesTotal || minutesAvg || 0,
          valueInFocus: usersInFocus || minutesTotalInFocus || minutesAvgInFocus || 0,
          showDot: true,
        };
      }

      return {
        time: +point.time,
        value: users || minutesTotal || minutesAvg || 0,
        valueInFocus: usersInFocus || minutesTotalInFocus || minutesAvgInFocus || 0,
      };
    });

    return {
      ...item,
      data,
      name: sessions.find((session) => session.id === item.id)?.label ?? item.id,
    };
  }) ?? [];

export default (action$, state$) =>
  action$.pipe(
    ofType(getChartDataAction.type),
    switchMap(() => {
      const state = state$.value;

      const activeTab = selectors.activeTabSelector(state);
      const event = selectors.eventSelector(state);
      const sessions = selectors.sessionsSelector(state);

      const interval = defineInterval(sessions);

      const stream$ = gqlRequest({
        query: activeTab.query,
        variables: {
          eventId: event?.value ?? null,
          scheduleSessionIds: sessions?.map((session) => +session.value) ?? [],
          interval,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

          if (!errors.length) {
            const chartData = {
              ...data.livePerformanceUsers,
              ...data.livePerformanceMinutesTotal,
              ...data.livePerformanceMinutesAvg,
            };

            actions.push(
              of(
                setFieldAction({
                  chartData: prepareChartData(chartData.data, sessions),
                }),
              ),
            );
          }

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

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