package im.zksy.yjmqserver.system.controller;

import cn.hutool.core.util.IdUtil;
import im.zksy.yjmqserver.common.shiro.ShiroActionProperties;
import im.zksy.yjmqserver.common.util.CaptchaUtil;
import im.zksy.yjmqserver.common.util.DateUtils;
import im.zksy.yjmqserver.common.util.ResultBean;
import im.zksy.yjmqserver.system.model.User;
import im.zksy.yjmqserver.system.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;

@Controller
public class LoginController {
    private static Logger log = LoggerFactory.getLogger(LoginController.class);
    @Resource
    private UserService userService;


    @Resource
    private ShiroActionProperties shiroActionProperties;


    @GetMapping(value = {"/", "/login"})
    public String login(Model model) {
        model.addAttribute("loginVerify", shiroActionProperties.getLoginVerify());
        return "login2";
    }

    @GetMapping("/register")
    public String register() {
        return "register";
    }

    @PostMapping("/login")
    @ResponseBody
    public ResultBean login(User user, @RequestParam(value = "captcha", required = false) String captcha, HttpServletResponse response) {
        Subject subject = SecurityUtils.getSubject();

        try {
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            subject.login(token);
            userService.updateLastLoginTimeByUsername(user.getUsername(), DateUtils.dateTimeNow("YYYY/MM/dd HH:mm:ss"));
            //查询用户操作权限一级菜单
            User cuser = userService.selectOneByUserName(user.getUsername());
            return ResultBean.success(cuser);
        } catch (UnknownAccountException ex) {
            log.error(ex.toString());
            return ResultBean.error("账户不存在");
        } catch (LockedAccountException ex) {
            log.error(ex.toString());
            return ResultBean.error("账户被锁住");
        } catch (AuthenticationException ex) {
            return ResultBean.error("账号或者密码错误");
        }

    }

    @GetMapping("/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        return "redirect:login";
    }

    @PostMapping("/register")
    @ResponseBody
    public ResultBean register(User user) {
        userService.checkUserNameExistOnCreate(user.getUsername());
        String activeCode = IdUtil.fastSimpleUUID();
        user.setActiveCode(activeCode);
        user.setStatus("0");

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        String url = request.getScheme() + "://"
//                + request.getServerName()
//                + ":"
//                + request.getServerPort()
//                + "/active/"
//                + activeCode;
//        Context context = new Context();
//        context.setVariable("url", url);
//        String mailContent = templateEngine.process("mail/registerTemplate", context);
//        new Thread(() ->
//                mailService.sendHTMLMail(user.getEmail(), "Shiro-Action 激活邮件", mailContent))
//                .start();

        // 注册后默认的角色, 根据自己数据库的角色表 ID 设置
        Integer[] initRoleIds = {2};
        return ResultBean.success(userService.add(user, initRoleIds));
    }

    @GetMapping("/captcha")
    public void captcha(HttpServletResponse response) throws IOException {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CaptchaUtil.Captcha captcha = CaptchaUtil.createCaptcha(140, 38, 4, 10, 30);
        Session session = SecurityUtils.getSubject().getSession();
        session.setAttribute("captcha", captcha.getCode());

        response.setContentType("image/png");
        OutputStream os = response.getOutputStream();
        ImageIO.write(captcha.getImage(), "png", os);
    }

    /***
     * 激活注册账号
     * @param token
     * @param model
     * @return
     */

    @GetMapping("/active/{token}")
    public String active(@PathVariable("token") String token, Model model) {
        User user = userService.selectByActiveCode(token);
        String msg;
        if (user == null) {
            msg = "请求异常, 激活地址不存在!";
        } else if ("1".equals(user.getStatus())) {
            msg = "用户已激活, 请勿重复激活!";
        } else {
            msg = "激活成功!";
            user.setStatus("1");
            userService.activeUserByUserId(user.getUserId());
        }
        model.addAttribute("msg", msg);
        return "active";
    }

    /***
     * 用户账号查询权限
     * @param username
     * @return
     */

    @PostMapping("/firstmenu")
    @ResponseBody
    public ResultBean firstmenu(String username) {
        if (null != username && shiroActionProperties.getSuperAdminUsername().equals(username)) {
            username = null;
            return ResultBean.success(userService.selectUserFirstMenu(username));
        } else if (null != username) {
            return ResultBean.success(userService.selectUserFirstMenu(username));
        }
        return ResultBean.success();
    }

    /***
     * 用户账号查询权限用户账号查询权限
     * @param menuid
     * @param username
     * @return
     */

    @PostMapping("/secondmenu")
    @ResponseBody
    public ResultBean firstmenu(Integer menuid, String username) {
        if (null != username && shiroActionProperties.getSuperAdminUsername().equals(username)) {
            username = null;
            return ResultBean.success(userService.selectUserSecondMenu(menuid, username));
        } else if (null != username) {
            return ResultBean.success(userService.selectUserSecondMenu(menuid, username));
        }

        return ResultBean.success();
    }


}
