package com.bb.api;

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.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.ResponseBody;

import com.bb.jwt.JwtManager;
import com.bb.model.ApiResponse;
import com.bb.model.Credit;
import com.bb.model.CreditPointSearch;
import com.bb.model.CreditSearchVO;
import com.bb.model.PageFormVO;
import com.bb.model.Site;
import com.bb.service.CreditService;
import com.bb.service.SiteService;
import com.bb.util.IPKit;
import com.bb.util.PagingUtil;
import com.bb.util.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

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

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

	@Autowired
	SiteService siteService;
	
	@Autowired
	CreditService creditService;
	
	@Autowired
	private final JwtManager jwtManager;
	
	
	@ResponseBody	
	@PostMapping("/list")
    public ApiResponse creditList(@RequestHeader String token, HttpServletRequest request, @RequestBody CreditSearchVO search) 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::CREDIT::creditList::"+tokenInfo.getSid()+"::::";
				
				ObjectMapper objectMapper = new ObjectMapper();
				String reqJsonStr = objectMapper.writeValueAsString(search);
				JSONObject reqObj = new JSONObject(reqJsonStr);
				log.info(LOG_PREFIX+ "Request {}", reqObj);
				
				// 여기서 부터 로직
		    	PageFormVO pageVo= new PageFormVO();
		    	if(search.getSiteIdx() == null || search.getSiteId() == null || search.getSiteId().equals("")) {
		    		search.setSiteId(site.getSiteId());
			    	search.setSiteIdx((long) site.getSiteIdx());
		    	}
		    	
		    	if(search.getOrderStr() == null || search.getOrderStr().equals("")) {
		    		search.setOrderStr("UPDATE_DESC");
		    	}
		    	
		    	search.setTransType(search.getTransType().trim());
		    	
		    	if(search.getTransType().equals("AD-AI") || search.getTransType().equals("AD-AO") || search.getTransType().equals("AD")) {
		    		// 관리자 지급/회수
		    		search.setUpperSiteIdx((long) 2);
		    		search.setUpperSiteId("tripleSuper");
		    		search.setTargetSiteIdx(search.getSiteIdx());
		    		search.setTargetSiteId(search.getSiteId());
		    		
		    		search.setSearchSiteId("");
		    	} else if(search.getTransType().equals("UP-AI") || search.getTransType().equals("UP-AO") || search.getTransType().equals("UP")) {
		    		// 상부가 지급/회수
		    		search.setTargetSiteIdx(search.getSiteIdx());
		    		search.setTargetSiteId(search.getSiteId());
		    	} else if(search.getTransType().equals("DW-AI") || search.getTransType().equals("DW-AO") || search.getTransType().equals("DW")) {
		    		// 하부에 지급/회수
		    		search.setUpperSiteIdx(search.getSiteIdx());
		    		search.setUpperSiteId(search.getSiteId());
		    	} else if(search.getTransType().equals("MAI") || search.getTransType().equals("MAO") || search.getTransType().equals("MAIO")) {
		    		// 회원에 충전/환전
		    		search.setUpperSiteIdx(search.getSiteIdx());
		    		search.setUpperSiteId(search.getSiteId());
		    	} else {
		    		// 전체 검색
		    		search.setUpperSiteIdx(search.getSiteIdx());
		    		search.setUpperSiteId(search.getSiteId());
		    		search.setTargetSiteIdx(search.getSiteIdx());
		    		search.setTargetSiteId(search.getSiteId());
		    	}
		    	
		    	log.info(LOG_PREFIX+ "CreditSearchVO::"+search.toString());
		    	
		    	int totalCount = creditService.getTransCreditListCnt(search);
				if (totalCount != 0) {
					PageFormVO commonForm = new PageFormVO();
					commonForm.setFunction_name("goPage");
					commonForm.setPage(search.getPage());
					commonForm.setCount_per_page(20);
					if(search.getCount_per_list()==0) {
						commonForm.setCount_per_list(30);
					} else {
						commonForm.setCount_per_list(search.getCount_per_list());
					}
					commonForm.setTatal_list_count(totalCount);
					pageVo = PagingUtil.setPageUtil(commonForm);
					search.setLimit(pageVo.getLimit());
					search.setOffset(pageVo.getOffset());
					search.setTatal_list_count(totalCount);
					
					responseData.put("pageInfo", pageVo);
				}
				
				List<HashMap<String, Object>> list = creditService.getTransCreditList(search);
				responseData.put("list", list);
				
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
			apiResponse.setData(responseData);
			apiResponse.success();
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@PostMapping("/transaction")
    public ApiResponse transaction(@RequestHeader String token, HttpServletRequest request, @RequestBody CreditSearchVO search) 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::CREDIT::transaction::"+tokenInfo.getSid()+"::::";
				
				ObjectMapper objectMapper = new ObjectMapper();
				String reqJsonStr = objectMapper.writeValueAsString(search);
				JSONObject reqObj = new JSONObject(reqJsonStr);
				log.info(LOG_PREFIX+ "Request {}", reqObj);
				
				// 여기서 부터 로직
		    	PageFormVO pageVo= new PageFormVO();
		    	if(search.getSiteIdx() == null || search.getSiteId() == null || search.getSiteId().equals("")) {
		    		search.setSiteId(site.getSiteId());
			    	search.setSiteIdx((long) site.getSiteIdx());
		    	}
		    	
		    	if(search.getOrderStr() == null || search.getOrderStr().equals("")) {
		    		search.setOrderStr("UPDATE_DESC");
		    	}
		    	
		    	search.setTransType(search.getTransType().trim());
		    	
		    	search.setStartDatePartition(StringUtils.convertToDateOnly(search.getStartDate()));
		    	search.setEndDatePartition(StringUtils.convertToDateOnly(search.getEndDate()));
		    	
		    	if(search.getTransType().equals("AD-AI") || search.getTransType().equals("AD-AO") || search.getTransType().equals("AD")) {
		    		// 관리자 지급/회수
		    		search.setUpperSiteIdx((long) 2);
		    		search.setUpperSiteId("tripleSuper");
		    		search.setTargetSiteIdx(search.getSiteIdx());
		    		search.setTargetSiteId(search.getSiteId());
		    		
		    		search.setSearchSiteId("");
		    	} else if(search.getTransType().equals("UP-AI") || search.getTransType().equals("UP-AO") || search.getTransType().equals("UP")) {
		    		// 상부가 지급/회수
		    		search.setTargetSiteIdx(search.getSiteIdx());
		    		search.setTargetSiteId(search.getSiteId());
		    	} else if(search.getTransType().equals("DW-AI") || search.getTransType().equals("DW-AO") || search.getTransType().equals("DW")) {
		    		// 하부에 지급/회수
		    		search.setUpperSiteIdx(search.getSiteIdx());
		    		search.setUpperSiteId(search.getSiteId());
		    	} else if(search.getTransType().equals("MAI") || search.getTransType().equals("MAO") || search.getTransType().equals("MAIO")) {
		    		// 회원에 충전/환전
		    		search.setUpperSiteIdx(search.getSiteIdx());
		    		search.setUpperSiteId(search.getSiteId());
		    	} else if(search.getTransType().equals("DP") || search.getTransType().equals("CD") || search.getTransType().equals("CDP")) {
		    		// 회원 베팅/결과
		    		search.setUpperSiteIdx(search.getSiteIdx());
		    		search.setUpperSiteId(search.getSiteId());
		    	} else {
		    		// 전체 검색
		    		search.setUpperSiteIdx(search.getSiteIdx());
		    		search.setUpperSiteId(search.getSiteId());
		    		search.setTargetSiteIdx(search.getSiteIdx());
		    		search.setTargetSiteId(search.getSiteId());
		    	}
		    	
		    	log.info(LOG_PREFIX+ "CreditSearchVO::"+search.toString());
		    	
		    	int totalCount = creditService.getTotalTransactionListCnt(search);
				if (totalCount != 0) {
					PageFormVO commonForm = new PageFormVO();
					commonForm.setFunction_name("goPage");
					commonForm.setPage(search.getPage());
					commonForm.setCount_per_page(20);
					if(search.getCount_per_list()==0) {
						commonForm.setCount_per_list(30);
					} else {
						commonForm.setCount_per_list(search.getCount_per_list());
					}
					commonForm.setTatal_list_count(totalCount);
					pageVo = PagingUtil.setPageUtil(commonForm);
					search.setLimit(pageVo.getLimit());
					search.setOffset(pageVo.getOffset());
					search.setTatal_list_count(totalCount);
					
					responseData.put("pageInfo", pageVo);
				}
				
				List<HashMap<String, Object>> list = creditService.getTotalTransactionList(search);
				responseData.put("list", list);
				
				
			} catch(Exception e) {
				log.info(e.toString());
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
			apiResponse.setData(responseData);
			apiResponse.success();
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@PostMapping("/addProc")
    public ApiResponse addProc(@RequestHeader String token, HttpServletRequest request, @RequestBody Credit credit) 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 data = new HashMap();
			
			try {
				JwtManager.TokenInfo tokenInfo = jwtManager.getTokenInfoAdmin(token);
				final String LOG_PREFIX = "#-API::CREDIT::addProc::"+tokenInfo.getSid()+"::::";
				
				ObjectMapper objectMapper = new ObjectMapper();
				String reqJsonStr = objectMapper.writeValueAsString(credit);
				JSONObject reqObj = new JSONObject(reqJsonStr);
				log.info(LOG_PREFIX+ "Request {}", reqObj);
				
				// 여기서 부터 로직
				if("tripleSuper".equals(site.getSiteId())){
					apiResponse.setResultCode("9991");
					apiResponse.setResultMessage("Super admin is not allow");
					return apiResponse;
				}
				
				if("AI".equals(credit.getCreditType())) {
					// 관리자 or 상부 직접 지급
					long siteCredit = siteService.getSiteCredit(tokenInfo.getSid());
					if(siteCredit < credit.getCreditAmt()) {
						apiResponse.setResultCode("9999");
						apiResponse.setResultMessage("크레딧이 모자릅니다");
						return apiResponse;
			    	}
					
					if(credit.getTargetSiteId() == null || credit.getTargetSiteId().equals("")) {
						apiResponse.setResultCode("9999");
						apiResponse.setResultMessage("대상이 존재하지 않습니다");
						return apiResponse;
					}
					
					credit.setInOut("IN");
			    	credit.setCreditStatus(1);
			    	credit.setSiteIdx(site.getSiteIdx());
			    	credit.setSiteId(site.getSiteId());
			    	
			    	
			    	
				} else if("AO".equals(credit.getCreditType())) {
					// 관리자 or 상부 직접환급
					
					if(credit.getTargetSiteId() == null || credit.getTargetSiteId().equals("")) {
						apiResponse.setResultCode("9999");
						apiResponse.setResultMessage("대상이 존재하지 않습니다");
						return apiResponse;
					}
					
					long targetSiteCredit = siteService.getSiteCredit(credit.getTargetSiteId());
					if(targetSiteCredit < credit.getCreditAmt()) {
						apiResponse.setResultCode("9999");
						apiResponse.setResultMessage("해당 에이젼시의 크레딧이 모자릅니다");
						return apiResponse;
					}
					
					credit.setInOut("OUT");
			    	credit.setCreditStatus(1);
			    	credit.setSiteIdx(site.getSiteIdx());
			    	credit.setSiteId(site.getSiteId());
			    	
				} else {
					apiResponse.setResultCode("9999");
					apiResponse.setResultMessage("알 수 없는 요청");
					return apiResponse;
				}
				
				log.info(LOG_PREFIX+ "Credit::AF::"+credit.toString());
				
				int result = creditService.insertCredit(credit);
				
				
				log.info(LOG_PREFIX+ "insertCredit result::"+result);
				
				
			} catch(Exception e) {
				log.error(e.toString());
				e.printStackTrace();
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
			apiResponse.setData(data);
			apiResponse.success();
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@PostMapping("/pointList")
    public ApiResponse pointList(@RequestHeader String token, HttpServletRequest request, @Valid @RequestBody CreditPointSearch search) 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::TRANS::betlist::"+tokenInfo.getSid()+"::::";
				
				// 여기서 부터 로직
		    	
		    	PageFormVO pageVo = new PageFormVO();	    	
		    	search.setSearchSiteId(site.getSiteId());
		    	search.setSearchSiteIdx((long) site.getSiteIdx());
		    	search.setStartDate(search.getStartDate()+".000");
		    	search.setEndDate(search.getEndDate()+".999");
		    	
		    	if(search.getOrderStr() == null || search.getOrderStr().equals("")) {
		    		search.setOrderStr("BETDATE_DESC");
		    	}
		    	
		    	log.info(LOG_PREFIX+ "CreditPointSearch::"+search.toString());
		    	
	    		int totalCount = creditService.getCreditPointListCnt(search);
				if (totalCount != 0) {
					PageFormVO commonForm = new PageFormVO();
					commonForm.setFunction_name("goPage");
					commonForm.setPage(search.getPage());
					commonForm.setCount_per_page(20);
					if(search.getCount_per_list()==0) {
						commonForm.setCount_per_list(30);
					} else {
						commonForm.setCount_per_list(search.getCount_per_list());
					}
					commonForm.setTatal_list_count(totalCount);
					pageVo = PagingUtil.setPageUtil(commonForm);
					search.setLimit(pageVo.getLimit());
					search.setOffset(pageVo.getOffset());
					search.setTatal_list_count(totalCount);
					
					responseData.put("pageInfo", pageVo);
				}
				
				List<HashMap<String, String>> list = creditService.getCreditPointList(search);
				responseData.put("list", list);
				
			} catch(Exception e) {
				log.info(e.toString());
				e.printStackTrace();
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
			apiResponse.setData(responseData);
			apiResponse.success();
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
	
	
	@ResponseBody	
	@PostMapping("/betList")
    public ApiResponse betList(@RequestHeader String token, HttpServletRequest request, @Valid @RequestBody CreditPointSearch search) 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::TRANS::betlist::"+tokenInfo.getSid()+"::::";
				
				// 여기서 부터 로직
		    	
		    	PageFormVO pageVo = new PageFormVO();	    	
		    	search.setSearchSiteId(site.getSiteId());
		    	search.setSearchSiteIdx((long) site.getSiteIdx());
		    	search.setStartDate(search.getStartDate()+".000");
		    	search.setEndDate(search.getEndDate()+".999");
		    	
		    	if(search.getOrderStr() == null || search.getOrderStr().equals("")) {
		    		search.setOrderStr("BETDATE_DESC");
		    	}
		    	
		    	log.info(LOG_PREFIX+ "CreditPointSearch::"+search.toString());
		    	
		    	search.setStartDatePartition(StringUtils.convertToDateOnly(search.getStartDate()));
		    	search.setEndDatePartition(StringUtils.convertToDateOnly(search.getEndDate()));
		    	
	    		int totalCount = creditService.getCreditBetListCnt(search);
				if (totalCount != 0) {
					PageFormVO commonForm = new PageFormVO();
					commonForm.setFunction_name("goPage");
					commonForm.setPage(search.getPage());
					commonForm.setCount_per_page(20);
					if(search.getCount_per_list()==0) {
						commonForm.setCount_per_list(30);
					} else {
						commonForm.setCount_per_list(search.getCount_per_list());
					}
					commonForm.setTatal_list_count(totalCount);
					pageVo = PagingUtil.setPageUtil(commonForm);
					search.setLimit(pageVo.getLimit());
					search.setOffset(pageVo.getOffset());
					search.setTatal_list_count(totalCount);
					
					responseData.put("pageInfo", pageVo);
				}
				
				List<HashMap<String, String>> list = creditService.getCreditBetList(search);
				responseData.put("list", list);
				
			} catch(Exception e) {
				log.info(e.toString());
				e.printStackTrace();
				apiResponse.setResultCode("99995");
				apiResponse.setResultMessage("token is no valid");
				return apiResponse;
			}
			
			apiResponse.setData(responseData);
			apiResponse.success();
			
		} catch (Exception e) {
			e.printStackTrace();
			apiResponse.fail();
		}
		
		return apiResponse;
	}
}
