/**
 * date : 2022. 4. 25.
 * auth : ckr
 * desc : 시스템관리
 */
package kr.co.uplus.ez.api.sysMgt;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import kr.co.uplus.ez.api.homeMgt.dto.NoticeListReqDto;
import kr.co.uplus.ez.api.sysMgt.dto.*;
import kr.co.uplus.ez.common.components.ValidComponents;
import kr.co.uplus.ez.common.components.WebClientRequestService;
import kr.co.uplus.ez.common.data.ApiResponseCode;
import kr.co.uplus.ez.common.data.Const;
import springfox.documentation.spring.web.json.Json;

import org.apache.http.HttpStatus;
import org.apache.http.protocol.HTTP;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 시스템 관리 Controller.
 *
 * @author rejoice
 *
 */
@RestController
@RequestMapping(value = "api/v1/bo/sysMgt")
public class SysMgtController {

	private static final Logger logger = LoggerFactory.getLogger(SysMgtController.class);
	
	@Autowired
	private WebClientRequestService clientRequestService;

	@Autowired
	SysMgtService sysService;

	@Autowired
	ValidComponents validComponents;
	
	
	@Value("${msghubez.batch-url:http://localhost:7070}")
	private String batchDomain;
	
	@Value("${msghubez.uri.batchExecuteJob:/executeJob}")
	private String executeJob;
	

