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

import { PCN_GET_MARKETPLACE_DASHBOARD } from '@/modules/@common/acl/constants';
import { TYPE_SUCCESS } from '@/modules/@common/notify/constants';

import {
  createFeesListInput,
  createIncludeExcludeInput,
  getIncludeOrExclude,
} from '../../helpers/createDemandTagRequestBody';
import * as selectors from '../selectors';
import { getInfoAction, setActiveTabIndexAction, setFieldAction, updateAdvertiserAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';
import { showNotificationAction } from '@/modules/layout/redux/slices';
import { uploadFileAndGetDownloadUrl$ } from '@/modules/marketplace/common/helpers/uploadToS3';

// const query = `
//   mutation UpdateAdvertiser(
//     $id: String,
//     $include: MarketplaceTargetingInputType,
//     $exclude: MarketplaceTargetingInputType,
//     $revShare: MarketplacePricingInputType,
//     $tier: Int
//   ) {
//     updateAdvertiser(
//       id: $id,
//       include: $include,
//       exclude: $exclude,
//       revShare: $revShare,
//       tier: $tier
//     ) {
//       id
//       name
//     }
//   }
// `;

const query = `
  mutation UpdateSelfServeAdvertiser(
    $id: String,
    $name: String,
    $include: MarketplaceTargetingInputType,
    $exclude: MarketplaceTargetingInputType,
    $revShare: MarketplacePricingInputType,
    $tier: Int,
    $profitability: Boolean,
    $frequencyCapAdjustment: Boolean,
    $frequencyCapAdjustmentPerSupply: Boolean,
    $pbsEnabled: Boolean,
    $frequencyCapAdjustmentThreshold: Float,
    $logo: String,
  ) {
    updateSelfServeAdvertiser(
      id: $id,
      name: $name,
      include: $include,
      exclude: $exclude,
      revShare: $revShare,
      tier: $tier,
      profitability: $profitability,
      frequencyCapAdjustment: $frequencyCapAdjustment,
      frequencyCapAdjustmentPerSupply: $frequencyCapAdjustmentPerSupply,
      pbsEnabled: $pbsEnabled,
      frequencyCapAdjustmentThreshold: $frequencyCapAdjustmentThreshold,
      logo: $logo,
    ) {
      id
      name
    }
  }
`;

const createIncludeExcludeGeoObject = (countriesList, isInclude = true) =>
  createIncludeExcludeInput({
    geo: {
      key: 'geo',
      value: getIncludeOrExclude(isInclude, countriesList),
    },
  });

export default (action$, state$) =>
  action$.pipe(
    ofType(updateAdvertiserAction.type),
    filter(() => {
      const state = state$.value;

      const info = selectors.infoSelector(state);
      return info?.id;
    }),
    switchMap(({ payload }) => {
      const state = state$.value;

      const { id } = selectors.infoSelector(state);
      const advertiserSettings = selectors.advertiserSettingsSelector(state);
      const userPermissions = getUserPermissionsSelector(state);

      const isAdminMP = hasPermission(PCN_GET_MARKETPLACE_DASHBOARD, userPermissions);

      const {
        name,
        countries,
        tier,
        pbsEnabled,
        profitability,
        frequencyCapAdjustment,
        frequencyCapAdjustmentPerSupply,
        frequencyCapAdjustmentThreshold,
        logo,
        logoFile,
      } = advertiserSettings;

      const updateAdvertiser$ = (logoUrl) =>
        gqlRequest({
          query,
          variables: {
            id,
            name,
            pbsEnabled,
            frequencyCapAdjustment,
            logo: logoUrl ?? logo,
            include: createIncludeExcludeGeoObject(countries, true),
            exclude: createIncludeExcludeGeoObject(countries, false),
            ...(isAdminMP && { tier, profitability }),
            ...(payload?.revShare && {
              revShare: createFeesListInput([payload.revShare])[0],
            }),
            ...(frequencyCapAdjustment && { frequencyCapAdjustmentThreshold, frequencyCapAdjustmentPerSupply }),
          },
        }).pipe(
          switchMap(({ errors }) => {
            let actions = [];
            if (!errors.length) {
              actions = [
                of(getInfoAction(id)),
                of(showNotificationAction({ type: TYPE_SUCCESS, message: 'Advertiser updated' })),
                of(setActiveTabIndexAction(0)),
              ];
            }
            return concat(...actions);
          }),
        );

      const stream$ = !logoFile
        ? updateAdvertiser$(null)
        : uploadFileAndGetDownloadUrl$({ file: logoFile }).pipe(
            switchMap((downloadUrl) => updateAdvertiser$(downloadUrl)),
          );

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