package kr.co.uplus.ez.api.comm;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import kr.co.uplus.ez.api.comm.dto.Auth;
import kr.co.uplus.ez.api.comm.dto.AuthRes;
import kr.co.uplus.ez.api.comm.dto.AuthResDto;
import kr.co.uplus.ez.api.comm.dto.Code;
import kr.co.uplus.ez.api.comm.dto.CodeReqDto;
import kr.co.uplus.ez.api.comm.dto.CodeRes;
import kr.co.uplus.ez.api.comm.dto.CodeResDto;
import kr.co.uplus.ez.api.comm.dto.Menu;
import kr.co.uplus.ez.api.comm.dto.MenuResDto;
import kr.co.uplus.ez.api.comm.dto.RefreshTokenReqDto;
import kr.co.uplus.ez.api.comm.dto.RefreshTokenResDto;
import kr.co.uplus.ez.common.data.ApiResponseCode;
import kr.co.uplus.ez.common.data.Const;
import kr.co.uplus.ez.common.jwt.JwtService;
import kr.co.uplus.ez.common.utils.CommonUtils;
import kr.co.uplus.ez.common.utils.DateUtil;
import kr.co.uplus.ez.common.utils.SpringUtils;

@Service
public class CommService {

	private final Logger log = LoggerFactory.getLogger(getClass());

	@Autowired
	@Qualifier("sqlSessionTemplateDb1")
	private SqlSessionTemplate sqlSessionMaster;

	@Autowired
	@Qualifier("sqlSessionTemplateDb2")
	private SqlSessionTemplate sqlSessionSlave;

	@Autowired
	private JwtService jwtSvc;
	
	/**
	 * date : 2022. 4. 26.
	 * auth : ckr
	 * desc : 메뉴 목록 조회
	 *
	 * @return MenuResDto
	 */
	public MenuResDto getMenu() {

		CommMapper commMapper = sqlSessionSlave.getMapper(CommMapper.class);

		String currUserRole = SpringUtils.getCurrentUserRole();
		log.debug("currUserRole : {}", currUserRole);
		List<Menu> menuList = commMapper.getMenuByRole(currUserRole);

		Menu root = new Menu();
		Map<Integer, Menu> map = menuList.stream().collect(
				Collectors.toMap(Menu::getMenuNo, Function.identity()));

		for (Menu menu : menuList) {
			Integer prntId = menu.getPrntsMenuNo();
			if (prntId == null || prntId == 0) {
				root.addChild(menu);
			}
			else {
				map.get(prntId).addChild(menu);
			}
		}
		MenuResDto result = new MenuResDto(ApiResponseCode.SUCCESS, root);
		return result;
	}

	/**
	 * date : 2022. 4. 26.
	 * auth : ckr
	 * desc : 공통 코드 조회
	 * @param codeReqDto
	 * @return CodeResDto
	 */
	public CodeResDto getCode(CodeReqDto codeReqDto) {
		// 1.디비 메퍼 정하기
		CommMapper commMapper = sqlSessionSlave.getMapper(CommMapper.class);

		// 2. request 파라미터 벨리데이션 체크 필수값, 데이터 타입

		// 3. 쿼리 조회 메퍼를 통해서 메퍼.xml 데이터 들고오기
		List<Code> codeList = commMapper.getCommCode(codeReqDto);

		// 응답 파라이터
		CodeRes codRes = new CodeRes();
		codRes.setList(codeList);

		// 응답 메시지
		CodeResDto result = new CodeResDto();
		result.setData(codRes);

		return result;
	}

	/**
	 * date : 2022. 4. 26.
	 * auth : ckr
	 * desc : 토큰연장
	 * @param refreshTokenReqDto
	 * @return RefreshTokenResDto
	 */
	public RefreshTokenResDto refreshToken(RefreshTokenReqDto refreshTokenReqDto) {
		// 1. AuthToken 생성.
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if(auth != null) {
			String authToken = jwtSvc.generatePrivateToken(auth);
			// 2. 응답.
			return new RefreshTokenResDto(ApiResponseCode.SUCCESS, authToken);
		}
		// 2. 응답.
		RefreshTokenResDto result = new RefreshTokenResDto(ApiResponseCode.SUCCESS, null);
		return result;
	}

