import dayjs from 'dayjs';

import { GET_LIST } from '@/graphql/services/analyticsRevenueOverview/constants';
import { SORT_ASC } from '@/modules/@common/constants/sort';
import { CALENDAR_FILTER_ADAPTER, CALENDAR_FILTER_CUSTOM } from '@/modules/analytics/monetization/constants';

import { DataRecordsType } from '../../types';
import { PAYLOAD_NAME } from '@/graphql/services/analyticsRevenueOverview/types/payload/list';

import {
  adFormatSelector,
  countriesSelector,
  customDateFromSelector,
  customDateToSelector,
  demandSourcesSelector,
  devicesSelector,
  domainsSelector,
  pageSelector,
  pageSizeSelector,
  periodSelector,
  playersSelector,
  sortBySelector,
  sortOrderSelector,
} from '../selectors';
import { getDataAction, setTableAction } from '../slices';
import createEpicGetData from '@/modules/@common/Table/redux/epics';
import { getUserTimezoneSelector } from '@/modules/@common/user/redux/selectors';

import { PayloadType } from '@/graphql/services/analyticsRevenueOverview/resolvers/getListResolver';
import type { RootState } from '@/modules/@common/store/store';

type DataType = Record<
  string,
  {
    data: DataRecordsType;
    total: number;
  }
>;

const gqlQuery = `
  query ${GET_LIST}($payload: ${PAYLOAD_NAME}) {
    ${GET_LIST}(payload: $payload) {
      total
      data {
        customId
        platformFee
        netRevenue
        playerLoads
        rpm
        anyclipVideoAdImpressions
        publisherVideoAdImpressions
        anyclipDisplayAdImpressions
        publisherDisplayAdImpressions
        videoAdImpressions
        displayAdImpressions
        anyclipVideoRevenue
        publisherVideoRevenue
        anyclipDisplayRevenue
        publisherDisplayRevenue
        videoRevenue
        displayRevenue
        time      
      }
    }
  }
`;

export default createEpicGetData({
  gqlQuery,
  triggerActionType: getDataAction.type,
  processBodyRequest: (state: RootState) => {
    const timezone = getUserTimezoneSelector(state);
    const period = periodSelector(state);
    const customDateFrom = customDateFromSelector(state);
    const customDateTo = customDateToSelector(state);
    const demandSources = demandSourcesSelector(state);
    const players = playersSelector(state);
    const countries = countriesSelector(state);
    const domains = domainsSelector(state);
    const devices = devicesSelector(state);

    const filters = CALENDAR_FILTER_ADAPTER[period as keyof typeof CALENDAR_FILTER_ADAPTER];

    const range =
      period === CALENDAR_FILTER_CUSTOM
        ? {
            stringFrom: customDateFrom,
            stringTo: customDateTo,
          }
        : {
            stringFrom: filters.range.stringFrom,
            stringTo: filters.range.stringTo,
          };
    const interval =
      period === CALENDAR_FILTER_CUSTOM
        ? {
            unit: dayjs(customDateTo).diff(customDateFrom, 'days') > 1 ? 'DAYS' : 'HOURS',
            value: 1,
          }
        : filters.interval;

    const payload: PayloadType = {
      timezone,
      page: pageSelector(state) - 1,
      pageSize: pageSizeSelector(state),
      sortBy: sortBySelector(state),
      sortOrder: sortOrderSelector(state) ?? SORT_ASC,
      adFormat: adFormatSelector(state) || undefined,
      demandSources: demandSources.length ? demandSources.map(({ value }) => value) : undefined,
      widgetIds: players.length ? players.map(({ value }) => value) : undefined,
      countries: countries.length ? countries.map(({ value }) => value) : undefined,
      domains: domains.length ? domains.map(({ value }) => value) : undefined,
      devices: devices.length ? devices.map(({ value }) => value) : undefined,
      range: {
        ...range,
        timezone,
      },
      interval,
    };

    return {
      payload,
    };
  },
  processResponse: ({ data }: { data: DataType }) => {
    const res = data[GET_LIST];

    return {
      records: res.data,
      recordsTotal: res.total,
      allRecordsCount: res.total,
    };
  },
  setTableAction,
});
