import dayjs from 'dayjs';

import { stringToTimestamp } from '../helpers/timestamp';
import * as selectors from '@/modules/xRay/lineItems/Editor/redux/selectors';

function prepareData(state) {
  // general tab
  const name = selectors.nameSelector(state);
  const status = selectors.statusSelector(state);
  const priority = selectors.prioritySelector(state);
  const xrayCreative1 = selectors.xrayCreative1Selector(state);
  const xrayCreative2 = selectors.xrayCreative2Selector(state);
  const xrayCreative3 = selectors.xrayCreative3Selector(state);
  // delivery tab
  const startTime = selectors.startTimeSelector(state);
  const endTime = selectors.endTimeSelector(state);
  const timezone = selectors.timezoneSelector(state);
  const rate = +selectors.rateSelector(state);
  const impressionsBudget = +selectors.impressionsBudgetSelector(state) || null;
  const spendBudget = +selectors.spendBudgetSelector(state) || null;
  // targeting tab
  const watch = selectors.watchSelectors(state);
  const watchChannel = selectors.watchChannelSelectors(state);
  const player = selectors.playerSelectors(state);
  const domains = selectors.domainsSelectors(state);
  const devices = selectors.devicesSelectors(state);
  const geography = selectors.geographySelectors(state);
  const inview = selectors.inviewSelectors(state);
  const notInview = selectors.notInviewSelectors(state);
  const playerSizes = selectors.playerSizesSelectors(state);
  const video = selectors.videoSelector(state);
  const videoFromTimestamp = stringToTimestamp(selectors.videoFromTimestampSelector(state));
  const videoToTimestamp = stringToTimestamp(selectors.videoToTimestampSelector(state));
  const iabCategories = selectors.iabCategoriesSelector(state);
  const people = selectors.peopleSelector(state);
  const brands = selectors.brandsSelector(state);
  const keywords = selectors.keywordsSelector(state);
  const labels = selectors.labelsSelector(state);
  const brandSafety = selectors.brandSafetySelector(state);

  const toIncludeExclude = (list, valueKey) => {
    const initial = { include: [], exclude: [] };
    if (!list?.length) {
      return initial;
    }

    return list.reduce((acc, o) => {
      acc[o.include ? 'include' : 'exclude'].push(o[valueKey]);
      return acc;
    }, initial);
  };

  const toIncludeExcludeTaxonomy = (list) => {
    const initial = { include: [], exclude: [] };
    if (!list?.length) {
      return initial;
    }

    return list.reduce((acc, o) => {
      const entity = {
        name: o.label,
        taxonomyId: o.taxonomyId,
      };
      acc[o.include ? 'include' : 'exclude'].push(entity);
      return acc;
    }, initial);
  };

  const toIncludeExcludeTaxonomyLabels = (list) => {
    const initial = { include: [], exclude: [] };
    if (!list?.length) {
      return initial;
    }

    return list.reduce((acc, o) => {
      const entity = {
        name: o.name || o.label, // o.label preserved to avoid crashing old saved x-ray items
        value: o.label,
        color: o.color,
        taxonomyId: o.taxonomyId,
      };

      acc[o.include ? 'include' : 'exclude'].push(entity);
      return acc;
    }, initial);
  };

  const body = {
    name,
    status,
    priority,
    xrayCreatives: [xrayCreative1?.id, xrayCreative2?.id, xrayCreative3?.id].filter(Boolean),
    startTime: startTime ? dayjs(startTime).valueOf() : startTime,
    endTime: endTime ? dayjs(endTime).valueOf() : endTime,
    timezoneId: timezone?.id,
    rate,
    impressionsBudget,
    spendBudget,
    watchId: watch?.id,
    watchChannelId: watchChannel?.id,
    playerId: player?.id,
    videoName: video?.name,
    videoUid: video?.id,
    videoFromTimestamp,
    videoToTimestamp,
    targeting: {
      domains: toIncludeExclude(domains, 'label'),
      devices,
      geography: toIncludeExclude(geography, 'value'),
      inview,
      notInview,
      iabCategories: toIncludeExclude(iabCategories, 'id'),
      people: toIncludeExcludeTaxonomy(people),
      brands: toIncludeExcludeTaxonomy(brands),
      keywords: toIncludeExcludeTaxonomy(keywords),
      labels: toIncludeExcludeTaxonomyLabels(labels),
      brandSafety: toIncludeExclude(brandSafety, 'value'),
      playerSizes,
    },
  };

  return body;
}

export function updateBody(state) {
  return prepareData(state);
}

export function createBody(state) {
  const hub = selectors.hubSelector(state);
  const xrayCampaign = selectors.xrayCampaignSelector(state);
  const data = prepareData(state);

  return {
    publisherId: hub?.id,
    xrayCampaignId: xrayCampaign?.id,
    ...data,
  };
}
