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

import java.util.Optional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.apobates.forum.trident.controller.form.LoginForm;
import com.apobates.forum.event.elderly.MemberActionDescriptor;
import com.apobates.forum.member.api.service.MemberService;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.storage.OnlineMemberStorage;
import com.apobates.forum.member.storage.core.MemberSessionBean;
import com.apobates.forum.utils.Commons;
import com.github.jscookie.javacookie.Cookies;
/**
 * 主控制器
 * 
 * @author xiaofanku@live.cn
 * @since 20190321
 */
@Controller
@RequestMapping(value = "/admin")
public class HomeController {
	@Autowired
	private MemberService memberService;
	@Autowired
	private OnlineMemberStorage onlineMemberStorage;
	@Value("${site.admin.path}")
	private String adminDomain;
	private final static Logger logger = LoggerFactory.getLogger(HomeController.class);

	// 跳转到版块首页
	@GetMapping(path="/")
	public String home(
			@RequestParam(value = "from", required = false, defaultValue = "") String fromPath,
			MemberSessionBean mbean, 
			HttpServletRequest request,
			Model model) {
		try{
			// 在线的状态下无需登录
			if (mbean.isOnline() && MemberRoleEnum.ADMIN == mbean.getRole()) {
				return "redirect:/admin/client";
			}
		}catch(NullPointerException e){}
		//
		LoginForm form = new LoginForm();
		String A = Commons.isNotBlank(fromPath) ? fromPath : Commons.getNativeURL(request.getHeader("referer"), adminDomain, "/admin/client");
		form.setRedirect(A);
		form.setLexical("tmp" + Commons.randomAlphaNumeric(12));
		form.setToken(Commons.randomAlphaNumeric(8));
		model.addAttribute("form", form);
		return "admin/member/login";
	}

	// 登录
	@PostMapping(path="/")
	public String login(
			@ModelAttribute("form") LoginForm form, 
			HttpServletRequest request,
			HttpServletResponse response, 
			Model model) {
		String errMsg=null;Member m=null;
		try{
			Optional<Member> rm = memberService.signIn(form.getNames(), form.getPswd(), true, MemberActionDescriptor.getInstance(request, form.getToken()));
			if (!rm.isPresent()) {
				errMsg="会员不存在或密码错误";
			}else{
				m=rm.get();
			}
		}catch(IllegalStateException e){
			errMsg=e.getMessage();
		}
		if(null == m){
			form.setToken(Commons.randomAlphaNumeric(8));
			model.addAttribute("form", form);
			//
			model.addAttribute("errors", errMsg);
			return "admin/member/login";
		}
		MemberSessionBean mbean = new MemberSessionBean(m, form.getRequestIpAddr(request));
		
		onlineMemberStorage.store(mbean, request, response);
		// ----------------------------------------清除客户端缓存的cookie标记,重新拉取@20200502
		if(Commons.isNotBlank(form.getTrace())){
			emptyTraceForCookie(form.getTrace(), "admin.login", request, response);
		}
		return "redirect:/admin/client";
	}

	// 根据组不同显示不同的欢迎界面
	@GetMapping(path = "/client")
	public String clientMain(MemberSessionBean mbean, HttpServletRequest request, HttpSession session, Model model) {
		return "redirect:/admin/starter";
	}
	@GetMapping(path = "/starter")
	public String welcome(HttpServletRequest request, Model model) {
		return "admin/starter";
	}
	// 退出系统
	@GetMapping(path="/offline.xhtml")
	public String signout(
			@RequestParam(value = "trace", required = false, defaultValue = "")String cookieTraceKey, 
			MemberSessionBean mbean, 
			HttpServletRequest request, 
			HttpServletResponse response,
			HttpSession session, 
			Model model) {
		if (mbean.isOnline()) {
			session.invalidate();
			// ----------------------------------------移除Cookie
			onlineMemberStorage.delete(request, response);
			// ----------------------------------------清除客户端缓存的cookie标记,重新拉取@20200502
			if(Commons.isNotBlank(cookieTraceKey)){
				emptyTraceForCookie(cookieTraceKey, "admin.offline", request, response);
			}
		}
		return "admin/member/logout";
	}
	/**
	 * 清除客户端缓存的cookie标记,重新拉取一次@20200502<br/>
	 * 需要js-cookie的服务器端依赖<br/>
	 * [有重复]MemberController.emptyTraceForCookie
	 * {@link https://github.com/js-cookie/java-cookie}
	 * {@link https://github.com/js-cookie/js-cookie/blob/master/SERVER_SIDE.md}
	 * @param cookieKey js-cookie设置的cookie key, 客户端缓存的cookie标记
	 * @param source    来自哪个方法
	 * @param request   http请求对象
	 * @param response  http响应对象
	 */
	private void emptyTraceForCookie(String cookieKey, String source, HttpServletRequest request, HttpServletResponse response){
		logger.info(String.format("[HMP][%s]current destroy cookie by key:%s", source, cookieKey));
		Cookies cookies = Cookies.initFromServlet(request, response);
		cookies.remove(cookieKey);
	}
}
