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

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

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

const queryGQL = `
  query WatchQuery($id: Int!) {
    watch(id: $id){
      id
      accountId
      publisher {
        id
        name
      }
      title
      description
      status
      environment
      feeds {
        id
        name
      }
      domain {
        id
        name
      }
      
      search
      deepSearch
      genAI
      comments
      autoplay
      autoplayMobile
      autoplayNext
      sound
      soundMobile
      seo
      sitemap
      download
      emailShare
      socialShare
      shareService
      highlights
      transcriptDownload
      slides
      chapters
      
      appearance
      font
      fontSize
      color
      bg
      dockMobile
      offsetTop
      offsetBottom
      cTitleSize
      cTitleColor
      cDescSize
      cDescColor
      cVidTitleSize
      cVidTitleColor
      cInfoColor
      engagement
      layout
      popupSize
      
      sTitleSize
      sTitleColor
      sVidTitleSize
      sVidTitleColor
      sVidInfoSize
      sVidInfoColor
      searchPlaceholder
      searchLabel
      
      tags
      tagTypes
      fixedTags
      excludedTags
      tagPages
      tagCount
      tagMin
      tagMax
      
      language
      languages {
        label
        value
      },
      tabOrder
      dsTags
      dsRedirect
      dblClickFlow
      rtl
      ad
      adHubId
      adWidgetId
      videoPreview
      delayPreview
      css
      
      player {
        id
        name
        alias
        publisherId
      }
      inlinePlayer {
        id
        name
        alias
        publisherId
      }
      verticalPlayer {
        id
        name
        alias
        publisherId
      }
      inlineVerticalPlayer {
        id
        name
        alias
        publisherId
      }
      myWatch
      widgetOrigin
      js
      backMobile
      genAICount
      
      configuration
      folderName
      
      createdAt
      createdBy
      updatedAt
      updatedBy
    }
  }
`;

const toAutocompleteValue = (item, extra = {}) => ({
  value: item.id,
  label: item.name,
  ...extra,
});

const getResponse = ({ data: { watch } }) => ({
  ...watch,
  hub: toAutocompleteValue(watch.publisher),
  source: watch.feeds.map((item) => toAutocompleteValue(item)),
  domain: watch.domain ? toAutocompleteValue(watch.domain) : null,
  dsTags: watch.dsTags,
});

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

          if (response.errors.length) {
            actions.push(of(removeQueriesAction([QUERY_PARAM_WATCH_ID])));
          } else {
            const watchData = getResponse(response);

            const normalizeValues = Object.keys(watchData).reduce((acc, curr) => {
              if (watchData[curr] !== null) {
                return {
                  ...acc,
                  [curr]: watchData[curr],
                };
              }

              if (curr === 'languages') {
                return {
                  ...acc,
                  [curr]: [],
                };
              }

              return acc;
            }, {});

            actions.push(of(updateStoreByPropAction({ ...normalizeValues })));
            actions.push(of(getAccountFeatures(normalizeValues.accountId)));
          }

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

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