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

import getCurrentAndFuturePrice from '../../helpers/getCurrentAndFuturePrice';
import * as selectors from '../selectors';
import { getDemandTagPricingAction, setPricingTabAction } from '../slices';
import { gqlRequest } from '@/modules/@common/request';
import { definePricingTableKey } from '@/modules/marketplace/account/helpers/createDemandTagPriceRequestBody';

const query = `
  query getDemandTagPricing($id: String!, $from: Int, $size: Int, $type: String!) {
    getDemandTagPricing(id: $id, from: $from, size: $size, type: $type) {
      totalCount
      data {
        id
        type
        value
        startDate
        endDate
        updatedBy
        model
      }
    }
  }
`;

export default (action$, state$) =>
  action$.pipe(
    ofType(getDemandTagPricingAction.type),
    mergeMap(({ payload }) => {
      const state = state$.value;

      const pricing = selectors.pricingSelector(state);
      const pageConfig = selectors.pageConfigSelector(state);

      const tableKey = definePricingTableKey(payload);
      const { page, rowsPerPage, type } = pricing[tableKey];
      const { isDuplicate } = pageConfig;

      const stream$ = gqlRequest({
        query,
        variables: {
          id: pageConfig.id,
          from: page * rowsPerPage,
          size: rowsPerPage,
          type,
        },
      }).pipe(
        switchMap(({ data, errors }) => {
          let actions = [];

          if (!errors.length) {
            const rows = isDuplicate
              ? getCurrentAndFuturePrice(data.getDemandTagPricing.data)
              : data.getDemandTagPricing.data;

            actions = [
              of(
                setPricingTabAction({
                  [tableKey]: {
                    ...pricing[tableKey],
                    totalCount: data.getDemandTagPricing.totalCount,
                    rows,
                  },
                }),
              ),
            ];
          }

          return concat(...actions);
        }),
      );

      return concat(stream$);
    }),
  );
