package com.iamberry.wechat.handles.admin;

import com.iamberry.sys.Admin;
import com.iamberry.wechat.face.mq.MQSerivce;
import com.iamberry.wechat.face.sys.SysService;
import com.iamberry.wechat.realm.IamberryRealm;
import com.iamberry.wechat.tools.ResponseJson;
import com.iamberry.wechat.utils.AdminUtils;
import com.iamberry.wechat.utils.VerifyCodeUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * @author 献
 * @company 深圳爱贝源科技有限公司
 * @website www.iamberry.com
 * @tel 18271840547
 * @date 2017/5/12
 */
@Controller
public class LoginController {

    private static Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private SysService sysService;

    @Autowired
    private IamberryRealm iamberryRealm;

    @RequestMapping("/_login")
    public ModelAndView loginUI(HttpServletRequest request) {
        // 判断用户是否登录，如果已经登录，则跳转
        Subject currentUser = SecurityUtils.getSubject();
        if (!currentUser.isAuthenticated()) {
            // 判断是否已经记住过密码
            Admin admin = AdminUtils.getAdminCookie(request);
            if (admin == null) {
                return new ModelAndView("login");
            }
            try {
                // 执行登录.
                currentUser.login(new UsernamePasswordToken(admin.getAdminAccount(), admin.getAdminPassword().toUpperCase()));
            } catch (Exception e) {
                logger.error("", e);
                return new ModelAndView("login");
            }
        }

        // 已登陆
        return new ModelAndView("redirect:/admin/sys/_index");
    }

    @ResponseBody
    @RequestMapping("/get_salt")
    public ResponseJson getSalt(@RequestParam("login_name") String login_name) {
        // 获取用户的盐值
        String salt = sysService.getSaltByLoginName(login_name);
        if (salt == null || "".equals(salt)) {
            return new ResponseJson(200, "SUCCESS", 400);
        }
        return new ResponseJson(200, "SUCCESS", 200).addResponseKeyValue("salt", salt);
    }

    @ResponseBody
    @RequestMapping("/loginShiro")
    public ResponseJson loginShiro(HttpServletRequest request,
                                   HttpServletResponse response,
                              @RequestParam("login_name") String loginName,
                              @RequestParam("login_pwd") String loginPwd,
                              @RequestParam("login_code") String loginCode,
                              @RequestParam(value = "remember_me", required = false, defaultValue = "false") String rememberMe) {

        // 判断 验证码是否有误
        Object temp = request.getSession().getAttribute("login_code");
        if (temp == null || !loginCode.equalsIgnoreCase(temp.toString())) {
            return new ResponseJson(200, "VERIFY_CODE_ERROR", 400);
        }

        // 调用Shiro登录
        Subject currentUser = SecurityUtils.getSubject();
        if (!currentUser.isAuthenticated()) {
            try {
                // 执行登录.
                currentUser.login(new UsernamePasswordToken(loginName, loginPwd.toUpperCase()));
            }
            catch (UnknownAccountException ue) {
                // 没有这个用户
                return new ResponseJson(200, "NOT_ADMIN", 404);
            }
            catch (LockedAccountException le) {
                // 账户被锁定
                return new ResponseJson(200, "ADMIN_LOCKED", 403);
            }
            catch (Exception ae) {
                // 所有认证时异常的父类.
                return new ResponseJson(200, "LOGIN_ERROR", 500);
            }
        }

        // 是否需要记住密码
        if ("true".equals(rememberMe)) {
            AdminUtils.saveAdminToCookie(AdminUtils.getLoginAdminId(), loginName, loginPwd.toUpperCase(), response);
        }

        // 登录成功
        return new ResponseJson(200, "SUCCESS", 200);
    }

    /**
     * 验证码
     * @param response
     * @param request
     * @throws IOException
     */
    @RequestMapping(value = "/security_code")
    public void securityCode(HttpServletResponse response, HttpServletRequest request,
                             @RequestParam(value = "len", required = false, defaultValue = "6") Integer len) throws IOException {
        // 生成随机的验证码
        String verifyCode = VerifyCodeUtil.generateTextCode(3, len, null);
        // 保存
        request.getSession().setAttribute("login_code", verifyCode);
        // 输出到Response
        response.setContentType("image/jpeg");
        BufferedImage bufferedImage = VerifyCodeUtil.generateImageCode(verifyCode, 130, 40, new Random().nextInt(50), true, Color.WHITE, Color.BLACK, null);
        // 使用ServletOutputStream，要比PrintWrite快
        ImageIO.write(bufferedImage, "JPEG", response.getOutputStream());
    }

    @RequestMapping("/_exit")
    public ModelAndView exit(HttpServletRequest request) {
        // Shiro退出
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            // 清空缓存的权限
            iamberryRealm.getAuthorizationCache().remove(subject);
            subject.logout();
        }
        // 返回Login页面
        return new ModelAndView("login");
    }
}
