import {
  take, call, put, cancelled, takeLatest, all,
  fork,
  cancel,
  select,
} from 'redux-saga/effects';
// import { normalize } from 'normalizr';
import * as Api from '../../services/api';
import * as LocalStorage from '../../services/localStorageApi';
import * as types from './constants';
import config from '../../config/app';
//import pathConfig from '../../config/path';
import {
  getTopbarMenuDataValue,
  getLoyaltyTopbarMenuDataValue,
  LOYALTY,
} from "../App/constants";
import { loyaltyTagProps } from "../CreativesContainer/selectors";
// import {makeSelectOrgId} from './selectors';

export function* authorize(user) {
  try {
    const res = yield call(Api.authorize, user);
    yield call(LocalStorage.saveItem, 'token', res.token);
    yield call(LocalStorage.saveItem, 'orgID', res.user.orgID);
    yield call(LocalStorage.saveItem, 'user', res.user);
    // yield call(LocalStorage.saveItem, 'isLoggedIn', true);
    yield put({ type: types.LOGIN_SUCCESS, res });
  } catch (error) {
    yield put({ type: types.LOGIN_FAILURE, error });
  } finally {
    if (yield cancelled()) {
      // reducer will clear out login_progress on logout request
      // So this block is not exactly required
    }
  }
}

export function* switchOrg({orgID}) {
  try {
    LocalStorage.saveItem('orgID', orgID);
    const res = yield call(Api.changeProxyOrg, orgID);
    yield put({ type: types.SWITCH_ORG_SUCCESS, orgID, isSuccess: res.success });
  } catch (error) {
    yield put({ type: types.SWITCH_ORG_FAILURE, error });
  }
}

export function* loginFlow() {
  let condition = true;
  while (condition) {
    const {user} = yield take(types.LOGIN_REQUEST);
    const task = yield fork(authorize, user);
    const action = yield take([types.LOGOUT_REQUEST_V2, types.LOGIN_FAILURE]);
    if (action.type === types.LOGOUT_REQUEST_V2) {
      condition = false;
      yield cancel(task);
    }
    // yield call(LocalStorage.clearItem, 'token');
    // yield call(LocalStorage.clearItem, 'orgID');
    // yield call(LocalStorage.clearItem, 'user');
  }
}

export function* logoutFlow() {
  try {
    const serverLogout = yield call(Api.logout);
    if (serverLogout.success && serverLogout.success === true) {
      const loginUrl = (process.env.NODE_ENV === 'production') ?
        `${config.production.login_url}` : `${config.development.login_url}`;
      yield put({type: types.LOGOUT_SUCCESS_V2});
      yield call(LocalStorage.clearItem, 'token');
      yield call(LocalStorage.clearItem, 'orgID');
      yield call(LocalStorage.clearItem, 'user');
      yield call(LocalStorage.clearItem, 'isLoggedIn');
      window.location.href = `${window.location.origin}${loginUrl}`;
    }
  } catch (error) {
    yield put({ type: types.LOGOUT_FAILURE_V2, error });
  }
}

export function* fetchUserInfo(option) {
  try {
    const result = yield call(Api.getUserData);
    if (result?.isError || result?.status === 401) {
      yield call(LocalStorage.clearItem, 'user');
      yield put({
        type: types.GET_USER_DATA_FAILURE,
        error: result,
        status: result?.status,
      });
    } 

    else {
      const userData = result.user;
      // const orgId = yield select(makeSelectOrgId());
      // yield put({type: types.GET_ORG_DETAILS_REQUEST, orgId});
      const currentOrgDetails = result.currentOrgDetails;
      if (!(currentOrgDetails && currentOrgDetails.basic_details && currentOrgDetails.basic_details.base_language && (currentOrgDetails.basic_details.base_language !== "" || currentOrgDetails.basic_details.base_language === null))) {
        currentOrgDetails.basic_details.base_language = 'en';
      }
      if (!(currentOrgDetails && currentOrgDetails.basic_details && currentOrgDetails.basic_details.supported_languages && currentOrgDetails.basic_details.supported_languages.length > 0)) {
        currentOrgDetails.basic_details.supported_languages = [
          {
            lang_id: 69,
            language: "English",
            iso_code: "en",
          },
        ];
      }
      yield call(LocalStorage.saveItem, 'orgID', result.currentOrgId);
      yield call(LocalStorage.saveItem, 'user', userData);
      yield put({type: types.GET_USER_DATA_SUCCESS, userData, currentOrgId: result.currentOrgId, currentOrgDetails});
      if (option.callback) {
        option.callback(userData, currentOrgDetails);
      }
    }
  } catch (error) {
    yield call(LocalStorage.clearItem, 'user');
    yield put({
      type: types.GET_USER_DATA_FAILURE,
      error,
    });
  }
}

export function* fetchSchemaForEntity(queryParams) {
  try {
    // Get stored loyalty tag props from Redux state
    const loyaltyTagPropsData = yield select(loyaltyTagProps());
    
    // Check if loyalty module is enabled and data exists
    const isLoyaltyModuleEnabled = loyaltyTagPropsData?.isLoyaltyModule;
    
    // If loyalty module is enabled and data exists, we can add specific logic here
    if (isLoyaltyModuleEnabled && loyaltyTagPropsData) {
      queryParams.queryParams.loyaltyTagsParams = loyaltyTagPropsData;
    }
    
    const result = yield call(Api.fetchSchemaForEntity, queryParams);

    // const sidebar = result.response.sidebar;
    const {
      success = false,
      response = {},
      status: {
        code = '',
      } = {},
    } = result || {};
    const {
      metaEntities = [],
    } = response || {};
    const {
      queryParams: {
        type = '',
      } = {},
    } = queryParams || {};
    if (success || metaEntities?.length) {
      yield put({ type: types.GET_SCHEMA_FOR_ENTITY_SUCCESS, data: response, statusCode: code, entityType: type });
    } else {
      yield put({ type: types.GET_SCHEMA_FOR_ENTITY_FAILURE, error: true });
    }
  } catch (error) {
    yield put({ type: types.GET_SCHEMA_FOR_ENTITY_FAILURE, error});
  }
}

