package com.dbnt.kcscbackend.auth;

import com.dbnt.kcscbackend.auth.entity.UserInfo;
import com.dbnt.kcscbackend.auth.service.EgovLoginService;
import com.dbnt.kcscbackend.config.common.BaseController;
import com.dbnt.kcscbackend.auth.entity.LoginVO;
import com.dbnt.kcscbackend.config.common.ResponseCode;
import com.dbnt.kcscbackend.config.common.ResultVO;
import com.dbnt.kcscbackend.config.egov.EgovMessageSource;
import com.dbnt.kcscbackend.config.jwt.EgovJwtTokenUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;

/**
 * 일반 로그인을 처리하는 컨트롤러 클래스
 * @author 공통서비스 개발팀 박지욱
 * @since 2009.03.06
 * @version 1.0
 * @see
 *
 * <pre>
 * << 개정이력(Modification Information) >>
 *
 *  수정일      수정자      수정내용
 *  -------            --------        ---------------------------
 *  2009.03.06  박지욱     최초 생성
 *  2011.08.31  JJY            경량환경 템플릿 커스터마이징버전 생성
 *
 *  </pre>
 */

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
@Tag(name="EgovLoginApiController",description = "로그인 관련")
public class EgovLoginApiController extends BaseController {

	/** EgovLoginService */
	@Resource(name = "loginService")
	private EgovLoginService loginService;

	private final EgovJwtTokenUtil egovJwtTokenUtil;

	/** EgovMessageSource */
	@Resource(name = "egovMessageSource")
	EgovMessageSource egovMessageSource;
	
	/** JWT */
	@Autowired
	private EgovJwtTokenUtil jwtTokenUtil;


	@Operation(
			summary = "회원가입",
			description = "회원가입",
			tags = {"EgovLoginApiController"}
	)
	@ApiResponses(value = {
			@ApiResponse(responseCode = "200", description = "가입 성공"),
			@ApiResponse(responseCode = "300", description = "가입 실패")
	})
	@PostMapping(value = "/join")
	public HashMap<String, Object> actionJoin(@RequestBody @Valid LoginVO loginVO, Errors errors, HttpServletRequest request) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		if(errors.hasErrors()){
			StringBuilder msg = new StringBuilder();
			for(FieldError error: errors.getFieldErrors()){
				msg.append(error.getDefaultMessage());
				msg.append("\n");
			}
			resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
			resultMap.put("resultMessage", msg.toString());
		}else if(!loginVO.getPassword().equals(loginVO.getPasswordChk())){
			resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
			resultMap.put("resultMessage", "비밀번호 확인이 잘못 입력되었습니다.");
		}else{
			Integer insertResult = loginService.insertUser(loginVO);

			if(insertResult!=null){
				if(insertResult==-1){
					resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
					resultMap.put("resultMessage", "사용중인 아이디입니다.");
				}else if(insertResult==-2){
					resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
					resultMap.put("resultMessage", "가입된 이메일입니다.");
				}else{
					resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
					resultMap.put("resultMessage", "저장 되었습니다.");
				}
			}else{
				resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
				resultMap.put("resultMessage", "저장에 실패하였습니다.");
			}
		}
		return resultMap;
	}

	@Operation(
			summary = "아이디 찾기",
			description = "아이디 찾기",
			tags = {"EgovLoginApiController"}
	)
	@ApiResponses(value = {
			@ApiResponse(responseCode = "200", description = "조회 성공"),
			@ApiResponse(responseCode = "300", description = "조회 실패")
	})
	@PostMapping(value = "/findId")
	public HashMap<String, Object> findId(@RequestBody LoginVO loginVO) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();

		String userId = loginService.selectEmail(loginVO);
		if(userId!=null){
			userId = userId.substring(0, userId.length()-3)+"***";
			resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
			resultMap.put("resultMessage", "아이디는 "+userId+" 입니다.");
		}else{
			resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
			resultMap.put("resultMessage", "이메일 조회에 실패하였습니다.");
		}
		return resultMap;
	}

	@Operation(
			summary = "비밀번호 찾기",
			description = "비밀번호 찾기",
			tags = {"EgovLoginApiController"}
	)
	@ApiResponses(value = {
			@ApiResponse(responseCode = "200", description = "조회 성공"),
			@ApiResponse(responseCode = "300", description = "조회 실패")
	})
	@PostMapping(value = "/findPw")
	public HashMap<String, Object> findPw(@RequestBody LoginVO loginVO) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();

		String password = loginService.updateTempPassword(loginVO);
		if(password!=null){
			resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
			resultMap.put("resultMessage", "비밀번호가 발급되었습니다.\n 새 비밀번호: "+password);
		}else{
			resultMap.put("resultCode", ResponseCode.SAVE_ERROR.getCode());
			resultMap.put("resultMessage", "조회에 실패하였습니다.");
		}
		return resultMap;
	}

	@RequestMapping("/accessTokenRefresh")
	public HashMap<String, Object> accessTokenRefresh(HttpServletRequest request, HttpServletResponse response, @AuthenticationPrincipal UserInfo loginVO){
		HashMap<String, Object> resultMap = new HashMap<>();
		String token = egovJwtTokenUtil.accessTokenRefresh(request.getHeader("Authorization"));
		if(token!=null){
			resultMap.put("resultCode", ResponseCode.SUCCESS.getCode());
			resultMap.put("accessToken", token);
		}else{
			resultMap.put("resultCode", ResponseCode.AUTH_ERROR.getCode());
		}
		return resultMap;
	}

	@RequestMapping("/loginSuccess")
	public HashMap<String, Object> loginSuccess(HttpServletRequest request, HttpServletResponse response){
		return new HashMap<>();
	}
}