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

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

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.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import com.style24.front.biz.service.TsfCartService;
import com.style24.front.biz.service.TsfLoginService;
import com.style24.front.biz.service.TsfRecentlyGoodsService;
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/pwd/find/form",				// 아이디/비밀번호 찾기
		"/customer/password/find/form",				// 비밀번호찾기
		"/customer/password/change/form",			// 비밀번호 변경 화면
		"/customer/join/complete/form",				// 회원가입완료
		"/customer/join/type/form",					// 회원가입유형
		"/customer/dormant/certify/form",			// 휴면해제화면
		"/customer/dormant/certify/complete/form",	// 휴면해제완료
		"/customer/certification/form",				// 본인인증화면
		"/customer/noncust/order/confirm/form",		// 비회원주문화면
		"/customer/nice/ipin/form",					// 나이스인증화면
		"/customer/nice/cellphone/form",			// 휴대폰인증화면
		"/customer/consent/useinfo/form"			// YES24동의화면
	};

	private static final int CHANG_PWD_CAMPAIGN_DAY = 90;	// 비밀번호 변경 캠페인일자

	private static final String CHANG_TEMP_PWD = "Y";	//임시비밀번호여부

	private static final String GOODS_DETAIL_FORM = "/goods/detail/form";	// 주문상세 URL

	@Autowired
	private TsfLoginService loginService;

	@Autowired
	private TsfCartService cartService;

	@Autowired
	private TsfRecentlyGoodsService recentlyGoodsService;

	@Value("${has-ssl}")
	private String hasSsl;

	@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(loginDetails.getLoginInfo().getCustId());
		if (failCnt > 0) {
			loginService.createLoginFail(loginDetails.getLoginInfo().getCustId(), "N");
		}

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

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

		// 장바구니 번호
		String cartSqArr = TsfSession.getAttribute("cartSqArr");

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

		boolean isSslServer = Boolean.parseBoolean(hasSsl);

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

			// RememberMe 쿠키 생성
			if (isSslServer) {
				GagaCookieUtil.setSecureCookie(response, TsfConstants.CK_PREFIX + "_remember-me", remembermeToken, TsfConstants.REMEMBER_ME_LIMIT_SECONDS);
			} else {
				GagaCookieUtil.setCookie(response, TsfConstants.CK_PREFIX + "_remember-me", remembermeToken, TsfConstants.REMEMBER_ME_LIMIT_SECONDS);
			}

			// 로그인유지토큰 생성
			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.isNotBlank(returnUrl)) {
			for (String page : pagesToMain) {
				if (returnUrl.indexOf(page) > -1) {
					returnUrl = "/";
					break;
				}
			}
		} else {
			returnUrl = "/";
		}

		// 로그인 후 장바구니 Update
		cartService.updateCartToAfterLogin(custNo);

		// 로그인 후 최근본상품 Update
		recentlyGoodsService.updateRecentlyGoodsAfterLogin(custNo);

		// 비밀번호 변경 캠페인 일자
		if (loginDetails.getLoginInfo().getPwdChgDay() >= CHANG_PWD_CAMPAIGN_DAY) {
			returnUrl = "/customer/password/campaign/form";
		}

		// 임시비밀번호로 로그인 한 경우
		if (CHANG_TEMP_PWD.equals(loginDetails.getLoginInfo().getTempPasswdYn())) {
			returnUrl = "/customer/password/change/form?pageGb=temp";
		}

		// 상품상세 바로구매 > 로그인 한 경우
		if (returnUrl.indexOf(GOODS_DETAIL_FORM) > -1) {
			if (StringUtils.isNotBlank(cartSqArr)) {
				returnUrl = "/order/noMember?cartSqArr=" + cartSqArr;
			}
		}

//		if (StringUtils.isNotBlank(TsfSession.getAttribute("afLinkCd"))) {
//			returnUrl += (returnUrl.contains("?") ? "&" : "?") + "afLinkCd=" + TsfSession.getAttribute("afLinkCd");
//		}

		if (isSslServer) {
			// 로그인 성공 쿠키로 저장 (마케팅 스크립트용)
			GagaCookieUtil.setSecureCookie(response, TsfConstants.CK_PREFIX + "_login_success", "Y", 1 * 60);
		} else {
			GagaCookieUtil.setCookie(response, TsfConstants.CK_PREFIX + "_login_success", "Y", 1 * 60);
		}

		GagaMap result = new GagaMap();
		result.setString("status", "OK");
		result.setString("returnUrl", returnUrl);
		result.setString("custNo", loginDetails.getUsername()); // 로그인 후 APP푸시SDK 연동을 위해
		if (loginDetails.isLogin()) {
			result.setString("appAgreeYn", loginDetails.getLoginInfo().getAppAgreeYn());
			result.setString("mkAgreeYn", loginDetails.getLoginInfo().getMkAgreeYn());
		}
		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);
	}

}
