package com.bb.front;

import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

import org.codehaus.jettison.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
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.RestController;

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

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

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/api/t1/spdtest")
@CrossOrigin(
	    origins = {
	        "https://cms.cent-10.com",
	        "https://core.nsol.cc/",
	        "https://familys.cc/"
	    }
	)
public class CallbackSpeedTestController {

	@Autowired
	SiteService siteService;
	
	@Autowired
	CallBackTestService callBackTestService;
	
	@Autowired
	private final JwtManager jwtManager;
	
	private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    private static final SecureRandom random = new SecureRandom();

    public static List<String> generateRandomStrings(int stringLength, int count) {
        Set<String> uniqueStrings = new HashSet<>();

        while (uniqueStrings.size() < count) {
            StringBuilder sb = new StringBuilder(stringLength);
            for (int i = 0; i < stringLength; i++) {
                sb.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length())));
            }

            // 시간 기반으로 중복 확률 줄이기 (나노타임 일부 추가)
            sb.append(Long.toHexString(System.nanoTime()).substring(0, 4));

            uniqueStrings.add(sb.toString());
        }

        return new ArrayList<>(uniqueStrings);
    }
	
	
	@GetMapping("/testBalance")
    public ApiResponse testBalance(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		Site site = siteService.getSiteInfo(request);
		if(site == null) {
			log.error("#-CB::SPD_TEST::testBalance::Authorization apiKey check");
			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("#-CB::SPD_TEST::testBalance::site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
			apiResponse.setResultCode("10001");
			apiResponse.setResultMessage("Deniend IP");
			return apiResponse;
		}
		
		if(token == null || token.equals("")) {
			log.error("#-CB::SPD_TEST::testBalance::Authorization apiKey check");
			apiResponse.setResultCode("9999");
			apiResponse.setResultMessage("Authorization token check");
			return apiResponse;
		}
		
		try {
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfo(token);
				final String LOG_PREFIX = "#-CB::SPD_TEST::testBalance::"+tokenInfo.getSid()+"::";
				
				int testCnt = site.getTestCnt();
				if(testCnt > 30) {
					log.error(LOG_PREFIX+ "TEST_COUNT_OVER");
					apiResponse.setResultCode("9999");
					apiResponse.setResultMessage("TEST_COUNT_OVER");
					return apiResponse;
				}
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				
				for(int i=1; i<=10; i++) {
					JSONObject responseObj = callBackTestService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
					int resultCode = responseObj.getInt("result_code");
					CallbackTestResult result = new CallbackTestResult();
					result.setIndex(i);
					result.setTimeMs(responseObj.getLong("timeMs"));
					responseObj.remove("timeMs");
					
					if(resultCode == 0) {
						result.setStatus("SUCCESS");
						result.setMsg("[balance] 성공");
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData(responseObj.toString());
						
						resultList.add(result);
					} else {
						result.setStatus("FAIL");
						if(resultCode == -99) {
							result.setMsg(responseObj.getString("error_msg"));
							result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData("");
						} else {
							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;
					}
					
					Thread.sleep(500);
				}
				
				responseData.put("resultList", resultList);
				
				site.setTestCnt(testCnt+1);
				int updResult = siteService.updateTestCnt(site);

				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;
	}
	
	
	@GetMapping("/testCasino")
    public ApiResponse testCasino(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		Site site = siteService.getSiteInfo(request);
		if(site == null) {
			log.error("#-CB::SPD_TEST::testCasino::Authorization apiKey check");
			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("#-CB::SPD_TEST::testCasino::site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
			apiResponse.setResultCode("10001");
			return apiResponse;
		}
		
		if(token == null || token.equals("")) {
			log.error("#-CB::SPD_TEST::testCasino::Authorization apiKey check");
			apiResponse.setResultCode("9999");
			apiResponse.setResultMessage("Authorization token check");
			return apiResponse;
		}
		
		try {
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfo(token);
				final String LOG_PREFIX = "#-CB::SPD_TEST::testCasino::"+tokenInfo.getSid()+"::";
				
				int testCnt = site.getTestCnt();
				if(testCnt > 30) {
					log.error(LOG_PREFIX+ "TEST_COUNT_OVER");
					apiResponse.setResultCode("9999");
					apiResponse.setResultMessage("TEST_COUNT_OVER");
					return apiResponse;
				}
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				int balance = 0;
				int betAmt = 100;
				int winAmt = 100;
				
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				
				// 유저 잔액 확인.
				JSONObject responseObj = callBackTestService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				result.setIndex(0);
				result.setTimeMs(responseObj.getLong("timeMs"));
				responseObj.remove("timeMs");
				
				if(resultCode == 0) {
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					
					balance = responseObj.getInt("balance");
					
					resultList.add(result);
				} else {
					result.setStatus("FAIL");
					if(resultCode == -99) {
						result.setMsg(responseObj.getString("error_msg"));
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData("");
					} else {
						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;
				}
				
				Thread.sleep(500);
				
				
				// 베팅 - 결과 테스트 진행
				// 1. 랜점한 betId 10개 생성.
				List<String> betIds = generateRandomStrings(20, 20);
				
				// 2. 베팅-결과 콜백 10번 진행.
				for (int i = 0; i < 20; i += 2) {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
					long ctms = System.currentTimeMillis();
					String betId = "B"+site.getSiteIdx()+"_"+betIds.get(i)+"_"+memberId;
					String debitTranId = "D"+site.getSiteIdx()+"_"+ctms+"_"+memberId;
					String creditTranId = "C"+site.getSiteIdx()+"_"+ctms+"_"+memberId;
					
					// 2-1 call bet
					requestBody = new JSONObject();
					requestBody.put("betId", betId);
					requestBody.put("tranId", debitTranId);
					requestBody.put("userId", memberId);
					requestBody.put("vendorIdx", 1);
					requestBody.put("vendorKey", "C01");
					requestBody.put("vendor", "svendor");
					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 = callBackTestService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
					resultCode = responseObj.getInt("result_code");
					result = new CallbackTestResult();
					result.setIndex(i+1);
					result.setTimeMs(responseObj.getLong("timeMs"));
					responseObj.remove("timeMs");
					
					if(resultCode == 0) {
						int balanceAfter = balance - betAmt;
						int balanceResult = responseObj.getInt("balance");
						if(balanceAfter == balanceResult) {
							result.setStatus("SUCCESS");
							result.setMsg("[bet] 성공");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							balance = balanceAfter;
						} else {
							result.setStatus("FAIL");
							result.setMsg("[bet] 실패: 잔액이 맞지 않습니다.");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							responseData.put("resultList", resultList);
							apiResponse.setData(responseData);
							apiResponse.success();
							return apiResponse;
						}
					} else {
						result.setStatus("FAIL");
						if(resultCode == -99) {
							result.setMsg(responseObj.getString("error_msg"));
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData("");
						} else {
							result.setMsg("[bet] 실패");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
						}
						
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						return apiResponse;
					}
					
					Thread.sleep(500);
					
					// 2-2 call win
					requestBody = new JSONObject();
					requestBody.put("betId", betId);
					requestBody.put("tranId", creditTranId);
					requestBody.put("userId", memberId);
					requestBody.put("vendorIdx", 1);
					requestBody.put("vendorKey", "C01");
					requestBody.put("vendor", "svendor");
					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 = callBackTestService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
					resultCode = responseObj.getInt("result_code");
					result = new CallbackTestResult();
					result.setIndex(i+2);
					result.setTimeMs(responseObj.getLong("timeMs"));
					responseObj.remove("timeMs");
					
					if(resultCode == 0) {
						int balanceAfter = balance + winAmt;
						int balanceResult = responseObj.getInt("balance");
						if(balanceAfter == balanceResult) {
							result.setStatus("SUCCESS");
							result.setMsg("[win] 성공");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							balance = balanceAfter;
						} else {
							result.setStatus("FAIL");
							result.setMsg("[win] 실패: 잔액이 맞지 않습니다.");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							responseData.put("resultList", resultList);
							apiResponse.setData(responseData);
							apiResponse.success();
							return apiResponse;
						}
					} else {
						result.setStatus("FAIL");
						if(resultCode == -99) {
							result.setMsg(responseObj.getString("error_msg"));
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData("");
						} else {
							result.setMsg("[win] 실패");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
						}
						
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						return apiResponse;
					}
					
					Thread.sleep(500);
				}
				
				responseData.put("resultList", resultList);
				
				site.setTestCnt(testCnt+1);
				int updResult = siteService.updateTestCnt(site);

				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;
	}
	
	
	@GetMapping("/testSlot")
    public ApiResponse testSlot(HttpServletRequest request, @RequestHeader String token, @Valid @RequestParam String memberId) throws Exception {
		ApiResponse apiResponse = new ApiResponse();
		
		Site site = siteService.getSiteInfo(request);
		if(site == null) {
			log.error("#-CB::SPD_TEST::testSlot::Authorization apiKey check");
			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("#-CB::SPD_TEST::testSlot::site.getSiteIp("+site.getSiteIp()+"), denied" + IPKit.getIpAddressByRequest(request));
			apiResponse.setResultCode("10001");
			return apiResponse;
		}
		
		if(token == null || token.equals("")) {
			log.error("#-CB::SPD_TEST::testSlot::Authorization apiKey check");
			apiResponse.setResultCode("9999");
			apiResponse.setResultMessage("Authorization token check");
			return apiResponse;
		}
		
		try {
			// TO DO 토큰체크 
			Map responseData = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfo(token);
				final String LOG_PREFIX = "#-CB::SPD_TEST::testSlot::"+tokenInfo.getSid()+"::";
				
				int testCnt = site.getTestCnt();
				if(testCnt > 30) {
					log.error(LOG_PREFIX+ "TEST_COUNT_OVER");
					apiResponse.setResultCode("9999");
					apiResponse.setResultMessage("TEST_COUNT_OVER");
					return apiResponse;
				}
				
				// 여기서 부터 로직
				List<CallbackTestResult> resultList = new ArrayList<>();
				
				int balance = 0;
				int betAmt = 100;
				int winAmt = 100;
				
				JSONObject requestBody = new JSONObject();
				requestBody.put("userId", memberId);
				
				// 유저 잔액 확인.
				JSONObject responseObj = callBackTestService.getBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
				int resultCode = responseObj.getInt("result_code");
				CallbackTestResult result = new CallbackTestResult();
				result.setIndex(0);
				result.setTimeMs(responseObj.getLong("timeMs"));
				responseObj.remove("timeMs");
				
				if(resultCode == 0) {
					result.setStatus("SUCCESS");
					result.setMsg("[balance] 성공");
					result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
					result.setRequestBody(requestBody.toString());
					result.setResponseData(responseObj.toString());
					
					balance = responseObj.getInt("balance");
					
					resultList.add(result);
				} else {
					result.setStatus("FAIL");
					if(resultCode == -99) {
						result.setMsg(responseObj.getString("error_msg"));
						result.setCallbackUrl(site.getSiteCbUrl()+"/balance");
						result.setRequestBody(requestBody.toString());
						result.setResponseData("");
					} else {
						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;
				}
				
				Thread.sleep(500);
				
				
				// 베팅 - 결과 테스트 진행
				// 1. 랜점한 betId 10개 생성.
				List<String> betIds = generateRandomStrings(20, 20);
				
				// 2. 베팅-결과 콜백 10번 진행.
				for (int i = 0; i < 20; i += 2) {
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
					long ctms = System.currentTimeMillis();
					String betId = "B"+site.getSiteIdx()+"_"+betIds.get(i)+"_"+memberId;
					String debitTranId = "D"+site.getSiteIdx()+"_"+ctms+"_"+memberId;
					String creditTranId = "C"+site.getSiteIdx()+"_"+ctms+"_"+memberId;
					
					// 2-1 call bet
					requestBody = new JSONObject();
					requestBody.put("betId", betId);
					requestBody.put("tranId", debitTranId);
					requestBody.put("userId", memberId);
					requestBody.put("vendorIdx", 17);
					requestBody.put("vendorKey", "S02");
					requestBody.put("vendor", "svendor");
					requestBody.put("gameIdx", 17);
					requestBody.put("gameKey", "와일드 웨스트 골드");
					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 = callBackTestService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
					resultCode = responseObj.getInt("result_code");
					result = new CallbackTestResult();
					result.setIndex(i+1);
					result.setTimeMs(responseObj.getLong("timeMs"));
					responseObj.remove("timeMs");
					
					if(resultCode == 0) {
						int balanceAfter = balance - betAmt;
						int balanceResult = responseObj.getInt("balance");
						if(balanceAfter == balanceResult) {
							result.setStatus("SUCCESS");
							result.setMsg("[bet] 성공");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							balance = balanceAfter;
						} else {
							result.setStatus("FAIL");
							result.setMsg("[bet] 실패: 잔액이 맞지 않습니다.");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							responseData.put("resultList", resultList);
							apiResponse.setData(responseData);
							apiResponse.success();
							return apiResponse;
						}
					} else {
						result.setStatus("FAIL");
						if(resultCode == -99) {
							result.setMsg(responseObj.getString("error_msg"));
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData("");
						} else {
							result.setMsg("[bet] 실패");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
						}
						
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						return apiResponse;
					}
					
					Thread.sleep(100);
					
					// 2-2 call win
					requestBody = new JSONObject();
					requestBody.put("betId", betId);
					requestBody.put("tranId", creditTranId);
					requestBody.put("userId", memberId);
					requestBody.put("vendorIdx", 17);
					requestBody.put("vendorKey", "S02");
					requestBody.put("vendor", "svendor");
					requestBody.put("gameIdx", 17);
					requestBody.put("gameKey", "와일드 웨스트 골드");
					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 = callBackTestService.changeBalance(LOG_PREFIX, site.getSiteCbUrl(), requestBody);
					resultCode = responseObj.getInt("result_code");
					result = new CallbackTestResult();
					result.setIndex(i+2);
					result.setTimeMs(responseObj.getLong("timeMs"));
					responseObj.remove("timeMs");
					
					if(resultCode == 0) {
						int balanceAfter = balance + winAmt;
						int balanceResult = responseObj.getInt("balance");
						if(balanceAfter == balanceResult) {
							result.setStatus("SUCCESS");
							result.setMsg("[win] 성공");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							balance = balanceAfter;
						} else {
							result.setStatus("FAIL");
							result.setMsg("[win] 실패: 잔액이 맞지 않습니다.");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
							resultList.add(result);
							
							responseData.put("resultList", resultList);
							apiResponse.setData(responseData);
							apiResponse.success();
							return apiResponse;
						}
					} else {
						result.setStatus("FAIL");
						if(resultCode == -99) {
							result.setMsg(responseObj.getString("error_msg"));
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData("");
						} else {
							result.setMsg("[win] 실패");
							result.setCallbackUrl(site.getSiteCbUrl()+"/changebalance");
							result.setRequestBody(requestBody.toString());
							result.setResponseData(responseObj.toString());
						}
						
						resultList.add(result);
						
						responseData.put("resultList", resultList);
						apiResponse.setData(responseData);
						apiResponse.success();
						return apiResponse;
					}
					
					Thread.sleep(100);
				}
				
				responseData.put("resultList", resultList);
				
				site.setTestCnt(testCnt+1);
				int updResult = siteService.updateTestCnt(site);

				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;
	}
}
