package com.apobates.forum.trident.controller.helper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.FlashMapManager;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.support.RequestContextUtils;
import com.apobates.forum.trident.controller.form.RegisteForm;
import com.apobates.forum.utils.Commons;

/**
 * 会员注册邀请码的拦载器
 *
 * @author xiaofanku
 * @since 20200827
 */
public class MemberInviteCodeInterceptorAdapter extends HandlerInterceptorAdapter {
    //是否开启邀请码注册,true[1](开启)验证邀请码,false[0](禁用)不会验证邀请码
    @Value("${site.member.invite}")
    private String activeInviteCode;
    private final static String KEY = "inviteCode";
    private final static Logger logger = LoggerFactory.getLogger(MemberInviteCodeInterceptorAdapter.class);
    
    /**
     * 预处理回调方法，实现处理器的预处理（如检查登陆），第三个参数为响应的处理器，自定义Controller
     * 返回值：true表示继续流程（如调用下一个拦截器或处理器）；false表示流程中断（如登录检查失败），不会继续调用其他的拦截器或处理器，此时我们需要通过response来产生响应；
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws java.lang.Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (activeInviteCode.equalsIgnoreCase("true") && request.getMethod().equalsIgnoreCase("post")) {
            String key = request.getSession().getAttribute("ICInputKey").toString();
            String val = request.getParameter(key);
            if (!Commons.isNotBlank(val)) {
                //throw new InviteCodeLostException("邀请码不存在或已经失效");
                String redirectPath = request.getContextPath() + "/member/register";
                FlashMap flashMap = new FlashMap();
                flashMap.put("errors", "邀请码不存在或已经失效");
                flashMap.put("form", getModelAttributeValue(request));
                flashMap.setTargetRequestPath(redirectPath);
                FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
                flashMapManager.saveOutputFlashMap(flashMap, request, response);
                response.sendRedirect(redirectPath);
                
                return false;
            }
        }
        return true;
    }
    
    /**
     * 后处理回调方法，实现处理器的后处理（但在渲染视图之前），此时我们可以通过modelAndView（模型和视图对象）对模型数据进行处理或对视图进行处理，modelAndView也可能为null。
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws java.lang.Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (activeInviteCode.equalsIgnoreCase("true")) {
            //String rndIN = Commons.randomAlphaNumeric(10);
            request.getSession().setAttribute("ICInputKey", KEY);
            modelAndView.addObject("ICInputActive", true);
            modelAndView.addObject("ICInputName", KEY);
        }
    }
    
    /**
     * 整个请求处理完毕回调方法，即在视图渲染完毕时回调，如性能监控中我们可以在此记录结束时间并输出消耗时间，还可以进行一些资源清理，类似于try-catch-finally中的finally，但仅调用处理器执行链中
     *
     * @Override 
     * public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) throws Exception { 
     *   //request.getSession().removeAttribute("ICInputKey");
     * }
     */
    
    private RegisteForm getModelAttributeValue(HttpServletRequest request){
        RegisteForm rf = new RegisteForm();
        rf.setNames(request.getParameter("names"));
        rf.setNickname(request.getParameter("nickname"));
        rf.setNewPswd(request.getParameter("newPswd"));
        rf.setPswdConfirm(request.getParameter("pswdConfirm"));
        rf.setToken(Commons.randomAlphaNumeric(8));
        return rf;
    }
}
