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

import { QUERY_PARAM_CHANNEL, QUERY_PARAM_WATCH_ID } from '@/modules/editorial/constants/routing';

import { getChannelByIdAction, updateStoreByPropAction } from '../slices';
import { removeQueriesAction } from '@/modules/@common/location/redux/slices';
import { gqlRequest } from '@/modules/@common/request';

const queryGQL = `
  query ChannelQuery($watchId: Int!, $id: Int!) {
    channel(watchId: $watchId, id: $id){
      id
      watchId
      order
      videoFilterId
      playlistId
      title
      name
      description
      bg
      logo
      size
      design
      titleColor
      descColor
      vidTitleColor
      vidInfoColor
      cTitleColor
      cVidTitleColor
      cVidInfoColor
      cTitleSize
      cVidTitleSize
      cVidInfoSize
      bgLogo
      updatedBy
      updatedAt
      createdBy
      createdAt
      MRSSForExport
      MRSSAliasDomain
      MRSSLinkUrl
      includeSponsoredContent,
      frequency,
      supplyTagId,
      supplyTagName,
    }
  }
`;

export default (action$) =>
  action$.pipe(
    ofType(getChannelByIdAction.type),
    mergeMap(({ payload }) => {
      const stream$ = gqlRequest({
        query: queryGQL,
        variables: {
          watchId: payload.watchId,
          id: payload.channelId,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          const actions = [];

          if (errors.length) {
            actions.push(of(removeQueriesAction([QUERY_PARAM_WATCH_ID, QUERY_PARAM_CHANNEL])));
          } else {
            const valuesWithoutNull = Object.keys(data.channel).reduce((acc, propName) => {
              if (data.channel[propName] !== null || propName === 'logo') {
                return {
                  ...acc,
                  [propName]: data.channel[propName],
                };
              }

              return acc;
            }, {});

            if ('supplyTagId' in valuesWithoutNull && 'supplyTagName' in valuesWithoutNull) {
              valuesWithoutNull.supplyTag = {
                id: valuesWithoutNull.supplyTagId,
                name: valuesWithoutNull.supplyTagName,
              };

              delete valuesWithoutNull.supplyTagId;
              delete valuesWithoutNull.supplyTagName;
            }

            actions.push(of(updateStoreByPropAction(valuesWithoutNull)));
          }

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

      return concat(
        of(updateStoreByPropAction({ isLoading: true })),
        stream$,
        of(updateStoreByPropAction({ isLoading: false })),
      );
    }),
  );