	/**
	 * date : 2022. 4. 25. auth : ckr desc : HUBEZ_BO_API_4001 - 관리자 목록 조회.
	 *
	 * @param adminListReqDto
	 * @return AdminListResDto
	 */
	@ApiOperation(value = "adminList", notes = "관리자 목록 조회")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "adminList", method = { RequestMethod.POST })
	@ResponseBody
	public AdminListResDto adminList(@RequestBody @Valid AdminListReqDto adminListReqDto, BindingResult bindingResult, HttpServletResponse response) {

		if (validComponents.validParameter(bindingResult)) {
			return new AdminListResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		
		return sysService.adminList(adminListReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : HUBEZ_BO_API_4001 - 마당ID 조회.
	 *
	 * @return SearchMadangIdResDto
	 */
	@ApiOperation(value = "madangId", notes = "마당ID 조회")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "madangId", method = { RequestMethod.POST })
	@ResponseBody
	public SearchMadangIdResDto searchMadangId(@RequestBody @Valid SearchMadangIdReqDto searchMadangIdReqDto,
			BindingResult bindingResult) {
		if (validComponents.validParameter(bindingResult)) {
			return new SearchMadangIdResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		return sysService.searchMadangId(searchMadangIdReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : HUBEZ_BO_API_4003 - 관리자 등록.
	 *
	 * @param insertAdminReqDto
	 * @return InsertAdminResDto
	 */
	@ApiOperation(value = "insertAdmin", notes = "관리자 등록")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "insertAdmin", method = { RequestMethod.POST })
	@ResponseBody
	public InsertAdminResDto insertAdmin(@RequestBody @Valid InsertAdminReqDto insertAdminReqDto,
			BindingResult bindingResult) {

		if (validComponents.validParameter(bindingResult)) {
			return new InsertAdminResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}

		return sysService.insertAdmin(insertAdminReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : HUBEZ_BO_API_4004 - 관리자 수정.
	 *
	 * @param updateAdminReqDto
	 * @return UpdateAdminResDto @
	 */
	@ApiOperation(value = "updateAdmin", notes = "관리자 수정")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "updateAdmin", method = { RequestMethod.POST })
	@ResponseBody
	public UpdateAdminResDto updateAdmin(@RequestBody @Valid UpdateAdminReqDto updateAdminReqDto,
			BindingResult bindingResult) {

		if (validComponents.validParameter(bindingResult)) {
			return new UpdateAdminResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}

		return sysService.updateAdmin(updateAdminReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : HUBEZ_BO_API_4005 - 관리자 삭제.
	 *
	 * @param deleteAdminReqDto
	 * @return DeleteAdminResDto @
	 */
	@ApiOperation(value = "deleteAdmin", notes = "관리자 삭제")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "deleteAdmin", method = { RequestMethod.POST })
	@ResponseBody
	public DeleteAdminResDto deleteAdmin(@RequestBody @Valid DeleteAdminReqDto deleteAdminReqDto,
			BindingResult bindingResult) {

		if (validComponents.validParameter(bindingResult)) {
			return new DeleteAdminResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}

		return sysService.deleteAdmin(deleteAdminReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : HUBEZ_BO_API_4006 - 관리자 정보 상세 조회.
	 *
	 * @param adminDetailReqDto
	 * @return AdminDetailResDto @
	 */
	@ApiOperation(value = "adminDetail", notes = "관리자 정보 상세 조회")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "adminDetail", method = { RequestMethod.POST })
	@ResponseBody
	public AdminDetailResDto adminDetail(@RequestBody @Valid AdminDetailReqDto adminDetailReqDto,
			BindingResult bindingResult) {

		if (validComponents.validParameter(bindingResult)) {
			return new AdminDetailResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}

		return sysService.adminDetail(adminDetailReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : 권한 목록 조회
	 *
	 * @param paramMap
	 * @return @
	 */
	@ApiOperation(value = "authList", notes = "권한 목록 조회")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "authList", method = { RequestMethod.POST })
	@ResponseBody
	public AuthListResDto authList(@RequestBody Map<String, Object> paramMap) {
		return sysService.authList(paramMap);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : 권한 삭제
	 *
	 * @param deleteAuthReqDto
	 * @return @
	 */
	@RequestMapping(value = "/deleteAuth", method = { RequestMethod.POST })
	@ResponseBody
	public DeleteAuthResDto deleteAuth(@RequestBody @Valid DeleteAuthReqDto deleteAuthReqDto,
			BindingResult bindingResult) {
		if (validComponents.validParameter(bindingResult)) {
			return new DeleteAuthResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		return sysService.deleteAuth(deleteAuthReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : 권한 상세 조회
	 *
	 * @param authDetailReqDto
	 * @return @
	 */
	@RequestMapping(value = "/authDetail", method = { RequestMethod.POST })
	@ResponseBody
	public AuthDetailResDto authDetail(@RequestBody @Valid AuthDetailReqDto authDetailReqDto,
			BindingResult bindingResult) {
		if (validComponents.validParameter(bindingResult)) {
			return new AuthDetailResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		return sysService.authDetail(authDetailReqDto);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : 권한 추가
	 *
	 * @param insertAuthReqDto
	 * @return @
	 */
	@RequestMapping(value = "/insertAuth", method = { RequestMethod.POST })
	@ResponseBody
	public InsertAuthResDto insertAuth(@RequestBody @Valid InsertAuthReqDto insertAuthReqDto,
			BindingResult bindingResult) {
		if (validComponents.validParameter(bindingResult)) {
			return new InsertAuthResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		UserDetails userDetails = (UserDetails) principal;

		String regId = userDetails.getUsername();

		return sysService.insertAuth(insertAuthReqDto, regId);
	}

	/**
	 * date : 2022. 4. 25. auth : ckr desc : 권한 수정
	 *
	 * @param updateAuthReqDto
	 * @return @
	 */
	@RequestMapping(value = "/updateAuth", method = { RequestMethod.POST })
	@ResponseBody

	public UpdateAuthResDto updateAuth(@RequestBody @Valid UpdateAuthReqDto updateAuthReqDto,
			BindingResult bindingResult) {
		if (validComponents.validParameter(bindingResult)) {
			return new UpdateAuthResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		UserDetails userDetails = (UserDetails) principal;

		String regId = userDetails.getUsername();

		return sysService.updateAuth(updateAuthReqDto, regId);
	}
	
	
	/**
	 * data: 2022. 10.24.
	 * auth: Lee
	 * desc: 배치 리스트 조회.
	 * @return
	 */
	@ApiOperation(value = "batchList", notes = "배치 리스트 조회")
	@RequestMapping(value = "/batchList", method = {RequestMethod.POST})
	@ResponseBody
	public BatchListResDto batchList() {
		return sysService.batchList();
	}

	/**
	 * date : 2022. 10. 26
	 * auth : Lee
	 * desc : 배치 상세내용.
	 * @return
	 */
	@ApiOperation(value = "batchDetail", notes = "배치 상세내용")
	@ApiResponses({ @ApiResponse(code = HttpServletResponse.SC_OK, message = "SUCESS") })
	@RequestMapping(value = "batchDetail", method = {RequestMethod.POST})
	@ResponseBody
	public BatchDetailResDto batchDetail(@RequestBody @Valid BatchDetailReqDto batchDetailReqDto,
			BindingResult bindingResult) {
		
		
		if (validComponents.validParameter(bindingResult)) {
			return new BatchDetailResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		
		return sysService.batchDetail(batchDetailReqDto);
	}
	
	
	/**
	 * date : 2022. 10. 26
	 * auth : Lee
	 * @param batchReqMap
	 * @return
	 */
	@RequestMapping(value = "batchExecuteJob", method = {RequestMethod.POST})
	@ResponseBody
	public BatchExeLogResDto batchExecuteJob(@RequestBody @Valid Map<Object, Object> batchReqMap) {
		
		logger.info("batchReqMap={}",batchReqMap);
		Map<Object, Object> batchResultMap = new HashMap<Object, Object>();
		Map<Object, Object> resultMap = new HashMap<Object, Object>();
		JSONObject jsonObject = new JSONObject();

		String callUrl = batchDomain + executeJob;
		
		String monthBatch = "yyyyMM";
		String dayBatch = "yyyyMMdd";
		String timeBatch = "yyyyMMddHHmmss";
		
		
		SimpleDateFormat monthDateFormat = new SimpleDateFormat(monthBatch);
		SimpleDateFormat dayDateFormat = new SimpleDateFormat(dayBatch);
		SimpleDateFormat timeDateFormat = new SimpleDateFormat(timeBatch);

		logger.info("callUrl={}",callUrl);
		String jobId = (String) batchReqMap.get("batchId");
		String batchType = (String) batchReqMap.get("batchType");
		String strDate = (String) batchReqMap.get("strDate");

		logger.info("batchExecuteJob input Date Check = {}",batchReqMap.get("strDate"));
		logger.debug("확인 batchType={}",batchType);
		
		// 배치 타입 : 일배치, 월배치, 매시간
		if("월배치".equals(batchType)) {
			logger.debug("월배치 batchType={}",batchType);
			try {
				Date date = new SimpleDateFormat("yyyy-MM-dd").parse(strDate);
				strDate = (String)monthDateFormat.format(date);
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}else if("일배치".equals(batchType)) {
			logger.debug("일배치 batchType={}",batchType);
			try {
				Date date = new SimpleDateFormat("yyyy-MM-dd").parse(strDate);
				strDate = (String)dayDateFormat.format(date);
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}		
		}else if("매시간".equals(batchType)) {
			logger.debug("매시간 batchType={}",batchType);
			try {
				Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse(strDate);
				strDate = (String)timeDateFormat.format(date);
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		
		try {

			jsonObject.put("strDate", strDate);
			jsonObject.put("jobId", jobId);
			
			logger.info("jsonObject={}",jsonObject);
			batchResultMap = (Map<Object, Object>) clientRequestService.callBySyncPost(callUrl, jsonObject);
			Map<Object, Object> returnMsg = new HashMap<Object, Object>();
			returnMsg = (Map<Object, Object>) batchResultMap.get("returnMsg");
			
			logger.info("batchResultMap={}",batchResultMap);
			if(batchResultMap == null) {
				resultMap.put("BATCH_RSLT", Const.BATCH_RESULT_FAIL);
				resultMap.put("BATCH_RSLT_MSG", "BATCH Result Recive null error");
			} else {
				if("02".equals(returnMsg.get("code"))) {
					resultMap.put("BATCH_RSLT", Const.BATCH_RESULT_SUCCESS);
					resultMap.put("BATCH_RSLT_MSG", returnMsg.get("msg"));
				} else {
					resultMap.put("BATCH_RSLT", Const.BATCH_RESULT_FAIL);
					resultMap.put("BATCH_RSLT_MSG", returnMsg.get("msg"));
				}
				resultMap.putAll(batchResultMap);
			}
		} catch (Exception e) {
			logger.error("mhez-batch fail : {}", e.getMessage(),e);
			resultMap.put("BATCH_RSLT", Const.BATCH_RESULT_FAIL);
			resultMap.put("BATCH_RSLT_MSG", e.getMessage());
		}
		
		logger.info("getChannel start : {}", callUrl);
		logger.info("jsonObject: {}",jsonObject);
		logger.info("resultMap: {}",resultMap);
		
		
		return new BatchExeLogResDto(ApiResponseCode.SUCCESS,resultMap);
		
	}
	
	/**
	 * data: 2022. 11.23.
	 * auth: Lee minha
	 * desc: 알림 이력 조회
	 * @return
	 */
	@ApiOperation(value = "notiList", notes = "알림 이력 조회")
	@RequestMapping(value = "/notiList", method = {RequestMethod.POST})
	@ResponseBody
	public NotiListResDto notiList(@RequestBody @Valid NotiListReqDto notiListReqDto) {
		
		logger.info("Start notiList controller");
		return sysService.notiList(notiListReqDto);
	}
	
	@RequestMapping(value = "/setWorkState", method = {RequestMethod.POST})
	@ResponseBody
	public SetWorkStateResDto setWorkState(@RequestBody @Valid SetWorkStateReqDto setWorkParam, BindingResult bindingResult) {
	
		if (validComponents.validParameter(bindingResult)) {
			return new SetWorkStateResDto(ApiResponseCode.CM_PARAMETER_ERROR);
		}
		
		return sysService.setWorkState(setWorkParam);
	}
	
	/**
	 * data: 2023. 05.09.
	 * auth: won
	 * desc: 서비스 점검 이력 조회
	 * @return
	 */
	@ApiOperation(value = "svcCheckList", notes = "서비스 점검 이력 조회")
	@RequestMapping(value = "/svcCheckList", method = {RequestMethod.POST})
	@ResponseBody
	public SvcCheckListResDto svcCheckList(@RequestBody @Valid SvcCheckListReqDto svcCheckListReqDto) {
		return sysService.svcCheckLists(svcCheckListReqDto);
	
	}
}
