import { all, call, put, takeLatest } from "redux-saga/effects";
import {
  setCategories,
  setCategoriesError,
  setIsCategoriesChecked,
  setIsCategoriesCheckedError,
  setGrantCategories,
  setGrantCategoriesError,
  setAllCategories,
  setAllCategoriesError,
  setCreateCategory,
} from "../actions/categories/categoriesAction";
import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers";
import { JWT_TOKEN } from "../../constants/localStorage";
import { addHeaderToken } from "../../request";
import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper";
import {
  FETCH_ROOT_CATEGORIES_REQ,
  FETCH_IS_CATEGORIES_CHECKED_REQ,
  GRANT_CATEGORY_REQ,
  FETCH_ALL_CATEGORIES_REQ,
  CREATE_CATEGORY_REQ,
} from "../actions/categories/categoriesActionConstants";
import {
  getRootCategories,
  getIsCategoriesChecked,
  grantCategoryRequest,
  getRootCategories2,
  getAllCategories,
  createCategoryRequest,
} from "../../request/categoriesRequest";

export function* getRootCategoriesSaga({ payload }) {
  try {
    const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
    yield call(addHeaderToken, JwtToken);
    let result = null;
    if (payload === undefined) {
      result = yield call(getRootCategories);
    } else {
      result = yield call(getRootCategories2, payload.parentCategoryId);
    }
    yield put(
      setCategories({
        categories: result.data.categories,
        childParentRelations: result.data.childParentRelations,
      })
    );
  } catch (error) {
    const errorMessage = yield call(rejectErrorCodeHelper, error);
    yield put(setCategoriesError(errorMessage));
  }
}

export function* getIsCategoriesCheckedSaga({ payload }) {
  try {
    const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
    yield call(addHeaderToken, JwtToken);
    const result = yield call(getIsCategoriesChecked, payload.userId);
    yield put(setIsCategoriesChecked(result.data));
  } catch (error) {
    const errorMessage = yield call(rejectErrorCodeHelper, error);
    yield put(setIsCategoriesCheckedError(errorMessage));
  }
}

export function* grantCategoriesCheckedSaga({ payload }) {
  try {
    const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
    yield call(addHeaderToken, JwtToken);
    const result = yield call(grantCategoryRequest, payload);
    yield put(setGrantCategories(result.data));
  } catch (error) {
    const errorMessage = yield call(rejectErrorCodeHelper, error);
    yield put(setGrantCategoriesError(errorMessage));
  }
}

export function* getAllCategoriesSaga() {
  try {
    const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
    yield call(addHeaderToken, JwtToken);
    const result = yield call(getAllCategories);
    yield put(setAllCategories(result.data));
  } catch (error) {
    const errorMessage = yield call(rejectErrorCodeHelper, error);
    yield put(setAllCategoriesError(errorMessage));
  }
}

export function* createCategorySaga({ payload }) {
  try {
    const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
    yield call(addHeaderToken, JwtToken);
    yield call(createCategoryRequest, {
      name: payload.name,
      parentId: payload.parentId,
    });
    yield put(setCreateCategory());
    if (payload.onSuccess) yield call(payload.onSuccess);
  } catch (error) {
    const errorMessage = yield call(rejectErrorCodeHelper, error);
    yield put(setGrantCategoriesError(errorMessage));
  }
}

export default function* categoriesSaga() {
  yield all([
    takeLatest(FETCH_ROOT_CATEGORIES_REQ, getRootCategoriesSaga),
    takeLatest(FETCH_IS_CATEGORIES_CHECKED_REQ, getIsCategoriesCheckedSaga),
    takeLatest(GRANT_CATEGORY_REQ, grantCategoriesCheckedSaga),
    takeLatest(FETCH_ALL_CATEGORIES_REQ, getAllCategoriesSaga),
    takeLatest(CREATE_CATEGORY_REQ, createCategorySaga),
  ]);
}
