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

import {
  DEMAND_TAG_KEY_VALUE_TARGETING_STATUS,
  DEMAND_TAG_KEY_VALUE_TARGETING_TYPE,
  DEMAND_TAG_PAGE_DEVICE_LIST,
  DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE,
  DEMAND_TAG_TARGETING_VIEWABILITY_TYPE,
  DEMAND_TAG_VIEWABILITY_TARGETING,
} from '../../constants';

import * as selectors from '../selectors';
import { getTargetingTabAction, setTargetingTabAction } from '../slices';

const getIncludeExcludeFromArray = (options, listInclude, listExclude) => {
  const includeExcludeList = [].concat(listInclude || [], listExclude || []);
  if (!includeExcludeList.length) {
    return [];
  }

  return includeExcludeList.map((item) => {
    let label = item[0].toUpperCase() + item.toLowerCase().substring(1);
    if (options && options.length) {
      const found = options.find((option) => option.value === item);
      if (found) {
        // eslint-disable-next-line prefer-destructuring
        label = found.label;
      }
    }
    return {
      label,
      value: item,
      include: listInclude ? listInclude.includes(item) : false,
    };
  });
};

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

      const info = selectors.infoSelector(state);
      const targeting = selectors.targetingSelector(state);

      if (info) {
        setTargeting.browsers = getIncludeExcludeFromArray(null, info.include?.browsers, info.exclude?.browsers);

        setTargeting.os = getIncludeExcludeFromArray(null, info.include?.os, info.exclude?.os);

        setTargeting.countries = getIncludeExcludeFromArray(
          targeting?.countriesList,
          info.include?.geo,
          info.exclude?.geo,
        );

        setTargeting.devices = getIncludeExcludeFromArray(
          DEMAND_TAG_PAGE_DEVICE_LIST,
          info.include?.devices,
          info.exclude?.devices,
        );

        setTargeting.playerSize = {
          [DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.xs]:
            info.include?.playerSizes?.includes(DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.xs) ?? false,
          [DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.s]:
            info.include?.playerSizes?.includes(DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.s) ?? false,
          [DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.m]:
            info.include?.playerSizes?.includes(DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.m) ?? false,
          [DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.l]:
            info.include?.playerSizes?.includes(DEMAND_TAG_TARGETING_PLAYER_SIZE_TYPE.l) ?? false,
        };

        setTargeting.viewability = {
          [DEMAND_TAG_TARGETING_VIEWABILITY_TYPE.inView]:
            info.include?.viewability?.includes(DEMAND_TAG_TARGETING_VIEWABILITY_TYPE.inView) ?? false,
          [DEMAND_TAG_TARGETING_VIEWABILITY_TYPE.nonInView]:
            info.include?.viewability?.includes(DEMAND_TAG_TARGETING_VIEWABILITY_TYPE.nonInView) ?? false,
        };

        if (info.viewabilityThreshold) {
          setTargeting.viewabilityTargeting = DEMAND_TAG_VIEWABILITY_TARGETING.enabled;
          setTargeting.viewabilityThreshold = Math.round(info.viewabilityThreshold * 100 * 100) / 100;
        }

        if (info.tier) {
          setTargeting.tier = info.tier;
        }

        if (info.kvTargeting?.length) {
          setTargeting.kvTargetingStatus = DEMAND_TAG_KEY_VALUE_TARGETING_STATUS.enabled;
          setTargeting.kvTargeting = info.kvTargeting.map((item) => ({
            keyName: { label: item.keyName, value: item.key },
            state: item.state,
            type: item.type,
            values: item.type === DEMAND_TAG_KEY_VALUE_TARGETING_TYPE.value ? item.values : [],
            valueLists:
              item.type === DEMAND_TAG_KEY_VALUE_TARGETING_TYPE.list && item.values?.length && item.listNames?.length
                ? item.values.map((value, index) => ({ label: item.listNames[index], value }))
                : [],
          }));
        }
      }

      return concat(of(setTargetingTabAction(setTargeting)));
    }),
  );
