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 = {
    ressourceType: payload.resourceType,
    pagination: $`pagination`,
    search: $`search`,
  };

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

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

  const paginationData = {
    sort: payload.order,
    limit: !payload.noLimit && parseInt(payload.limit || config.defaultLimit, 10),
    skip: 0,
  };

  payload.noLoading = true;

  payload.data = {
    pagination: paginationData,
    search: payload.search,
  };

  yield call(genericApolloSaga('listsGetMany', 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({
    listsGetOne: [search, models.listModel],
  });

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

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

/**
 * MUTATIONS
 */

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

  const zeusMutation = Zeus.mutation({
    listsAddOne: [
      {
        input: $`input`,
      },
      models.listModel,
    ],
  });

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

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

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

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

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

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

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

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

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

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

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

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

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

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