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

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

const queryGQL = `
  query saveConfiguration(
  $awsRecognitionModels: [inputModelDictionaryObject],
  $clarifaiModels: [inputModelDictionaryObject],
  $googleModels: [inputModelDictionaryObject],
  $weavoModels: [inputModelDictionaryObject],
  $dictionaryBrandSafetyCategories: [String],
  $dictionaryIabClassificationCategories: [String],
  $dictionaryBrandSafetySpeech: inputDictionaryBrandSafetyObjectType,
  $dictionaryBrandSafetyText: inputDictionaryBrandSafetyObjectType,
  $dictionaryBlacklistFile: inputFileDictionaryObjectType,
  $dictionaryMapFile: inputFileDictionaryObjectType,
  $dictionaryCategorizationFile: inputFileDictionaryObjectType,
  $dictionaryFilterFile: inputFileDictionaryObjectType,
  $dictionaryBrandSafetyFile: inputFileDictionaryObjectType,
  $htmlParsingConfigFile: inputFileDictionaryObjectType,
  $classificationIabWeightsFile: inputFileDictionaryObjectType,
  $classificationIabCelebritiesMapFile: inputFileDictionaryObjectType,
  $classificationIabMapFile: inputFileDictionaryObjectType,
  $classificationKeywordsLowerbound: Float,
  $classificationKeywordsCount: Float,
  $classificationIabCount: Float,
  $classificationIabLowerbound: Float,
  $enableIabKeywordsMergingAlgorithm: Boolean,
  $enableIabCategorizationAlgorithm: Boolean,
  ) {
    saveConfigurationDictionary(
    awsRecognitionModels: $awsRecognitionModels,
    clarifaiModels: $clarifaiModels,
    googleModels: $googleModels,
    weavoModels: $weavoModels,
    dictionaryBrandSafetyCategories: $dictionaryBrandSafetyCategories,
    dictionaryIabClassificationCategories: $dictionaryIabClassificationCategories,
    dictionaryBrandSafetySpeech: $dictionaryBrandSafetySpeech,
    dictionaryBrandSafetyText: $dictionaryBrandSafetyText,
    dictionaryBlacklistFile: $dictionaryBlacklistFile,
    dictionaryMapFile: $dictionaryMapFile,
    dictionaryCategorizationFile: $dictionaryCategorizationFile,
    dictionaryFilterFile: $dictionaryFilterFile,
    dictionaryBrandSafetyFile: $dictionaryBrandSafetyFile,
    htmlParsingConfigFile: $htmlParsingConfigFile,
    classificationIabWeightsFile: $classificationIabWeightsFile,
    classificationIabCelebritiesMapFile: $classificationIabCelebritiesMapFile,
    classificationIabMapFile: $classificationIabMapFile,
    classificationKeywordsLowerbound: $classificationKeywordsLowerbound,
    classificationKeywordsCount: $classificationKeywordsCount,
    classificationIabCount: $classificationIabCount,
    classificationIabLowerbound: $classificationIabLowerbound,
    enableIabKeywordsMergingAlgorithm: $enableIabKeywordsMergingAlgorithm,
    enableIabCategorizationAlgorithm: $enableIabCategorizationAlgorithm
    ) {
       awsRecognitionModels {
          model
          category
          lowerBound
          maxResults
       }
       clarifaiModels {
          model
          category
          lowerBound
          maxResults
       }
       googleModels {
          model
          category
          lowerBound
          maxResults
       }
       weavoModels {
          model
          category
          lowerBound
          maxResults
       }
       dictionaryBrandSafetyCategories
       dictionaryIabClassificationCategories
       notifications {
          type
          state
          email {
            title
            message
            replyTo {
              address
              name
            }
          }
       }
       dictionaryBrandSafetySpeech {
          grouped {
            label
            value {
              bucket
              key
              url
            }
          }
       }
       dictionaryBrandSafetyText {
          grouped {
            label
            value {
              bucket
              key
              url
            }
          }
       }
       dictionaryBlacklistFile {
            bucket
            key
            url
       }
       dictionaryMapFile {
            bucket
            key
            url
       }
       dictionaryCategorizationFile {
            bucket
            key
            url
       }
       dictionaryFilterFile {
            bucket
            key
            url
       }
       dictionaryBrandSafetyFile {
            bucket
            key
            url
       }
       htmlParsingConfigFile {
            bucket
            key
            url
       }
       classificationIabWeightsFile {
            bucket
            key
            url
       }
       classificationIabCelebritiesMapFile {
          bucket
          key
          url
       }
       classificationIabMapFile {
          bucket
          key
          url
       }
       classificationKeywordsLowerbound
       classificationKeywordsCount
       classificationIabCount
       classificationIabLowerbound
       enableIabKeywordsMergingAlgorithm
       enableIabCategorizationAlgorithm
    }
  }
`;

const allAnalyticsModels = ['awsRecognitionModels', 'clarifaiModels', 'googleModels', 'weavoModels'];

const allFilesProps = [
  'dictionaryBlacklistFile',
  'dictionaryMapFile',
  'dictionaryCategorizationFile',
  'dictionaryFilterFile',
  'dictionaryBrandSafetyFile',
  'classificationIabWeightsFile',
  'classificationIabCelebritiesMapFile',
  'classificationIabMapFile',
];

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

      const propsToRequest = payload.reduce((acc, rawKey) => {
        const key = `${rawKey}Selector`;

        // eslint-disable-next-line import/namespace
        let value = selectors[key](state);

        if (rawKey === 'dictionaryBrandSafetyText' || rawKey === 'dictionaryBrandSafetySpeech') {
          value = {
            // eslint-disable-next-line import/namespace
            grouped: selectors[key](state).map((item) => ({
              label: item.label,
              value: {
                bucket: item.value.bucket,
                key: item.value.key,
              },
            })),
          };
        } else if (allAnalyticsModels.find((prop) => prop === rawKey)) {
          // eslint-disable-next-line import/namespace
          value = selectors[key](state).formList.map((item) => ({
            model: item.model,
            category: item.category,
            lowerBound: item.lowerBound,
            maxResults: item.maxResults,
          }));
        } else if (allFilesProps.find((prop) => prop === rawKey)) {
          value = {
            // eslint-disable-next-line import/namespace
            bucket: selectors[key](state).bucket,
            // eslint-disable-next-line import/namespace
            key: selectors[key](state).key,
          };
        }
        return { ...acc, [rawKey]: value };
      }, {});

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

          if (!errors.length) {
            actions.push(
              of(
                updateConfigurationByPropAction({
                  isLoading: false,
                }),
              ),
            );
          }

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

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