import {
  PERIOD_DAILY,
  PLAYER_SIZE_LARGE,
  PLAYER_SIZE_MEDIUM,
  PLAYER_SIZE_SMALL,
  PLAYER_SIZE_X_SMALL,
  TARGET_PLACEMENT_TYPE_PLAYER,
  TARGET_PLACEMENT_TYPE_WATCH,
  TRIGGER_API,
  TRIGGER_BEGINNING,
  TRIGGER_END,
  TRIGGER_TIMESTAMP,
} from '@/modules/forms/editor/constants';

import { getFormMetadataCalculation } from '@/modules/forms/editor/helpers/calculationsFromState';
import * as selectors from '@/modules/forms/editor/redux/selectors';

const excludeIncludeFilter = (items, include = true) => items.filter((item) => item.include === include);
const getValue = (item) => item.value;
const getLabel = (item) => ({
  groupBy: item.groupBy,
  labelId: item.labelId,
  color: item.color,
  value: item.value,
  name: item.name,
});
const getCategory = (item) => ({
  id: item.id,
  name: item.name,
});
const getGeographies = (item) => ({
  value: item.value,
  label: item.label,
});
const getTaxonomyValue = (item) => ({
  name: item.label,
  taxonomyId: item.value,
});

export const createRequestBody = (state) => {
  const name = selectors.nameSelector(state);
  const site = selectors.siteSelector(state);
  const status = selectors.statusSelector(state);
  const title = selectors.titleSelector(state);
  const scheduleReport = selectors.scheduleReportSelector(state);
  const enableInstantDelivery = selectors.enableInstantDeliverySelector(state);
  const image = selectors.imageSelector(state);
  const trigger = selectors.triggerSelector(state);
  const medataFormId = selectors.medataFormIdSelector(state);
  const id = selectors.idSelector(state);

  const defaultTriggerBody = {
    triggerTime: '00:00:00',
    activateLimitsPeriod: false,
    frequencyLimitsMaxViewPerUser: 5,
    frequencyLimitsPeriod: PERIOD_DAILY,
    frequencyLimitsDisplayOnlyOnceSubmitted: false,
    frequencyLimitsNotShowWhenOnceDisplayed: false,
  };

  const defaultTargetingBody = {
    watchId: null,
    watchChannelId: null,
    playerId: null,
    playerSizes: [PLAYER_SIZE_X_SMALL, PLAYER_SIZE_SMALL, PLAYER_SIZE_MEDIUM, PLAYER_SIZE_LARGE],
    videoId: null,
    videoName: '',
    includeDomains: [],
    excludeDomains: [],
    includeDevices: [],
    excludeDevices: [],
    includeGeographies: [],
    excludeGeographies: [],
    includeCategory: [],
    excludeCategory: [],
    includePeople: [],
    excludePeople: [],
    includeBrands: [],
    excludeBrands: [],
    includeKeywords: [],
    excludeKeywords: [],
    includeBrandSafety: [],
    excludeBrandSafety: [],
    includeLabels: [],
    excludeLabels: [],
  };

  let body = {
    name,
    publisherId: site.value,
    status,
    title,
    scheduleReportEmail: scheduleReport.email,
    scheduleReportPeriod: scheduleReport.period,
    enableInstantDelivery,
    logo: image,
    metadata: JSON.stringify(getFormMetadataCalculation(state)),

    triggerAction: trigger.triggerAction,
    triggerTime: trigger.triggerTime,
    triggerApiValue: trigger.triggerApiValue,

    activateLimitsPeriod: trigger.activateLimitsPeriod,
    frequencyLimitsDisplayOnlyOnceSubmitted: trigger.frequencyLimitsDisplayOnlyOnceSubmitted,
    frequencyLimitsNotShowWhenOnceDisplayed: trigger.frequencyLimitsNotShowWhenOnceDisplayed,
    frequencyLimitsMaxViewPerUser: trigger.frequencyLimitsMaxViewPerUser,
    frequencyLimitsPeriod: trigger.frequencyLimitsPeriod,

    watchId: trigger.targetPlacementType === TARGET_PLACEMENT_TYPE_WATCH ? trigger.watch?.value : null,
    watchChannelId:
      trigger.targetPlacementType === TARGET_PLACEMENT_TYPE_WATCH ? (trigger.watchChannel?.value ?? null) : null,

    playerId: trigger.targetPlacementType === TARGET_PLACEMENT_TYPE_PLAYER ? trigger.playerName?.value : null,
    playerSizes: trigger.playerSize,

    videoId: trigger.video?.value || null,
    videoName: trigger.video?.label || '',

    includeDomains: excludeIncludeFilter(trigger.domains, true).map(getValue),
    excludeDomains: excludeIncludeFilter(trigger.domains, false).map(getValue),

    includeDevices: excludeIncludeFilter(trigger.devices, true).map(getValue),
    excludeDevices: excludeIncludeFilter(trigger.devices, false).map(getValue),

    includeGeographies: excludeIncludeFilter(trigger.geographies, true).map(getGeographies),
    excludeGeographies: excludeIncludeFilter(trigger.geographies, false).map(getGeographies),

    includeCategory: excludeIncludeFilter(trigger.categories, true).map(getCategory),
    excludeCategory: excludeIncludeFilter(trigger.categories, false).map(getCategory),

    includePeople: excludeIncludeFilter(trigger.peoples, true).map(getTaxonomyValue),
    excludePeople: excludeIncludeFilter(trigger.peoples, false).map(getTaxonomyValue),

    includeBrands: excludeIncludeFilter(trigger.brands, true).map(getTaxonomyValue),
    excludeBrands: excludeIncludeFilter(trigger.brands, false).map(getTaxonomyValue),

    includeKeywords: excludeIncludeFilter(trigger.keywords, true).map(getTaxonomyValue),
    excludeKeywords: excludeIncludeFilter(trigger.keywords, false).map(getTaxonomyValue),

    includeBrandSafety: excludeIncludeFilter(trigger.brandSafeties, true).map(getValue),
    excludeBrandSafety: excludeIncludeFilter(trigger.brandSafeties, false).map(getValue),

    includeLabels: excludeIncludeFilter(trigger.labels, true).map(getLabel),
    excludeLabels: excludeIncludeFilter(trigger.labels, false).map(getLabel),

    medataFormId,
  };

  // for update
  if (id) {
    body.id = id;
  }

  switch (true) {
    case trigger.triggerAction === TRIGGER_API: {
      body = {
        ...body,
        ...defaultTriggerBody,
        ...defaultTargetingBody,
      };
      break;
    }
    case [TRIGGER_BEGINNING, TRIGGER_END].includes(trigger.triggerAction): {
      body = {
        ...body,
        triggerTime: defaultTriggerBody.triggerTime,
        triggerApiValue: '',
      };
      break;
    }
    case trigger.triggerAction === TRIGGER_TIMESTAMP: {
      body = {
        ...body,
        frequencyLimitsNotShowWhenOnceDisplayed: defaultTriggerBody.frequencyLimitsNotShowWhenOnceDisplayed,
        triggerApiValue: '',
      };
      break;
    }
    default: {
      break;
    }
  }

  return body;
};

export default createRequestBody;
