package com.bb.api;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.bb.jwt.JwtManager;
import com.bb.model.ApiResponse;
import com.bb.model.CallbackTestResult;
import com.bb.model.Site;
import com.bb.service.CallBackService;
import com.bb.service.CallBackTestService;
import com.bb.service.SiteService;
import com.bb.service.TransService;
import com.bb.util.IPKit;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@RequiredArgsConstructor
@RequestMapping(value = "/api/v1/test")
public class ApiCallbackTestController {

	@Autowired
	SiteService siteService;
	
	@Autowired
	TransService transService;
	
	@Autowired
	CallBackTestService callBackService;
	
	@Autowired
	private final JwtManager jwtManager;
	
	
	@ResponseBody	
	@GetMapping("/testBalance")
    public ApiResponse testBalance(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		try {
			Site site = siteService.getSiteInfoAPI(request);
			if(site == null) {
				apiResponse.setResultCode("9999");
				apiResponse.setResultMessage("Authorization apiKey check");
				return apiResponse;
			}
			
			if( !( site.getSiteIp()==null || "".equals(site.getSiteIp())
					|| "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) {
				log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
				apiResponse.setResultCode("10001");
				return apiResponse;
			}
			
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token);
				final String LOG_PREFIX = "#-API::CB_TEST::testBalance::"+tokenInfo.getSid()+"::";
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				JSONObject responseObj = callBackService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				if(resultCode == 0) {
					result.setIndex(1);
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
				} else {
					result.setIndex(1);
					result.setStatus("FAIL");
					result.setMsg("[balance] 실패");
				}
				result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
				result.setRequestBody(requestBody.toString());
				result.setResponseData(responseObj.toString());
				resultList.add(result);
				
				responseData.put("resultList", resultList);

				apiResponse.setData(responseData);
				apiResponse.success();
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@GetMapping("/testBet")
    public ApiResponse testBet(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		try {
			Site site = siteService.getSiteInfoAPI(request);
			if(site == null) {
				apiResponse.setResultCode("9999");
				apiResponse.setResultMessage("Authorization apiKey check");
				return apiResponse;
			}
			
			if( !( site.getSiteIp()==null || "".equals(site.getSiteIp())
					|| "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) {
				log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
				apiResponse.setResultCode("10001");
				return apiResponse;
			}
			
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token);
				final String LOG_PREFIX = "#-API::CB_TEST::testBet::"+tokenInfo.getSid()+"::";
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				int balance = 0;
				int betAmt = 100;
				int winAmt = 200;
				
				// 2-1 call balance
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				JSONObject responseObj = callBackService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				if(resultCode == 0) {
					result.setIndex(1);
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					balance = responseObj.getInt("balance");
				} else {
					result.setIndex(1);
					result.setStatus("FAIL");
					result.setMsg("[balance] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
				long ctms = System.currentTimeMillis();
				String betId = "B"+site.getSiteIdx()+ctms+memberId;
				String tranId = "D"+site.getSiteIdx()+ctms+memberId;
				
				// 2-2 call bet
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "debit");
				requestBody.put("debit", betAmt);
				requestBody.put("credit", 0);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(2);
						result.setStatus("SUCCESS");
						result.setMsg("[bet] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(2);
						result.setStatus("FAIL");
						result.setMsg("[bet] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(2);
					result.setStatus("FAIL");
					result.setMsg("[bet] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 2-3 call bet 중복
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 98) {
					int balanceAfter = balance - betAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(3);
						result.setStatus("SUCCESS");
						result.setMsg("[bet 중복] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(3);
						result.setStatus("FAIL");
						result.setMsg("[bet 중복] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(3);
					result.setStatus("FAIL");
					result.setMsg("[bet 중복] 실패: 배팅중복 시 result_code=98 입니다.");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 2-4 call win
				tranId = "C"+site.getSiteIdx()+ctms+memberId;
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "credit");
				requestBody.put("debit", 0);
				requestBody.put("credit", winAmt);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt + winAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(4);
						result.setStatus("SUCCESS");
						result.setMsg("[win] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(4);
						result.setStatus("FAIL");
						result.setMsg("[win] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(4);
					result.setStatus("FAIL");
					result.setMsg("[win] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				responseData.put("resultList", resultList);
				apiResponse.setData(responseData);
				apiResponse.success();
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@GetMapping("/testBetOver")
    public ApiResponse testBetOver(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		try {
			Site site = siteService.getSiteInfoAPI(request);
			if(site == null) {
				apiResponse.setResultCode("9999");
				apiResponse.setResultMessage("Authorization apiKey check");
				return apiResponse;
			}
			
			if( !( site.getSiteIp()==null || "".equals(site.getSiteIp())
					|| "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) {
				log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
				apiResponse.setResultCode("10001");
				return apiResponse;
			}
			
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token);
				final String LOG_PREFIX = "#-API::CB_TEST::testBetOver::"+tokenInfo.getSid()+"::";
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				int balance = 0;
				
				// 3-1 call balance
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				JSONObject responseObj = callBackService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				if(resultCode == 0) {
					result.setIndex(1);
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					balance = responseObj.getInt("balance");
				} else {
					result.setIndex(1);
					result.setStatus("FAIL");
					result.setMsg("[balance] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
				long ctms = System.currentTimeMillis();
				String betId = "B"+site.getSiteIdx()+ctms+memberId;
				String tranId = "D"+site.getSiteIdx()+ctms+memberId;
				

				int betAmt = balance + 100;
				// 3-2 call bet
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "debit");
				requestBody.put("debit", betAmt);
				requestBody.put("credit", 0);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 80) {
					int balanceAfter = balance;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(2);
						result.setStatus("SUCCESS");
						result.setMsg("[bet over] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(2);
						result.setStatus("FAIL");
						result.setMsg("[bet over] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(2);
					result.setStatus("FAIL");
					result.setMsg("[bet over] 실패: 배팅금 초과 시 result_code=80 입니다.");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				responseData.put("resultList", resultList);
				apiResponse.setData(responseData);
				apiResponse.success();
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@GetMapping("/testWin")
    public ApiResponse testWin(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		try {
			Site site = siteService.getSiteInfoAPI(request);
			if(site == null) {
				apiResponse.setResultCode("9999");
				apiResponse.setResultMessage("Authorization apiKey check");
				return apiResponse;
			}
			
			if( !( site.getSiteIp()==null || "".equals(site.getSiteIp())
					|| "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) {
				log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
				apiResponse.setResultCode("10001");
				return apiResponse;
			}
			
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token);
				final String LOG_PREFIX = "#-API::CB_TEST::testWin::"+tokenInfo.getSid()+"::";
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				int balance = 0;
				int betAmt = 100;
				int winAmt = 200;
				
				// 4-1 call balance
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				JSONObject responseObj = callBackService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				if(resultCode == 0) {
					result.setIndex(1);
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					balance = responseObj.getInt("balance");
				} else {
					result.setIndex(1);
					result.setStatus("FAIL");
					result.setMsg("[balance] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
				long ctms = System.currentTimeMillis();
				String betId = "B"+site.getSiteIdx()+ctms+memberId;
				String tranId = "D"+site.getSiteIdx()+ctms+memberId;
				
				// 4-2 call bet
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "debit");
				requestBody.put("debit", betAmt);
				requestBody.put("credit", 0);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(2);
						result.setStatus("SUCCESS");
						result.setMsg("[bet] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(2);
						result.setStatus("FAIL");
						result.setMsg("[bet] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(2);
					result.setStatus("FAIL");
					result.setMsg("[bet] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 4-3 call win
				tranId = "C"+site.getSiteIdx()+ctms+memberId;
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "credit");
				requestBody.put("debit", 0);
				requestBody.put("credit", winAmt);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt + winAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(3);
						result.setStatus("SUCCESS");
						result.setMsg("[win] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(3);
						result.setStatus("FAIL");
						result.setMsg("[win] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(3);
					result.setStatus("FAIL");
					result.setMsg("[win] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 4-4 call win 중복
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 98) {
					int balanceAfter = balance - betAmt + winAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(4);
						result.setStatus("SUCCESS");
						result.setMsg("[win 중복] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(4);
						result.setStatus("FAIL");
						result.setMsg("[win 중복] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(4);
					result.setStatus("FAIL");
					result.setMsg("[win 중복] 실패: 결과중복 시 result_code=98 입니다.");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				responseData.put("resultList", resultList);
				apiResponse.setData(responseData);
				apiResponse.success();
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@GetMapping("/testCancel")
    public ApiResponse testCancel(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		try {
			Site site = siteService.getSiteInfoAPI(request);
			if(site == null) {
				apiResponse.setResultCode("9999");
				apiResponse.setResultMessage("Authorization apiKey check");
				return apiResponse;
			}
			
			if( !( site.getSiteIp()==null || "".equals(site.getSiteIp())
					|| "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) {
				log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
				apiResponse.setResultCode("10001");
				return apiResponse;
			}
			
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token);
				final String LOG_PREFIX = "#-API::CB_TEST::testCancel::"+tokenInfo.getSid()+"::";
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				int balance = 0;
				int betAmt = 100;
				int winAmt = 100;
				
				// 5-1 call balance
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				JSONObject responseObj = callBackService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				if(resultCode == 0) {
					result.setIndex(1);
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					balance = responseObj.getInt("balance");
				} else {
					result.setIndex(1);
					result.setStatus("FAIL");
					result.setMsg("[balance] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
				long ctms = System.currentTimeMillis();
				String betId = "B"+site.getSiteIdx()+ctms+memberId;
				String tranId = "D"+site.getSiteIdx()+ctms+memberId;
				
				// 5-2 call bet
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "debit");
				requestBody.put("debit", betAmt);
				requestBody.put("credit", 0);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(2);
						result.setStatus("SUCCESS");
						result.setMsg("[bet] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(2);
						result.setStatus("FAIL");
						result.setMsg("[bet] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(2);
					result.setStatus("FAIL");
					result.setMsg("[bet] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 5-3 call Cancel
				tranId = "C"+site.getSiteIdx()+ctms+memberId;
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "credit");
				requestBody.put("debit", 0);
				requestBody.put("credit", winAmt);
				requestBody.put("isCancel", 1);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt + winAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(3);
						result.setStatus("SUCCESS");
						result.setMsg("[cancel] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(3);
						result.setStatus("FAIL");
						result.setMsg("[cancel] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(3);
					result.setStatus("FAIL");
					result.setMsg("[cancel] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 5-4 call Cancel 중복
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 98) {
					int balanceAfter = balance - betAmt + winAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(4);
						result.setStatus("SUCCESS");
						result.setMsg("[cancel 중복] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(4);
						result.setStatus("FAIL");
						result.setMsg("[cancel 중복] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(4);
					result.setStatus("FAIL");
					result.setMsg("[cancel 중복] 실패: 결과중복 시 result_code=98 입니다.");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				responseData.put("resultList", resultList);
				apiResponse.setData(responseData);
				apiResponse.success();
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@GetMapping("/testAdjust")
    public ApiResponse testAdjust(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		try {
			Site site = siteService.getSiteInfoAPI(request);
			if(site == null) {
				apiResponse.setResultCode("9999");
				apiResponse.setResultMessage("Authorization apiKey check");
				return apiResponse;
			}
			
			if( !( site.getSiteIp()==null || "".equals(site.getSiteIp())
					|| "3.3.3.3".equals(site.getSiteIp()) || site.getSiteIp().indexOf(IPKit.getIpAddressByRequest(request)) >= 0) ) {
				log.error("site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
				apiResponse.setResultCode("10001");
				return apiResponse;
			}
			
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token);
				final String LOG_PREFIX = "#-API::CB_TEST::testAdjust::"+tokenInfo.getSid()+"::";
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				int balance = 0;
				int betAmt = 100;
				int winAmt = 200;
				int adjustAmt1 = 50;
				int adjustAmt2 = -50;
				
				// 6-1 call balance
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				JSONObject responseObj = callBackService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				if(resultCode == 0) {
					result.setIndex(1);
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					balance = responseObj.getInt("balance");
				} else {
					result.setIndex(1);
					result.setStatus("FAIL");
					result.setMsg("[balance] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
				long ctms = System.currentTimeMillis();
				String betId = "B"+site.getSiteIdx()+ctms+memberId;
				String tranId = "D"+site.getSiteIdx()+ctms+memberId;
				
				// 6-2 call bet
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "debit");
				requestBody.put("debit", betAmt);
				requestBody.put("credit", 0);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(2);
						result.setStatus("SUCCESS");
						result.setMsg("[bet] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(2);
						result.setStatus("FAIL");
						result.setMsg("[bet] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(2);
					result.setStatus("FAIL");
					result.setMsg("[bet] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 6-3 call win
				tranId = "C"+site.getSiteIdx()+ctms+memberId;
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "credit");
				requestBody.put("debit", 0);
				requestBody.put("credit", winAmt);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt + winAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(3);
						result.setStatus("SUCCESS");
						result.setMsg("[win] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(3);
						result.setStatus("FAIL");
						result.setMsg("[win] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(3);
					result.setStatus("FAIL");
					result.setMsg("[win] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 6-4 call adjust 잔액증가
				ctms = System.currentTimeMillis();
				tranId = "C"+site.getSiteIdx()+ctms+memberId;
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "adjust");
				requestBody.put("debit", 0);
				requestBody.put("credit", adjustAmt1);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt + winAmt + adjustAmt1;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(4);
						result.setStatus("SUCCESS");
						result.setMsg("[adjust 잔액증가] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(4);
						result.setStatus("FAIL");
						result.setMsg("[adjust 잔액증가] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(4);
					result.setStatus("FAIL");
					result.setMsg("[adjust 잔액증가] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 6-5 call adjust 잔액증가 중복
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 98) {
					int balanceAfter = balance - betAmt + winAmt + adjustAmt1;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(5);
						result.setStatus("SUCCESS");
						result.setMsg("[adjust 잔액증가 중복] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(5);
						result.setStatus("FAIL");
						result.setMsg("[adjust 잔액증가 중복] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
					
					balance = responseObj.getInt("balance");
				} else {
					result.setIndex(5);
					result.setStatus("FAIL");
					result.setMsg("[adjust 잔액증가 중복] 실패: 결과중복 시 result_code=98 입니다.");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				
				ctms = System.currentTimeMillis();
				betId = "B"+site.getSiteIdx()+ctms+memberId;
				tranId = "D"+site.getSiteIdx()+ctms+memberId;
				
				// 6-6 call bet
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "debit");
				requestBody.put("debit", betAmt);
				requestBody.put("credit", 0);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(6);
						result.setStatus("SUCCESS");
						result.setMsg("[bet] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(6);
						result.setStatus("FAIL");
						result.setMsg("[bet] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(6);
					result.setStatus("FAIL");
					result.setMsg("[bet] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 6-7 call win
				tranId = "C"+site.getSiteIdx()+ctms+memberId;
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "credit");
				requestBody.put("debit", 0);
				requestBody.put("credit", winAmt);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt + winAmt;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(7);
						result.setStatus("SUCCESS");
						result.setMsg("[win] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(7);
						result.setStatus("FAIL");
						result.setMsg("[win] 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(7);
					result.setStatus("FAIL");
					result.setMsg("[win] 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 6-8 call adjust 잔액감소
				ctms = System.currentTimeMillis();
				tranId = "C"+site.getSiteIdx()+ctms+memberId;
				requestBody = new JSONObject();
				requestBody.put("betId", betId);
				requestBody.put("tranId", tranId);
				requestBody.put("userId", memberId);
				requestBody.put("vendorIdx", 1);
				requestBody.put("vendorKey", "C01");
				requestBody.put("vendor", "nexus");
				requestBody.put("gameIdx", 1);
				requestBody.put("gameKey", "코리안 스피드 바카라 A");
				requestBody.put("gameId", "");
				requestBody.put("tranType", "adjust");
				requestBody.put("debit", 0);
				requestBody.put("credit", adjustAmt2);
				requestBody.put("isCancel", 0);
				requestBody.put("isBonus", 0);
				requestBody.put("requestAt", sdf.format(System.currentTimeMillis()));
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 0) {
					int balanceAfter = balance - betAmt + winAmt + adjustAmt2;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(8);
						result.setStatus("SUCCESS");
						result.setMsg("[adjust] 잔액감소 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(8);
						result.setStatus("FAIL");
						result.setMsg("[adjust] 잔액감소 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(8);
					result.setStatus("FAIL");
					result.setMsg("[adjust] 잔액감소 실패");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				// 6-9 call adjust 잔액감소 중복
				responseObj = callBackService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				resultCode = responseObj.getInt("result_code");
				result = new CallbackTestResult();
				if(resultCode == 98) {
					int balanceAfter = balance - betAmt + winAmt + adjustAmt2;
					int balanceResult = responseObj.getInt("balance");
					if(balanceAfter == balanceResult) {
						result.setIndex(9);
						result.setStatus("SUCCESS");
						result.setMsg("[adjust 중복] 잔액감소 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
					} else {
						result.setIndex(9);
						result.setStatus("FAIL");
						result.setMsg("[adjust 중복] 잔액감소 실패: 잔액이 맞지 않습니다.");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						
						return apiResponse;
					}
				} else {
					result.setIndex(9);
					result.setStatus("FAIL");
					result.setMsg("[adjust 중복] 잔액감소 실패: 결과중복 시 result_code=98 입니다.");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					resultList.add(result);
					
					responseData.put("resultList", resultList);
					apiResponse.setData(responseData);
					apiResponse.success();
					
					return apiResponse;
				}
				
				responseData.put("resultList", resultList);
				apiResponse.setData(responseData);
				apiResponse.success();
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
}
