import {
takeEvery, put, call, select, takeLeading,
} from 'redux-saga/effects';
/**
* @namespace sagas/turbo
*/
import Constants, { GAME_TYPE, BUFFER_TIME } from '../constants';
import { requestGet } from '../utils/request';
import {
SHOW_ERROR_MODAL,
KICK_OFF,
KICK_OFF_SUCCESS,
SET_ROUND_LOADER,
GET_TURBO_ROUND_SUCCESS,
GET_TURBO_ROUND,
GET_PLACED_BETS,
FORCE_BALANCE_UPDATE,
SET_LAST_BET_ROUND_TURBO,
GET_BALANCE,
CLEAR_SELECTIONS,
GO_TO_BETS,
SET_TURBO_ROUND_ID,
DISABLE_PLACEBET,
SCHEDULE_BET_COUNT,
SET_FILTERED_SELECTED_ODDS,
} from '../reducers';
import { getInitialTurboBetsLoaded, getTurboRoundId } from '../store/bets';
import {
getLastBetRoundTurbo,
getLastTurboRoundBetPlacedId,
getPlacedSelectionsTurbo,
getSelectedOdds,
} from '../store/placebet';
import { delay, filterSelectedOdds } from '../utils/common';
import { getCurrentPage } from '../store/common';
/**
* Represent getting round data for turbo game
*
* @param {object} action
* @property {object} action
* @property {object} action.payload
* @property {Array|null} action.payload.placedSelections
* @memberof sagas/turbo
* @async
*/
function* getTurboRound(action) {
let response;
try {
const initialBetsLoaded = yield select(getInitialTurboBetsLoaded);
yield put({
type: SET_ROUND_LOADER,
payload: {
roundLoading: true,
},
});
response = yield call(requestGet, Constants.API_URLS.KICK_OFF, true);
if (response.status === -1) {
throw new Error(response.error.message);
} else {
const haveLiveMatches = !!response.data.liveId;
const roundEnd = response.data.endDate && new Date(response.data.endDate);
const leftTime = roundEnd && parseInt((roundEnd.getTime() - new Date().getTime()) / 1000);
const isNoBetTime = roundEnd
&& leftTime <= 2 && leftTime > 0; // change 3 to 2, give time for last moment user kick off
if (!initialBetsLoaded) {
yield put({
type: GET_PLACED_BETS,
payload: {
haveLiveMatches,
isNoBetTime,
roundId: response.data.roundId,
liveId: response.data.liveId,
turbo: true,
},
});
if (response.data.liveId) {
yield put({
type: KICK_OFF,
payload: {
liveId: response.data.liveId,
},
});
}
}
const selectedOdds = yield select(getSelectedOdds);
const roundId = response.data?.roundId;
const filteredSelectedOdds = filterSelectedOdds(selectedOdds, roundId);
yield put({
type: SET_FILTERED_SELECTED_ODDS,
payload: {
selectedOdds: filteredSelectedOdds,
},
});
yield put({
type: GET_TURBO_ROUND_SUCCESS,
payload: {
round: response.data,
roundEnd,
winCap: response.data.winCap,
bonusOddsThreshold: response.data.bonusOddsThreshold,
bonusPercentages: response.data.bonusPercentages.split('-'),
},
});
yield put({
type: DISABLE_PLACEBET,
payload: { placebetDisabled: false },
});
if (action.payload?.selectedOdds?.length === 0 || action.payload?.haveGameTypeChanged) {
yield put({
type: CLEAR_SELECTIONS,
});
}
const lastBetRound = yield select(getLastBetRoundTurbo);
if (lastBetRound && parseInt(lastBetRound) !== parseInt(response.data.roundId)) {
yield put({
type: FORCE_BALANCE_UPDATE,
payload: 0,
});
const lastTurboRoundId = yield select(getTurboRoundId);
yield put({
type: KICK_OFF,
payload: { liveId: lastTurboRoundId },
});
}
yield put({
type: SET_TURBO_ROUND_ID,
payload: {
roundId: response.data.roundId,
},
});
}
} catch (error) {
yield put({
type: SHOW_ERROR_MODAL,
payload: {
activeModal: error.modal || Constants.MODALS.GENERAL_ERROR,
message: error.message,
},
});
}
}
/**
* Represent getting live data for turbo game
*
* @param {object} action
* @property {object} action
* @property {object} action.payload
* @property {Array|null} action.payload.liveId
*
* @memberof sagas/turbo
* @async
*/
function* kickOff(action) {
// this is when user click on kick off
// in the last moments and we call it
// also because round is ending
if (action.payload && action.payload.placedSelections === null) {
return;
}
const lastTurboRoundBetPlacedId = yield select(getLastTurboRoundBetPlacedId);
let response;
try {
yield put({
type: SET_LAST_BET_ROUND_TURBO,
payload: null,
});
const roundId = action.payload && action.payload.liveId
? action.payload.liveId
: yield select(getTurboRoundId);
if (roundId !== lastTurboRoundBetPlacedId) {
return;
}
response = yield call(requestGet,
`${Constants.API_URLS.KICK_OFF}/${roundId}/close`, true);
if (response.status === -1) {
throw new Error(response.error.message);
} else {
let placedSelections = yield select(getPlacedSelectionsTurbo);
const initialBetsLoaded = yield select(getInitialTurboBetsLoaded);
placedSelections = placedSelections[roundId];
const now = new Date(response.data.liveEndDate).getTime()
- new Date(response.data.liveStartDate).getTime()
< BUFFER_TIME
? Date.now() - BUFFER_TIME
: Date.now();
if (new Date(response.data.liveEndDate).getTime() > now) {
const currentPage = yield select(getCurrentPage);
// prevents page change when on account page
const nextPage = currentPage === Constants.PAGES.MY_ACCOUNT_MENU
? currentPage : Constants.PAGES.MY_LIVE;
yield put({
type: KICK_OFF_SUCCESS,
payload: {
haveLiveMatches: true,
roundResults: response.data,
liveStart: new Date(response.data.liveStartDate),
currentPage: nextPage,
initialBetsLoaded,
},
});
let roundEndTime = response.data.liveEndDate;
roundEndTime = new Date(Date.parse(roundEndTime) + 3 * 1000);
yield put({
type: SCHEDULE_BET_COUNT,
payload: {
roundId,
gameType: GAME_TYPE.TURBO,
time: roundEndTime,
},
});
} else {
yield put({
type: GO_TO_BETS,
});
}
yield put({
type: CLEAR_SELECTIONS,
});
yield put({
type: GET_TURBO_ROUND,
payload: {
placedSelections,
},
});
yield delay((Math.floor(Math.random() * 5) + 5) * 1000);
yield put({
type: GET_BALANCE,
payload: {},
});
}
} catch (error) {
yield put({
type: SHOW_ERROR_MODAL,
payload: {
activeModal: error.modal || Constants.MODALS.GENERAL_ERROR,
message: error.message,
},
});
}
}
/**
* @memberof sagas/turbo
* @async
* @returns {void}
*/
export default function* turboSaga() {
yield takeEvery(GET_TURBO_ROUND, getTurboRound);
yield takeLeading(KICK_OFF, kickOff);
}