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

import { apiCall } from 'store/utils/sagas';
import app from 'store/app';
import content from 'store/content';

import actions from './actions';
import selectors from './selectors';

// login paragraph
function* paragraphLogin(action): void {
  const request = yield call(apiCall, {
    api: api.paragraph.login,
    data: action.payload,
    sessionLogin: true,
    noFeedback: true,
  });

  if (request && (request.code === 'success' || request.code === 'already_logged')) {
    yield put(actions.me.result.action(request.element));
  } else if (request) {
    yield put(
      app.actions.dialog.error.action({
        data: request.message,
      }),
    );
  }
}

// logout paragraph
function* paragraphLogout(action): void {
  const request = yield call(apiCall, {
    api: api.paragraph.logout,
    data: action.payload,
    sessionLogin: true,
    noFeedback: true,
  });

  if (request && !request.error) {
    yield put(actions.logout.result.action());
  }
}

// get me
function* paragraphMe(action): void {
  const request = yield call(apiCall, {
    api: api.paragraph.me,
    sessionLogin: true,
    noLoading: true,
    noFeedback: true,
  });

  if (request && request.code === 'success') {
    yield put(actions.me.result.action(request.element));
  } else {
    yield put(actions.me.result.action());
  }
}

function* paragraphList(action): void {
  const request = yield call(apiCall, {
    api: api.paragraph.list,
    data: {
      limit: 1000,
    },
    callback: action.payload && action.payload.callback,
    noLoading: true,
    sessionLogin: true,
    noFeedback: true,
  });

  if (request && request.elements) {
    yield put(actions.list.result.action(request.elements));
  } else {
    // retry
    yield put(actions.list.request.action());
    // yield put(actions.list.result.action());
    // yield put(
    //   app.actions.dialog.error.action({
    //     data: 'Error retrieving content',
    //   }),
    // );
  }
}

function* paragraphUpdate(action): void {
  const payload = action.payload;
  const data = payload.data;

  if (typeof data.content !== 'string') data.content = JSON.stringify(data.content);

  const request = yield call(apiCall, {
    api: api.paragraph.update,
    id: data.id,
    data,
    sessionLogin: true,
    noFeedback: true,
  });

  if (request && request.element) {
    if (typeof payload.callback === 'function') payload.callback();
    yield put(actions.update.result.action(request.element));
    yield put(
      app.actions.dialog.success.action({
        data: 'admin.messages.pageUpdateSuccess',
      }),
    );

    const paragraph = yield select(selectors.getParagraphData);
    if (paragraph) {
      yield put(content.actions.content.result.action(paragraph, 'fulfilled'));
    }
  } else {
    yield put(
      app.actions.dialog.error.action({
        data: 'Error updating page',
      }),
    );
  }
}

function* paragraphAdd(action): void {
  const payload = action.payload;

  const request = yield call(apiCall, {
    api: api.paragraph.add,
    data: payload.data,
    sessionLogin: true,
    noFeedback: true,
  });
  if (request && request.element) {
    yield put(actions.add.result.action(request.element));

    if (typeof payload.callback === 'function') payload.callback(request.element);
    yield put(
      app.actions.dialog.success.action({
        data: 'Page added with success',
      }),
    );
  } else {
    yield put(
      app.actions.dialog.error.action({
        data: 'Error adding a page',
      }),
    );
  }
}

function* paragraphDelete(action): void {
  const payload = action.payload;

  const request = yield call(apiCall, {
    api: api.paragraph.delete,
    id: payload.id,
    sessionLogin: true,
    noFeedback: true,
  });

  if (request && request.element) {
    if (typeof payload.callback === 'function') payload.callback(request.element);
    yield put(actions.delete.result.action(payload.id));
    yield put(
      app.actions.dialog.success.action({
        data: 'Page deleted with success',
      }),
    );
  } else {
    yield put(
      app.actions.dialog.error.action({
        data: 'Error deleting page',
      }),
    );
  }
}

function* paragraphUpdateContent(action): void {
  const payload = action.payload;
  yield call(apiCall, {
    api: payload.dev ? api.app.updateContentDev : api.app.updateContent,
    success: 'Content updated with success',
  });
}

function* paragraphWatchers(): void {
  yield all([
    yield takeEvery(actions.login.request.constant, paragraphLogin),
    yield takeEvery(actions.logout.request.constant, paragraphLogout),
    yield takeEvery(actions.me.request.constant, paragraphMe),
    yield takeEvery(actions.list.request.constant, paragraphList),
    yield takeEvery(actions.update.request.constant, paragraphUpdate),
    yield takeEvery(actions.add.request.constant, paragraphAdd),
    yield takeEvery(actions.delete.request.constant, paragraphDelete),
    yield takeEvery(actions.updateContent.request.constant, paragraphUpdateContent),
  ]);
}

export default function* saga(): void {
  yield call(paragraphWatchers);
}
