package com.style24.front.support.security.handler;

import java.io.IOException;
import java.util.Base64;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import com.style24.front.biz.service.TsfLoginService;
import com.style24.front.support.env.TsfConstants;
import com.style24.front.support.security.TsfLoginDetails;
import com.style24.front.support.security.session.TsfSession;

import lombok.extern.slf4j.Slf4j;

import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.util.GagaCookieUtil;
import com.gagaframework.web.util.GagaCryptoUtil;
import com.gagaframework.web.util.GagaDateUtil;
import com.gagaframework.web.util.GagaStringUtil;

/**
 * 로그인 성공 시 호출되는 Handler
 * 
 * @author gagamel
 * @since 2020. 9. 11
 */
@Slf4j
public class TsfLoginSuccessHandler implements AuthenticationSuccessHandler {

	// 로그인 후 메인으로 이동할 페이지 목록
	private final String[] pagesToMain = new String[] {
		"/customer/join/form",				// 회원가입
		"/customer/sns/join/form",			// SNS 회원가입
		"/customer/id/find/form",			// 아이디찾기
		"/customer/id/find/result/form",	// 아이디찾기
		"/customer/pwd/find/form",			// 비밀번호찾기
		"/customer/pwd/find/result/form",	// 비밀번호완료
		"/customer/join/complete/form"		// 회원가입완료
	};

	@Autowired
	private TsfLoginService loginService;

//	@Autowired
//	private FoCustomerService customerService;

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
		// 로그인 상세 정보
		TsfLoginDetails loginDetails = (TsfLoginDetails)authentication.getDetails();

		// 로그인 성공 시 로그인실패수가 0보다 크면 로그인실패수 reset
		Integer custNo = loginDetails.getLoginInfo().getCustNo();
		int failCnt = loginService.getLoginFailCount(custNo);
		if (failCnt > 0) {
			loginService.createLoginFail(loginDetails.getLoginInfo().getCustId(), "N");
		}

		// 최종로그인일시 Update
		loginService.updateLastLoginDate(custNo);

		// 로그인이력 생성
		loginService.createLoginHistory(custNo);

		// 세션 생성
		this.createSession(request, loginDetails);

		// 자동로그인용 RememberMe 쿠키 및 토큰 생성
		if (request.getParameter("rememberMe") != null && request.getParameter(TsfConstants.REMEMBER_ME_PARAMETER).equals("true")) {
			Date expiry = new Date(System.currentTimeMillis() + (1000 * TsfConstants.REMEMBER_ME_LIMIT));
			String md5HexToken = GagaCryptoUtil.encryptMD5(custNo + ":" + GagaDateUtil.getDate(expiry, "yyyyMMddHHmmss") + ":" + TsfSession.getSessionId());
			String remembermeToken = Base64.getEncoder().encodeToString((TsfConstants.REMEMBER_ME_KEY + ":" + md5HexToken).getBytes());

			// RememberMe 쿠키 생성
			GagaCookieUtil.setSecureCookie(response, TsfConstants.CK_PREFIX + "_remember-me", remembermeToken, TsfConstants.REMEMBER_ME_LIMIT);

			// 로그인유지토큰 생성
			loginService.createPersistentToken(custNo, remembermeToken, expiry);
		}

//		String isApp = FoSession.getAttribute("isApp");
//		if ("true".equals(isApp)) {
//			customerService.giveFirstAppDownPoint(loginDetails.getUsername());
//		}

		String returnUrl = GagaCookieUtil.getCookie(request, TsfConstants.CK_PREFIX + "_return_url");
		log.info("returnUrl: {}", returnUrl);

		// 회원가입, 아이디찾기, 비밀번호찾기, 회원가입완료 페이지에서 로그인 했으면 메인으로 이동
		// 그 외는 RETURN URL로 이동
		if (StringUtils.isNotEmpty(returnUrl)) {
			for (String page : pagesToMain) {
				if (returnUrl.indexOf(page) > -1) {
					returnUrl = "/";
					break;
				}
			}
		} else {
			returnUrl = "/";
		}

		GagaMap result = new GagaMap();
		result.setString("status", "OK");
		result.setString("returnUrl", returnUrl);
		result.setString("custNo", loginDetails.getUsername()); // 로그인 후 APP푸시SDK 연동을 위해

		GagaStringUtil.write(response, result);
	}

	/**
	 * Session 생성
	 * @param request - HttpServletRequest
	 * @param loginDetails - 로그인 상세 정보
	 */
	private void createSession(HttpServletRequest request, TsfLoginDetails loginDetails) {
		HttpSession session = request.getSession(true);
		session.setMaxInactiveInterval(1800);
		session.setAttribute("session", loginDetails);
	}

}
