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

import { PLAYER_ID_FILTER_NAME, PLAYER_NAME_FILTER_NAME, PLAYER_TYPE_FILTER_NAME } from '../../constants';

import { getUserPlayersAction, setFieldAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';

const query = `
  query analyticsUserPlayers(
    $searchText: String
  ) {
    analyticsUserPlayers(
      searchText: $searchText
    ) {
      id
      name
      alias
      playerType {
        id
        name
      }
      publisherDomain {
        id
        domain
      }
    }
  }
`;

export default (action$) =>
  action$.pipe(
    ofType(getUserPlayersAction.type),
    debounce((action) => timer(action.payload ? 1000 : 0)),
    switchMap((action) => {
      let requestParams = {};

      if (action.payload?.length) {
        requestParams = {
          searchText: action.payload,
        };
      }

      const stream$ = gqlRequest({
        query,
        variables: {
          ...requestParams,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

          if (!errors.length && data?.analyticsUserPlayers?.length) {
            const fields = data.analyticsUserPlayers.reduce((acc, cur) => {
              const isPlayerTypeAlreadyExists = acc?.[`${PLAYER_TYPE_FILTER_NAME}_FILTER_OPTIONS`]?.some(
                (item) => item?.value === cur.playerType?.id,
              );

              const playerTypesOptions = isPlayerTypeAlreadyExists
                ? (acc?.[`${PLAYER_TYPE_FILTER_NAME}_FILTER_OPTIONS`] ?? [])
                : [
                    ...(acc?.[`${PLAYER_TYPE_FILTER_NAME}_FILTER_OPTIONS`] ?? []),
                    {
                      label: cur.playerType.name,
                      value: cur.playerType.id,
                    },
                  ];

              return {
                [`${PLAYER_NAME_FILTER_NAME}_FILTER_OPTIONS`]: [
                  ...(acc?.[`${PLAYER_NAME_FILTER_NAME}_FILTER_OPTIONS`] ?? []),
                  {
                    label: cur.alias,
                    value: cur.alias,
                  },
                ],
                [`${PLAYER_ID_FILTER_NAME}_FILTER_OPTIONS`]: [
                  ...(acc?.[`${PLAYER_ID_FILTER_NAME}_FILTER_OPTIONS`] ?? []),
                  {
                    label: cur.name,
                    value: cur.name,
                  },
                ],
                [`${PLAYER_TYPE_FILTER_NAME}_FILTER_OPTIONS`]: playerTypesOptions,
              };
            }, {});

            actions.push(of(setFieldAction(fields)));
          }
          return concat(...actions);
        }),
      );

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