package com.bb.front;

import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.List;

import jakarta.servlet.http.HttpServletRequest;

import org.apache.http.conn.ConnectTimeoutException;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import org.springframework.web.reactive.function.client.WebClientResponseException;

import com.bb.model.PowerballData;
import com.bb.model.PowerballRequest;
import com.bb.model.PowerballResponse;
import com.bb.service.CallBackService;
import com.bb.service.SiteService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
@RequestMapping("/api/callback/powerball")
@RequiredArgsConstructor
@SecurityRequirement(name = "Authorization")
public class CallBackPowerBall {


	@Autowired
	SiteService siteService;
	
	@Autowired
	CallBackService callBackService;

	@Autowired
	WebClient webClient;
	
	
	@ResponseBody
	@RequestMapping(path = "/balance")
	public ResponseEntity<PowerballResponse> balance(HttpServletRequest request, @RequestParam String id, @RequestParam String siteName) throws Exception {
		PowerballResponse response = null;
		PowerballData data = null;
		HttpStatus httpStatus = HttpStatus.OK;
		
		//사이트정보
		HashMap sParam = new HashMap();
		long siteIdx = Long.parseLong(id.substring(0, 3), 16);
		String memberId = id.substring(3, id.length());
		final String LOG_PREFIX = "#-CB::POWER_BALL::"+memberId+"::BALANCE::::";
		
		log.info(LOG_PREFIX+ "id:"+id+", siteName:"+siteName);
		
		try {
			sParam.put("siteIdx", siteIdx);
			sParam.put("memberId",  memberId);
			HashMap siteApiInfo = siteService.getSiteApiInfo(sParam);
			if(siteApiInfo == null) {
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("NOT_FOUND_USER");
				data = new PowerballData();
				data.setSiteId(siteName);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
				log.error(LOG_PREFIX+ "Response Body: "+response.toString());
				return new ResponseEntity<PowerballResponse>(response, httpStatus);
			}
			
			JSONObject member = new JSONObject();
			member.put("userId", memberId);
			log.info(LOG_PREFIX + "SEND_BALANCE request body: " + member.toString());
			
			HttpHeaders header = new HttpHeaders();				
			header.add("Content-Type", "application/json");
			header.add("Accept", "application/json");
			header.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" + " AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");

			ResponseEntity<String> responseEntity = webClient.post()
					.uri(siteApiInfo.get("siteCbUrl")+"/balance")
					.headers(h -> h.addAll(header))
					.bodyValue(member.toString())
					.retrieve()
					.toEntity(String.class)
					.block();

			log.info(LOG_PREFIX+ "SEND_BALANCE status code: " + responseEntity.getStatusCode());
			log.info(LOG_PREFIX+ "SEND_BALANCE response body: " + responseEntity.getBody());
			
			JSONObject resData  = new JSONObject(responseEntity.getBody());
			int balance = resData.getInt("balance");
			
			response = new PowerballResponse();
			response.setResult("SUCCESS");
			response.setMsg("");
			data = new PowerballData();
			data.setSiteId(siteName);
			data.setMemId(id);
			data.setBalance(Integer.toString(balance));
			response.setData(data);
			
		} catch (WebClientResponseException e) {
	    	// HttpServerErrorException handling
	    	if (e.getStatusCode().is5xxServerError()) {
	    		log.error(LOG_PREFIX+ "WebClientResponseException 5xx: " + e.getResponseBodyAsString());
	    		response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("BALANCE_SERVER_ERROR");
				data = new PowerballData();
				data.setSiteId(siteName);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
	    	}
	    	// HttpClientErrorException handling
	    	else if (e.getStatusCode().is4xxClientError()) {
	    		log.error(LOG_PREFIX+ "WebClientResponseException 4xx: " + e.getResponseBodyAsString());
	    		response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("BALANCE_SERVER_ERROR");
				data = new PowerballData();
				data.setSiteId(siteName);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
	    	} else {
	    		log.error(LOG_PREFIX+ "WebClientResponseException: " + e.getResponseBodyAsString());
	    		response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("BALANCE_SERVER_ERROR");
				data = new PowerballData();
				data.setSiteId(siteName);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
	    	}
	    	
		} catch (WebClientRequestException e) {
			// 타임아웃 등 연결 오류
			Throwable cause = e.getCause();
			if (cause instanceof ConnectTimeoutException) {
				log.error(LOG_PREFIX+ "ConnectTimeoutException: " + cause.getMessage());
			} else if (cause instanceof SocketTimeoutException) {
				log.error(LOG_PREFIX+ "SocketTimeoutException: " + cause.getMessage());
			} else {
				log.error(LOG_PREFIX+ "WebClientRequestException: " + e.getMessage());
			}
			
            response = new PowerballResponse();
			response.setResult("FAILED");
			response.setMsg("TIMEOUT_ERROR");
			data = new PowerballData();
			data.setSiteId(siteName);
			data.setMemId(id);
			data.setBalance("0");
			response.setData(data);
			
		/*
		} catch (ResourceAccessException rae) {
            if(rae.getCause() instanceof ConnectTimeoutException) {
            	log.error(LOG_PREFIX+ "ConnectTimeoutException: " + rae.getMessage());
            }
        
            if(rae.getCause() instanceof SocketTimeoutException) {
            	log.error(LOG_PREFIX+ "SocketTimeoutException: " + rae.getMessage());
            }
        
            if(rae.getCause() instanceof InterruptedException) {
            	log.error(LOG_PREFIX+ "InterruptedException: " + rae.getMessage());
            }
            
            response = new PowerballResponse();
			response.setResult("FAILED");
			response.setMsg("TIMEOUT_ERROR");
			data = new PowerballData();
			data.setSiteId(siteName);
			data.setMemId(id);
			data.setBalance("0");
			response.setData(data);
		*/	
		} catch (Exception e) {
			log.error(LOG_PREFIX+ "Exception: " + e.getMessage());
			response = new PowerballResponse();
			response.setResult("FAILED");
			response.setMsg("BALANCE_SERVER_ERROR");
			data = new PowerballData();
			data.setSiteId(siteName);
			data.setMemId(id);
			data.setBalance("0");
			response.setData(data);
		}
		
		log.error(LOG_PREFIX+ "Response Body: " + response.toString());
		ResponseEntity<PowerballResponse> res = new ResponseEntity<PowerballResponse>(response, httpStatus);
		
		return res;
	}
	
	
	@ResponseBody
	@RequestMapping(path = "/bet")
	public ResponseEntity<PowerballResponse> bet(HttpServletRequest request, @RequestBody net.sf.json.JSONObject reqBodyObj) throws Exception {
		PowerballResponse response = null;
		PowerballData data = null;
		HttpStatus httpStatus = HttpStatus.OK;
		
		ObjectMapper mapper = new ObjectMapper();
		PowerballRequest reqBody = mapper.readValue(reqBodyObj.toString(), new TypeReference<PowerballRequest>() {});
		
		//사이트정보
		HashMap sParam = new HashMap();
		long siteIdx = Long.parseLong(reqBody.getId().substring(0, 3), 16);
		String memberId = reqBody.getId().substring(3, reqBody.getId().length());
		
		String siteId = reqBody.getSiteId();
		String id = reqBody.getId();
		String transactionId = reqBody.getBetId();
		String gameName = reqBody.getGameName();
		
		String gameType = reqBody.getGameType();
		String gameTypeName = "";
		String betType = reqBody.getBetType();
		String betTypeName = "";
		String rateType = "";
		
		final String LOG_PREFIX = "#-CB::POWER_BALL::"+memberId+"::"+transactionId+"::BET::::";
		
		log.info(LOG_PREFIX+ "reqBodyObj:"+reqBodyObj);
		log.info(LOG_PREFIX+ "reqBody:"+reqBody);
		
		try {
			sParam.put("siteIdx", siteIdx);
			sParam.put("memberId", memberId);
			sParam.put("vendor", "");
			sParam.put("vendorGameCode", "powerball");
			log.info(LOG_PREFIX + "getSiteVendorInfo::"+sParam.toString());
			HashMap<String,String> siteVendorInfo = siteService.getSiteVendorInfo(sParam);
			if(siteVendorInfo == null) {
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("NOT_FOUND_USER");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
				log.error(LOG_PREFIX+ "Response Body: "+response.toString());
				return new ResponseEntity<PowerballResponse>(response, httpStatus);
			}
			log.info(LOG_PREFIX + "siteVendorInfo::"+siteVendorInfo.toString());
			
			long memberIdx = Long.parseLong(siteVendorInfo.get("memberIdx").toString());
			String vendorApiId = siteVendorInfo.get("vendorApiId").toString();
			
			int amount = Math.abs(reqBody.getBetAmt());
			long siteCredit = Long.parseLong(siteVendorInfo.get("credit").toString());
			if(siteCredit < amount) {
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("NO_SITE_CREDIT");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
				log.error(LOG_PREFIX+ "Response Body: "+response.toString());
				return new ResponseEntity<PowerballResponse>(response, httpStatus);
			}
			
			String vendorTranKey = transactionId;
			String tranId = siteId + "#D#" + vendorTranKey;
			String betId = siteId + "#" + vendorTranKey;
			String vendorKey = siteVendorInfo.get("vendorKey").toString();
			int vendorIdx = Integer.parseInt(siteVendorInfo.get("vendorIdx").toString());
			String vendorCetegory = siteVendorInfo.get("vendorCetegory").toString();
			
			List<HashMap<String,String>> infoList = siteService.getPowerBallInfoList(gameType);
			for(HashMap<String,String> info : infoList) {
				if(betType.equals(info.get("betType").toString())) {
					gameTypeName = info.get("gameTypeName").toString();
					betTypeName = info.get("betTypeName").toString();
					rateType = info.get("rateType").toString();
				}
			}
			
			if(gameTypeName.equals("") || betTypeName.equals("")) {
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("NOT_FOUND_GAME_TYPE");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
				log.error(LOG_PREFIX+ "Response Body: "+response.toString());
				return new ResponseEntity<PowerballResponse>(response, httpStatus);
			}
			
			HashMap tranParam = new HashMap();
			tranParam.put("tranId", tranId);
			tranParam.put("refId",  betId);
			tranParam.put("siteIdx", siteIdx);
			tranParam.put("siteId", siteId);
			tranParam.put("memberIdx", memberIdx);
			tranParam.put("memberId", memberId);
			tranParam.put("vendorCetegory", vendorCetegory);
			tranParam.put("vendorIdx", vendorIdx);
			tranParam.put("vendorCode", "powerball");
			tranParam.put("vendorTranKey", vendorTranKey);
			tranParam.put("gameType", gameType);
			tranParam.put("gameId", "");
			tranParam.put("gameIdx", gameName+"("+gameTypeName+")");
			tranParam.put("tranType", "debit");
			tranParam.put("depositAmt", amount);
			tranParam.put("creditAmt", 0);
			tranParam.put("isCancel", "N");
			tranParam.put("isTie", "N");
			tranParam.put("apiStatus", 0);
			tranParam.put("vendorApiId", vendorApiId);
			
			log.info(LOG_PREFIX + "-----INSERT_BET_START-----");
			siteService.commonBetinsert(tranParam);
			log.info(LOG_PREFIX + "-----INSERT_BET_END-----");
			
			JSONObject debit = new JSONObject();
			debit.put("betId", betId);
			debit.put("tranId", tranId);
			debit.put("userId", memberId);
			debit.put("vendorIdx", vendorIdx);
			debit.put("vendorKey", vendorKey);
			debit.put("vendor", "powerball");
			debit.put("gameIdx", vendorIdx);
			debit.put("gameKey", gameName+"("+gameTypeName+")");
			debit.put("gameType", gameType);
			debit.put("gameId", "");
			debit.put("tranType", "debit");
			debit.put("debit", amount);
			debit.put("credit", 0);
			debit.put("isCancel", 0);
			debit.put("isBonus", 0);
			
			/**
			 * betType : 유저가 배팅한 타입
			 * gameType : 게임 타입
			 * resultType : 결과 타입
			 */
			
			JSONArray detailsArr = new JSONArray();
			
			JSONObject detailItem = new JSONObject();
			detailItem.put("detailId", betType+"("+betTypeName+")");
			detailItem.put("detailType", rateType);
			detailItem.put("detailName", gameType+"("+gameTypeName+")");
			detailItem.put("betAmt", amount);
			detailItem.put("betWinAmt", 0);
			detailsArr.put(detailItem);
			
			debit.put("betDetails", detailsArr);
			
			log.info(LOG_PREFIX + "SEND_DEBIT request body: " + debit.toString());
			JSONObject resData = new JSONObject();
			resData = callBackService.changeBalance(LOG_PREFIX, siteVendorInfo, debit);
			log.info(LOG_PREFIX + "SEND_DEBIT status code: " + resData.getLong("result_code"));
			log.info(LOG_PREFIX + "SEND_DEBIT response body: " + resData.toString());
			
			if(resData.getLong("result_code") == 0) {
				tranParam.put("balance", resData.getInt("balance"));
				int res = siteService.updateCbApi(tranParam);
				log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END");
				
				int balance = resData.getInt("balance");
				
				response = new PowerballResponse();
				response.setResult("SUCCESS");
				response.setMsg("");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance(Integer.toString(balance));
				response.setData(data);
			} else {
				String msg = "";
				if(resData.has("error_msg")) msg = resData.getString("error_msg");
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg(msg);
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
			}
			
		} catch (ResourceAccessException rae) {
            if(rae.getCause() instanceof ConnectTimeoutException) {
            	log.error(LOG_PREFIX+ "ConnectTimeoutException: " + rae.getMessage());
            }
        
            if(rae.getCause() instanceof SocketTimeoutException) {
            	log.error(LOG_PREFIX+ "SocketTimeoutException: " + rae.getMessage());
            }
        
            if(rae.getCause() instanceof InterruptedException) {
            	log.error(LOG_PREFIX+ "InterruptedException: " + rae.getMessage());
            }
            
            response = new PowerballResponse();
			response.setResult("FAILED");
			response.setMsg("TIMEOUT_ERROR");
			data = new PowerballData();
			data.setSiteId(siteId);
			data.setMemId(id);
			data.setBalance("0");
			response.setData(data);
			
		} catch (Exception e) {
			log.error(LOG_PREFIX+ "Exception: " + e.getMessage());
			response = new PowerballResponse();
			response.setResult("FAILED");
			response.setMsg("BET_SERVER_ERROR");
			data = new PowerballData();
			data.setSiteId(siteId);
			data.setMemId(id);
			data.setBalance("0");
			response.setData(data);
		}
		
		
		httpStatus = HttpStatus.OK;
		log.error(LOG_PREFIX+ "Response Body: " + response.toString());
		ResponseEntity<PowerballResponse> res = new ResponseEntity<PowerballResponse>(response, httpStatus);
		
		return res;
	}
	
	
	@ResponseBody
	@RequestMapping(path = "/result")
	public ResponseEntity<PowerballResponse> result(HttpServletRequest request, @RequestBody net.sf.json.JSONObject reqBodyObj) throws Exception {
		PowerballResponse response = null;
		PowerballData data = null;
		HttpStatus httpStatus = HttpStatus.OK;
		
		ObjectMapper mapper = new ObjectMapper();
		PowerballRequest reqBody = mapper.readValue(reqBodyObj.toString(), new TypeReference<PowerballRequest>() {});
		
		//사이트정보
		HashMap sParam = new HashMap();
		long siteIdx = Long.parseLong(reqBody.getId().substring(0, 3), 16);
		String memberId = reqBody.getId().substring(3, reqBody.getId().length());
		
		String siteId = reqBody.getSiteId();
		String id = reqBody.getId();
		String transactionId = reqBody.getBetId();
		String gameName = reqBody.getGameName();
		
		String gameType = reqBody.getGameType();
		String gameTypeName = "";
		String betType = reqBody.getBetType();
		String betTypeName = "";
		if(reqBody.getResultType() == null) {
			reqBody.setResultType("");
		}
		String resultType = reqBody.getResultType();
		String resultTypeName = "";
		String rateType = "";
		
		final String LOG_PREFIX = "#-CB::POWER_BALL::"+memberId+"::"+transactionId+"::RESULT::::";
		
		log.info(LOG_PREFIX+ "reqBodyObj:"+reqBodyObj);
		log.info(LOG_PREFIX+ "reqBody:"+reqBody);
		
		try {
			sParam.put("siteIdx", siteIdx);
			sParam.put("memberId", memberId);
			sParam.put("vendor", "");
			sParam.put("vendorGameCode", "powerball");
			log.info(LOG_PREFIX + "getSiteVendorInfo::"+sParam.toString());
			HashMap<String,String> siteVendorInfo = siteService.getSiteVendorInfo(sParam);
			if(siteVendorInfo == null) {
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("NOT_FOUND_USER");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
				log.error(LOG_PREFIX+ "Response Body: "+response.toString());
				return new ResponseEntity<PowerballResponse>(response, httpStatus);
			}
			log.info(LOG_PREFIX + "siteVendorInfo::"+siteVendorInfo.toString());
			
			long memberIdx = Long.parseLong(siteVendorInfo.get("memberIdx").toString());
			String vendorApiId = siteVendorInfo.get("vendorApiId").toString();
			
			int amount = Math.abs(reqBody.getBetWinAmt());
			long siteCredit = Long.parseLong(siteVendorInfo.get("credit").toString());
			if(siteCredit < amount) {
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("NO_SITE_CREDIT");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
				log.error(LOG_PREFIX+ "Response Body: "+response.toString());
				return new ResponseEntity<PowerballResponse>(response, httpStatus);
			}
			
			String vendorTranKey = transactionId;
			String tranId = siteId + "#C#" + vendorTranKey;
			String betId = siteId + "#" + vendorTranKey;
			String vendorKey = siteVendorInfo.get("vendorKey").toString();
			int vendorIdx = Integer.parseInt(siteVendorInfo.get("vendorIdx").toString());
			String vendorCetegory = siteVendorInfo.get("vendorCetegory").toString();
			
			List<HashMap<String,String>> infoList = siteService.getPowerBallInfoList(gameType);
			for(HashMap<String,String> info : infoList) {
				if(betType.equals(info.get("betType").toString())) {
					gameTypeName = info.get("gameTypeName").toString();
					betTypeName = info.get("betTypeName").toString();
					rateType = info.get("rateType").toString();
				}
				if(resultType.equals(info.get("betType").toString())) {
					resultTypeName = info.get("betTypeName").toString();
				}
			}
			
			if(gameTypeName.equals("") || betTypeName.equals("")) {
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg("NOT_FOUND_GAME_TYPE");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
				log.error(LOG_PREFIX+ "Response Body: "+response.toString());
				return new ResponseEntity<PowerballResponse>(response, httpStatus);
			}
			
			HashMap tranParam = new HashMap();
			tranParam.put("tranId", tranId);
			tranParam.put("refId",  betId);
			tranParam.put("siteIdx", siteIdx);
			tranParam.put("siteId", siteId);
			tranParam.put("memberIdx", memberIdx);
			tranParam.put("memberId", memberId);
			tranParam.put("vendorCetegory", vendorCetegory);
			tranParam.put("vendorIdx", vendorIdx);
			tranParam.put("vendorCode", "powerball");
			tranParam.put("vendorTranKey", vendorTranKey);
			tranParam.put("gameType", gameType);
			tranParam.put("gameId", "");
			tranParam.put("gameIdx", gameName+"("+gameTypeName+")");
			tranParam.put("tranType", "credit");
			tranParam.put("depositAmt", 0);
			tranParam.put("creditAmt", amount);
			tranParam.put("isCancel", "N");
			tranParam.put("isTie", "N");
			tranParam.put("apiStatus", 0);
			tranParam.put("vendorApiId", vendorApiId);
			
			/**
			 * betType : 유저가 배팅한 타입
			 * gameType : 게임 타입
			 * resultType : 결과 타입
			 */
			
			JSONArray detailsArr = new JSONArray();
			JSONObject detailItem = new JSONObject();
			detailItem.put("detailId", betType+"("+betTypeName+")");
			detailItem.put("detailType", rateType);
			detailItem.put("detailName", gameType+"("+gameTypeName+")");
			detailItem.put("betAmt", 0);
			detailItem.put("betWinAmt", amount);
			
			JSONObject detailCredit = new JSONObject();
			detailCredit.put("rateType", rateType);
			detailCredit.put("betType", betType);
			detailCredit.put("betTypeName", betTypeName);
			detailCredit.put("gameType", gameType);
			detailCredit.put("gameTypeName", gameTypeName);
			detailCredit.put("resultType", resultType);
			detailCredit.put("resultTypeName", resultTypeName);
			detailCredit.put("betAmt", reqBody.getBetAmt());
			detailCredit.put("betWinAmt", reqBody.getBetWinAmt());
			
			detailItem.put("detail", detailCredit);
			detailsArr.put(detailItem);
			
			tranParam.put("detail", detailCredit.toString());
			log.info(LOG_PREFIX + "-----INSERT_BET_START-----");
			siteService.commonBetinsert(tranParam);
			log.info(LOG_PREFIX + "-----INSERT_BET_END-----");
			
			JSONObject credit = new JSONObject();
			credit.put("betId", betId);
			credit.put("tranId", tranId);
			credit.put("userId", memberId);
			credit.put("vendorIdx", vendorIdx);
			credit.put("vendorKey", vendorKey);
			credit.put("vendor", "powerball");
			credit.put("gameIdx", vendorIdx);
			credit.put("gameKey", gameName+"("+gameTypeName+")");
			credit.put("gameType", gameType);
			credit.put("gameId", "");
			credit.put("tranType", "credit");
			credit.put("debit", 0);
			credit.put("credit", amount);
			credit.put("isCancel", 0);
			credit.put("isBonus", 0);
			credit.put("betDetails", detailsArr);
			
			log.info(LOG_PREFIX + "SEND_CREDIT request body: " + credit.toString());
			JSONObject resData = new JSONObject();
			resData = callBackService.changeBalance(LOG_PREFIX, siteVendorInfo, credit);
			log.info(LOG_PREFIX + "SEND_CREDIT status code: " + resData.getLong("result_code"));
			log.info(LOG_PREFIX + "SEND_CREDIT response body: " + resData.toString());
			
			if(resData.getLong("result_code") == 0) {
				tranParam.put("balance", resData.getInt("balance"));
				int res = siteService.updateCbApi(tranParam);
				log.info(LOG_PREFIX + "UPDATE_CALLBACK_API_STATUS END");
				
				int balance = resData.getInt("balance");
				
				response = new PowerballResponse();
				response.setResult("SUCCESS");
				response.setMsg("");
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance(Integer.toString(balance));
				response.setData(data);
			} else {
				String msg = "";
				if(resData.has("error_msg")) msg = resData.getString("error_msg");
				response = new PowerballResponse();
				response.setResult("FAILED");
				response.setMsg(msg);
				data = new PowerballData();
				data.setSiteId(siteId);
				data.setMemId(id);
				data.setBalance("0");
				response.setData(data);
			}
			
		} catch (ResourceAccessException rae) {
            if(rae.getCause() instanceof ConnectTimeoutException) {
            	log.error(LOG_PREFIX+ "ConnectTimeoutException: " + rae.getMessage());
            }
        
            if(rae.getCause() instanceof SocketTimeoutException) {
            	log.error(LOG_PREFIX+ "SocketTimeoutException: " + rae.getMessage());
            }
        
            if(rae.getCause() instanceof InterruptedException) {
            	log.error(LOG_PREFIX+ "InterruptedException: " + rae.getMessage());
            }
            
            response = new PowerballResponse();
			response.setResult("FAILED");
			response.setMsg("TIMEOUT_ERROR");
			data = new PowerballData();
			data.setSiteId(siteId);
			data.setMemId(id);
			data.setBalance("0");
			response.setData(data);
			
		} catch (Exception e) {
			log.error(LOG_PREFIX+ "Exception: " + e.getMessage());
			response = new PowerballResponse();
			response.setResult("FAILED");
			response.setMsg("RESULT_SERVER_ERROR");
			data = new PowerballData();
			data.setSiteId(siteId);
			data.setMemId(id);
			data.setBalance("0");
			response.setData(data);
		}
		
		
		httpStatus = HttpStatus.OK;
		log.error(LOG_PREFIX+ "Response Body: " + response.toString());
		ResponseEntity<PowerballResponse> res = new ResponseEntity<PowerballResponse>(response, httpStatus);
		
		return res;
	}
}
