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

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

import { getWatchesAction } from '../../../Watches/redux/slices';
import * as watchSelectors from '../selectors';
import { clearAction, createWatchAction, updateStoreByPropAction } from '../slices';
import { removeQueriesAction } from '@/modules/@common/location/redux/slices';
import { gqlRequest } from '@/modules/@common/request';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';

const queryGQL = `
  mutation CreateWatch(
    $publisherId: Int,
    $title: String,
    $description: String,
    $status: Int,
    $environment: String,
    $feedIds: [Int],
    $domainId: Int,
    
    $search: Boolean,
    $deepSearch: Boolean,
    $genAI: Boolean,
    $comments: Boolean,
    $autoplay: Boolean,
    $autoplayMobile: Boolean,
    $autoplayNext: Boolean,
    $sound: Boolean,
    $soundMobile: Boolean,
    $seo: Boolean,
    $sitemap: String,
    $download: Boolean,
    $emailShare: Boolean,
    $socialShare: Boolean,
    $shareService: Boolean,
    $highlights: Boolean,
    $transcriptDownload: Boolean,
    $slides: Boolean,
    $chapters: Boolean,
    
    $appearance: String,
    $font: String,
    $fontSize: String,
    $color: String,
    $bg: String,
    $dockMobile: Boolean,
    $offsetTop: String,
    $offsetBottom: String,
    $cTitleSize: String,
    $cTitleColor: String,
    $cDescSize: String,
    $cDescColor: String,
    $cVidTitleSize: String,
    $cVidTitleColor: String,
    $cInfoColor: String,
    $engagement: [String],
    $layout: String,
    $popupSize: Int,
    
    $sTitleSize: String,
    $sTitleColor: String,
    $sVidTitleSize: String,
    $sVidTitleColor: String,
    $sVidInfoSize: String,
    $sVidInfoColor: String,
    $searchPlaceholder: String,
    $searchLabel: String,
    
    $tags: Boolean,
    $tagTypes: [String],
    $fixedTags: [String],
    $excludedTags: [String],
    $tagPages: [String],
    $tagCount: Int,
    $tagMin: Int,
    $tagMax: Int,
    
    $language: String,
    $languages: [WatchLanguageInputType],
    $tabOrder: [String],
    $dsTags: [String],
    $dsRedirect: String,
    $dblClickFlow: Boolean,
    $rtl: Boolean,
    $ad: Boolean,
    $adHubId: String,
    $adWidgetId: String,
    $videoPreview: Boolean,
    $delayPreview: Int,
    $css: String,
    $configuration: String,
    
    $myWatch: Boolean,
    $widgetOrigin: String,
    $js: String,
    $backMobile: Boolean,
    $genAICount: Int,
  ) {
    createWatch(
      publisherId: $publisherId,
      title: $title,
      description: $description,
      status: $status,
      environment: $environment,
      domainId: $domainId,
      feedIds: $feedIds,
      
      search: $search,
      deepSearch: $deepSearch,
      genAI: $genAI,
      comments: $comments,
      autoplay: $autoplay,
      autoplayMobile: $autoplayMobile,
      autoplayNext: $autoplayNext,
      sound: $sound,
      soundMobile: $soundMobile,
      seo: $seo,
      sitemap: $sitemap,
      download: $download,
      emailShare: $emailShare,
      socialShare: $socialShare,
      shareService: $shareService,
      highlights: $highlights,
      transcriptDownload: $transcriptDownload,
      slides: $slides,
      chapters: $chapters,
      
      appearance: $appearance,
      font: $font,
      fontSize: $fontSize,
      color: $color,
      bg: $bg,
      dockMobile: $dockMobile,
      offsetTop: $offsetTop,
      offsetBottom: $offsetBottom,
      cTitleSize: $cTitleSize,
      cTitleColor: $cTitleColor,
      cDescSize: $cDescSize,
      cDescColor: $cDescColor,
      cVidTitleSize: $cVidTitleSize,
      cVidTitleColor: $cVidTitleColor,
      cInfoColor: $cInfoColor,
      engagement: $engagement,
      layout: $layout,
      popupSize: $popupSize,
      
      sTitleSize: $sTitleSize,
      sTitleColor: $sTitleColor,
      sVidTitleSize: $sVidTitleSize,
      sVidTitleColor: $sVidTitleColor,
      sVidInfoSize: $sVidInfoSize,
      sVidInfoColor: $sVidInfoColor,
      searchPlaceholder: $searchPlaceholder,
      searchLabel: $searchLabel,
      
      tags: $tags,
      tagTypes: $tagTypes,
      fixedTags: $fixedTags,
      excludedTags: $excludedTags,
      tagPages: $tagPages,
      tagCount: $tagCount,
      tagMin: $tagMin,
      tagMax: $tagMax,
      
      language: $language,
      languages: $languages,
      tabOrder: $tabOrder,
      dsTags: $dsTags,
      dsRedirect: $dsRedirect,
      dblClickFlow: $dblClickFlow,
      rtl: $rtl,
      ad: $ad,
      adHubId: $adHubId,
      adWidgetId: $adWidgetId,
      videoPreview: $videoPreview,
      delayPreview: $delayPreview,
      css: $css,
      configuration: $configuration,
      
      myWatch: $myWatch,
      widgetOrigin: $widgetOrigin,
      js: $js,
      backMobile: $backMobile,
      genAICount: $genAICount,
    ) {
      id
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(createWatchAction.type),
    switchMap(() => {
      const hub = watchSelectors.hubSelector(state$.value);
      const source = watchSelectors.sourceSelector(state$.value);
      const domain = watchSelectors.domainSelector(state$.value);
      const userPermissions = getUserPermissionsSelector(state$.value);

      const variables = {
        publisherId: hub.value,
        title: watchSelectors.titleSelector(state$.value),
        description: watchSelectors.descriptionSelector(state$.value),
        status: watchSelectors.statusSelector(state$.value),
        environment: watchSelectors.environmentSelector(state$.value),
        feedIds: source.map((item) => item.value),

        search: watchSelectors.searchSelector(state$.value),
        deepSearch: watchSelectors.deepSearchSelector(state$.value),
        genAI: watchSelectors.genAISelector(state$.value),
        comments: watchSelectors.commentsSelector(state$.value),
        autoplay: watchSelectors.autoplaySelector(state$.value),
        autoplayMobile: watchSelectors.autoplayMobileSelector(state$.value),
        autoplayNext: watchSelectors.autoplayNextSelector(state$.value),
        sound: watchSelectors.soundSelector(state$.value),
        soundMobile: watchSelectors.soundMobileSelector(state$.value),
        seo: watchSelectors.seoSelector(state$.value),
        sitemap: watchSelectors.sitemapSelector(state$.value),
        download: watchSelectors.downloadSelector(state$.value),
        emailShare: watchSelectors.emailShareSelector(state$.value),
        socialShare: watchSelectors.socialShareSelector(state$.value),
        shareService: watchSelectors.shareServiceSelector(state$.value),
        highlights: watchSelectors.highlightsSelector(state$.value),
        transcriptDownload: watchSelectors.transcriptDownloadSelector(state$.value),
        slides: watchSelectors.slidesSelector(state$.value),
        chapters: watchSelectors.chaptersSelector(state$.value),

        appearance: watchSelectors.appearanceSelector(state$.value),
        font: watchSelectors.fontSelector(state$.value),
        fontSize: watchSelectors.fontSizeSelector(state$.value),
        color: watchSelectors.colorSelector(state$.value),
        bg: watchSelectors.bgSelector(state$.value),
        dockMobile: watchSelectors.dockMobileSelector(state$.value),
        offsetTop: watchSelectors.offsetTopSelector(state$.value),
        offsetBottom: watchSelectors.offsetBottomSelector(state$.value),
        cTitleSize: watchSelectors.cTitleSizeSelector(state$.value),
        cTitleColor: watchSelectors.cTitleColorSelector(state$.value),
        cDescSize: watchSelectors.cDescSizeSelector(state$.value),
        cDescColor: watchSelectors.cDescColorSelector(state$.value),
        cVidTitleSize: watchSelectors.cVidTitleSizeSelector(state$.value),
        cVidTitleColor: watchSelectors.cVidTitleColorSelector(state$.value),
        cInfoColor: watchSelectors.cInfoColorSelector(state$.value),
        engagement: watchSelectors.engagementSelector(state$.value),
        layout: watchSelectors.layoutSelector(state$.value),
        popupSize: watchSelectors.popupSizeSelector(state$.value),

        sTitleSize: watchSelectors.sTitleSizeSelector(state$.value),
        sTitleColor: watchSelectors.sTitleColorSelector(state$.value),
        sVidTitleSize: watchSelectors.sVidTitleSizeSelector(state$.value),
        sVidTitleColor: watchSelectors.sVidTitleColorSelector(state$.value),
        sVidInfoSize: watchSelectors.sVidInfoSizeSelector(state$.value),
        sVidInfoColor: watchSelectors.sVidInfoColorSelector(state$.value),
        searchPlaceholder: watchSelectors.searchPlaceholderSelector(state$.value),
        searchLabel: watchSelectors.searchLabelSelector(state$.value),

        tags: watchSelectors.tagsSelector(state$.value),
        tagTypes: watchSelectors.tagTypesSelector(state$.value),
        fixedTags: watchSelectors.fixedTagsSelector(state$.value),
        excludedTags: watchSelectors.excludedTagsSelector(state$.value),
        tagPages: watchSelectors.tagPagesSelector(state$.value),
        tagCount: watchSelectors.tagCountSelector(state$.value),
        tagMin: watchSelectors.tagMinSelector(state$.value),
        tagMax: watchSelectors.tagMaxSelector(state$.value),

        language: watchSelectors.languageSelector(state$.value),
        languages: watchSelectors.languagesSelector(state$.value),
        tabOrder: watchSelectors.tabOrderSelector(state$.value),
        dsTags: watchSelectors.dsTagsSelector(state$.value),
        dsRedirect: watchSelectors.dsRedirectSelector(state$.value),
        dblClickFlow: watchSelectors.dblClickFlowSelector(state$.value),
        rtl: watchSelectors.rtlSelector(state$.value),
        ad: watchSelectors.adSelector(state$.value),
        adHubId: watchSelectors.adHubIdSelector(state$.value),
        adWidgetId: watchSelectors.adWidgetIdSelector(state$.value),
        videoPreview: watchSelectors.videoPreviewSelector(state$.value),
        delayPreview: watchSelectors.delayPreviewSelector(state$.value),
        css: watchSelectors.cssSelector(state$.value),
        configuration: watchSelectors.configurationSelector(state$.value),

        myWatch: watchSelectors.myWatchSelector(state$.value),
      };

      if (domain?.value) {
        variables.domainId = domain.value;
      }

      if (hasPermission(WATCH_CONFIGURATION_CUSTOM_SETTING, userPermissions)) {
        variables.widgetOrigin = watchSelectors.widgetOriginSelector(state$.value);
        variables.js = watchSelectors.jsSelector(state$.value);
        variables.backMobile = watchSelectors.backMobileSelector(state$.value);
        variables.genAICount = watchSelectors.genAICountSelector(state$.value);
      }

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

          if (!errors.length) {
            actions.push(of(clearAction()), of(getWatchesAction()), of(removeQueriesAction([QUERY_PARAM_WATCH_ID])));
          }

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

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