export function* getLiquidTags(action) {
  try {
    const askAiraResponse = {askAiraResponse: {}, isError: true};
    const result = yield call(Api.getLiquidTags, action?.data);
    if (result) {
      if (result?.errors?.length > 0) {
        const getAskAiraErrorResponse = yield call(Api.askAiraForLiquid, {
          templateContent: action?.data,
          errorMessage: result?.errors?.[0]?.message,
        });
        if (getAskAiraErrorResponse?.result?.errors?.length) {
          askAiraResponse.askAiraResponse = getAskAiraErrorResponse?.result;
        } else {
          askAiraResponse.askAiraResponse = result;
        }
      } else {
        askAiraResponse.askAiraResponse = result;
        askAiraResponse.isError = false;
      }
      if (action?.callback) {
        yield call(action?.callback, askAiraResponse);
      }
      yield put({ type: types.GET_LIQUID_TAGS_SUCCESS });
    } else {
      yield put({ type: types.GET_LIQUID_TAGS_FAILURE });
    }
  } catch (error) {
    yield put({ type: types.GET_LIQUID_TAGS_FAILURE });
  }
}
const getTopbarData = (parentModule) => {
  switch (parentModule) {
    case LOYALTY:
      return getLoyaltyTopbarMenuDataValue();
    default:
      return getTopbarMenuDataValue();
  }
};

export function* createCentralCommsMetaId(action) {
  try {
    const result = yield call(Api.createCentralCommsMetaId, action?.data);
    if (result?.status?.code === 200) {
      if (action?.callback) {
        yield call(action?.callback, result);
      }
      yield put({ type: types.CREATE_CENTRAL_COMMS_META_ID_SUCCESS, result });
    } else {
      yield put({ type: types.CREATE_CENTRAL_COMMS_META_ID_FAILURE, error: result?.message });
    }
  } catch (error) {
    yield put({ type: types.CREATE_CENTRAL_COMMS_META_ID_FAILURE, error });
  }
}

function* getTopbarMenuData(params) {
  const {parentModule} = params;
  try {
    yield put({
      type: types.GET_TOPBAR_MENU_DATA_SUCCESS,
      data: getTopbarData(parentModule),
    });
  } catch (error) {
    yield put({ type: types.GET_TOPBAR_MENU_DATA_FAILURE, error });
  }
}

export function* getSupportVideosConfig({ callback }) {
  try {
    const response = yield call(Api.getSupportVideosConfig);
    if (response?.success) {
      yield put({
        type: types.GET_SUPPORT_VIDEOS_CONFIG_SUCCESS,
        result: response?.data || {},
      });
    } else {
      yield put({
        type: types.GET_SUPPORT_VIDEOS_CONFIG_FAILURE,
        error: response?.message,
      });
    }
    if (callback) callback(response);
  } catch (error) {
    yield put({ type: types.GET_SUPPORT_VIDEOS_CONFIG_FAILURE, error });
  }
}

export function* watchFetchSchemaForEntity() {
  yield takeLatest(types.GET_SCHEMA_FOR_ENTITY_REQUEST, fetchSchemaForEntity);
}
export function* watchLiquidEntity() {
  yield takeLatest(types.GET_LIQUID_TAGS_REQUEST, getLiquidTags);
}

export function* watchMetaId() {
  yield takeLatest(types.CREATE_CENTRAL_COMMS_META_ID_REQUEST, createCentralCommsMetaId);
}

function* watchForOrgChange() {
  yield takeLatest(types.SWITCH_ORG_REQUEST, switchOrg);
}

function* watchForLogoutFlow() {
  yield takeLatest(types.LOGOUT_REQUEST_V2, logoutFlow);
}

function* watchForFetchUserInfo() {
  yield takeLatest(types.GET_USER_DATA_REQUEST, fetchUserInfo);
}

function* watchGetTopbarMenuData() {
  yield takeLatest(types.GET_TOPBAR_MENU_DATA_REQUEST, getTopbarMenuData);
}

export function* watchForGetVideosConfig() {
  yield takeLatest(
    types.GET_SUPPORT_VIDEOS_CONFIG_REQUEST,
    getSupportVideosConfig,
  );
}

export default [
  loginFlow,
  watchForOrgChange,
  watchForLogoutFlow,
  watchForFetchUserInfo,
  watchFetchSchemaForEntity,
  watchGetTopbarMenuData,
  watchForGetVideosConfig,
  watchLiquidEntity,
  watchMetaId,
];


export function* capSagaForFetchSchemaForEntity() {
  yield all([
    watchFetchSchemaForEntity(),
  ]);
}
export function* capSagaLiquidEntity() {
  yield all([
    watchLiquidEntity(),
    watchMetaId(),
  ]);
};

export function* v2CapSagas() {
  yield all([
    loginFlow(),
    watchForOrgChange(),
    watchForLogoutFlow(),
    watchForFetchUserInfo(),
    watchGetTopbarMenuData(),
    watchForGetVideosConfig(),
    watchMetaId(),
  ]);
}
