import { put, takeEvery, all, call } from 'redux-saga/effects';

import gql from 'graphql-tag';

// Action type
import { StoreAction } from 'store/utils/actions';

import { genericApolloSaga } from 'store/utils/apollo';

import { config, zeus } from 'config/general';

import { deepOmit } from 'store/utils/helper';
import actions from './actions';
import selectors from './selectors';
import * as models from './models';

const { Zeus, $ } = zeus;

export const treatmentOut = values => {
  const output = {
    ...values,
  };

  return deepOmit(output, ['_id', '__typename', 'createdAt', 'updatedAt']);
};

function* list(action: StoreAction) {
  action.payload = action.payload || {};
  const payload = action.payload;

  const search = payload.data || {};

  if (payload.limit) {
    search.pagination = {
      limit: payload.limit,
      skip: ((payload.page || 1) - 1) * payload.limit,
    };
  }

  const zeusQuery = Zeus.query({
    bookingsGetMany: [search, models.bookingListModel],
    bookingsGetCount: [search],
  });

  payload.query = gql`
    ${zeusQuery}
  `;

  yield call(genericApolloSaga('', actions.list.result.action), action);
}

function* detail(action) {
  action.payload = action.payload || {};
  const payload = action.payload;

  const search = { id: payload.id };

  const zeusQuery = Zeus.query({
    bookingsGetOne: [search, models.bookingModel],
  });

  payload.query = gql`
    ${zeusQuery}
  `;

  yield call(genericApolloSaga('bookingsGetOne', actions.detail.result.action), action);
}

/**
 * MUTATIONS
 */

function* update(action: StoreAction) {
  action.payload = action.payload || {};
  const payload = action.payload;

  const zeusMutation = Zeus.mutation({
    bookingsEditOne: [
      {
        id: payload.id,
        input: $`input`,
      },
      models.bookingModel,
    ],
  });

  payload.mutation = gql`
    ${zeusMutation}
  `;

  payload.data = {
    input: payload.data && treatmentOut(payload.data.input),
  };

  yield call(genericApolloSaga('bookingsEditOne', actions.update.result.action), action);
}

function* deletebooking(action: StoreAction) {
  action.payload = action.payload || {};
  const payload = action.payload;

  const zeusMutation = Zeus.mutation({
    bookingsDeleteOne: [
      {
        id: payload.id,
      },
      models.bookingModel,
    ],
  });

  payload.mutation = gql`
    ${zeusMutation}
  `;

  yield call(genericApolloSaga('bookingsDeleteOne', actions.delete.result.action), action);
}

function* bookingWatchers() {
  yield all([
    takeEvery(actions.list.request.constant, list),
    takeEvery(actions.detail.request.constant, detail),
    takeEvery(actions.update.request.constant, update),
    takeEvery(actions.delete.request.constant, deletebooking),
  ]);
}

export default function* saga() {
  yield call(bookingWatchers);
}