	/**
	 * 권한 코드 조회.
	 *
	 * @return AuthResDto
	 */
	public AuthResDto getAuth(){
		// 1.디비 메퍼 정하기
		CommMapper commMapper = sqlSessionSlave.getMapper(CommMapper.class);

		List<Auth> auths = commMapper.getAuthCode();

		// 응답 파라이터
		AuthRes authRes = new AuthRes();
		authRes.setList(auths);

		// 응답 메시지
		AuthResDto result = new AuthResDto();
		result.setData(authRes);

		return result;
	}
	
	
	/**
	 * date : 2022. 7. 16.
	 * auth : ckr
	 * desc : 권한으로 메뉴 조회
	 * @param role
	 * @return  
	 */
	public Menu getByRoleMenu(String role) {

		CommMapper commMapper = sqlSessionSlave.getMapper(CommMapper.class);
		
		log.debug("role : {}", role);
		List<Menu> menuList = commMapper.getMenuByRole(role);

		Menu root = new Menu();
		Map<Integer, Menu> map = menuList.stream().collect(
				Collectors.toMap(Menu::getMenuNo, Function.identity()));

		for (Menu menu : menuList) {
			Integer prntId = menu.getPrntsMenuNo();
			if (prntId == null || prntId == 0) {
				root.addChild(menu);
			}
			else {
				map.get(prntId).addChild(menu);
			}
		}
		return root;		
	}
	
  	//알림문자 발송테이블
  	public static String WEB_REQ_ID = "WEB_REQ_ID";
  	public  Map<Object, Object> sendMsg(Map<Object, Object> ezMsgMap) {
		
  		CommMapper commMapper = sqlSessionMaster.getMapper(CommMapper.class);
  		// webReqId 채번
  		String prefix = (String) ezMsgMap.get("prefix");
    	String webReqId = prefix + ezMsgMap.get(WEB_REQ_ID);
    	
    	Map<Object, Object> newezMsgMap = new HashMap<Object, Object>();
    	
    	newezMsgMap.put("tableName", Const.LineTpCd.LINE_TP_REAL);
    	newezMsgMap.put("trafficType", Const.LineTpCd.LINE_TP_REAL);
    	String clientKey = generateClientKey("R", 10);
    	newezMsgMap.put("clientKey", clientKey);
    	newezMsgMap.put("reqProduct", "LMS");
    	newezMsgMap.put("msgStatus", "ready");
    	newezMsgMap.put("callbackNumber", "15445992");
    	newezMsgMap.put("phone", ezMsgMap.get("phone"));
    	newezMsgMap.put("webReqId", webReqId);
    	newezMsgMap.put("orderId", "2");
    	newezMsgMap.put("msg", ezMsgMap.get("msg"));
    	
    	commMapper.insertWebMsgCli(newezMsgMap);
    	
		return ezMsgMap ;
		
  	}
  	
  	public  Map<Object, Object> sendMsgHist(Map<Object, Object>msgHistMap) {
  		CommMapper commMapper = sqlSessionMaster.getMapper(CommMapper.class);
  		// webReqId 채번
  		String prefix = (String) msgHistMap.get("prefix");
    	String webReqId = prefix + msgHistMap.get(WEB_REQ_ID);
    	
		//알림 이력 insert
    	Map<Object, Object> newMsgHistMap = new HashMap<Object, Object>();
    	newMsgHistMap.put("userSeq", msgHistMap.get("userSeq"));
    	newMsgHistMap.put("notiSeq", msgHistMap.get("notiSeq"));
    	newMsgHistMap.put("notiMsg", msgHistMap.get("notiMsg"));
    	newMsgHistMap.put("webReqId", webReqId);
    	newMsgHistMap.put("notiDiv", msgHistMap.get("notiDiv"));
    	
    	commMapper.insertNotiHst(newMsgHistMap);
    	
		return msgHistMap;
		
  	}
  	
  	// clientKey 생성
  	public String generateClientKey(String lineTpCdKey, int length) {
		String prefix = DateUtil.getCurrentDate("yyyyMMddHHmmss") + lineTpCdKey;
		String clientKey = "";
		
		clientKey = CommonUtils.getCommonId(prefix, length);
		
		return clientKey;
	}
}