package com.pqs9900.controller.root;

import com.njcn.enums.LogTypeEnum;
import com.njcn.pojo.commons.HttpResult;
import com.njcn.pojo.commons.RedisDB;
import com.njcn.pojo.user.RoleGroup;
import com.njcn.service.log.UserLogDetailService;
import com.njcn.service.user.RoleGroupService;
import com.njcn.service.user.UserService;
import com.njcn.shiro.token.TokenManager;
import com.njcn.sso.pojo.user.User;
import com.njcn.utils.DesUtils;
import com.njcn.utils.PubUtils;
import com.njcn.utils.SerializeUtil;
import com.njcn.utils.XssFilterUtil;
import com.njcn.utils.redis.JedisManager;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.security.interfaces.RSAPrivateKey;
import java.util.List;

/**
 * @author hongawen
 * @date: 2019/9/26 13:26
 */
@Controller
@RequestMapping("managers")
public class ManagersController {
    private static final Logger logger = LoggerFactory.getLogger(ManagersController.class);

    @Resource
    UserLogDetailService userLogservice;

    @Resource
    private UserService userService;

    @Resource
    private RoleGroupService roleGroupService;

    @Resource
    private JedisManager jedisManager;

    /**
     * 获取管理员列表
     * @param request
     * @param userState
     * @return
     */
    @PostMapping("allManagers")
    @ResponseBody
    public HttpResult allManagers(HttpServletRequest request, String userState){
        HttpResult httpResult;
        List<User> managers;
        try{
            managers=userService.getAllManagers(userState);
            httpResult= PubUtils.assignmentResult(managers,200,"获取管理员列表成功");
        }catch(Exception e){
            httpResult= PubUtils.assignmentResult(null,500,"获取管理员列表异常");
        }
        return httpResult;
    }

    /**
     * 弹出新增管理员页面
     */
    @GetMapping("addManager")
    public String addManager(HttpServletRequest request){
        return "business/root/addManager";
    }

    /**
     * 弹出修改管理员密码页面
     */
    @GetMapping("updateManagerPassWord")
    public String updateManagerPassWord(HttpServletRequest request){
        return "business/root/updateManagerPassWord";
    }



    /**
     * 获取所有管理员的角色组
     */
    @PostMapping("allManagerRole")
    @ResponseBody
    public HttpResult allManagerRole(){
        HttpResult httpResult;
        List<RoleGroup> roleGroups;
        try{
            roleGroups=roleGroupService.getAllManagerRoleGroup();
            httpResult= PubUtils.assignmentResult(roleGroups,200,"获取所有管理员角色组成功");
        }catch(Exception e){
            httpResult= PubUtils.assignmentResult(null,500,"获取管理员角色组异常");
        }
        return httpResult;
    }

    /**
     * 保存管理员
     */
    @PostMapping("saveManager")
    @ResponseBody
    public HttpResult saveManager(String name, String loginName,
                               String password, String phone, String email, String ip, String ipEnd, String time, Integer mark, String rolegpIndex, String token, HttpServletRequest request) {
        HttpResult result = new HttpResult();
        String sessionToken = (String) TokenManager.getSession().getAttribute("token");
        if (!token.equalsIgnoreCase(sessionToken)) {
            result = PubUtils.assignmentResult(null, 500, "非法访问");
            return result;
        }
        //后台Xss攻击处理、包括html/js/sql
        name = XssFilterUtil.dealString(name);
        loginName = XssFilterUtil.dealString(loginName);
        loginName = DesUtils.aesDecrypt(loginName);//解密操作
        rolegpIndex = XssFilterUtil.dealString(rolegpIndex);
        password = XssFilterUtil.dealString(password);
        phone = XssFilterUtil.dealString(phone);
        email = XssFilterUtil.dealString(email);
        ip = XssFilterUtil.dealString(ip);
        ipEnd = XssFilterUtil.dealString(ipEnd);
        time = XssFilterUtil.dealString(time);
        String tmpip = StringUtils.isBlank(PubUtils.getIpAddr(request)) ? "127.0.0.1" : PubUtils.getIpAddr(request);
        try {
//            byte[] value = jedisManager.getValueByKey(RedisDB.SHORT_TIME_QUERY, SerializeUtil.serialize(loginName + tmpip));
//            RSAPrivateKey privateKey = SerializeUtil.deserialize(value, RSAPrivateKey.class);
            //秘钥用完即删
//            jedisManager.deleteByKey(RedisDB.SHORT_TIME_QUERY, SerializeUtil.serialize(loginName + tmpip));
            //密码处理
            String privateKey = jedisManager.getValueByKey(RedisDB.SHORT_TIME_QUERY, loginName + tmpip);
            //秘钥用完即删
            jedisManager.deleteByKey(RedisDB.SHORT_TIME_QUERY, loginName + tmpip);
            password = PubUtils.getPasswordSM2Verify(privateKey, password);

            if (password == null && password.length() == 0) {
                result = PubUtils.assignmentResult(null, 500, "密码传输完整性被破坏");
                return result;
            }
            if (password.contains(loginName)) {
                result = PubUtils.assignmentResult(null, 302, "用户密码包含用户名");
                logger.error("新增管理员失败");
                userLogservice.getLog("用户审核", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
                return result;
            }

            //新增管理员
            String message = userService.saveManager(name, loginName, rolegpIndex, password, phone, email, ip, ipEnd, time, mark);

            if (message.equalsIgnoreCase("新增管理员成功！")) {
                result = PubUtils.assignmentResult("success", 200, message);
                logger.info("新增管理员成功");
                userLogservice.getLog("新增用户", "成功", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("登录名已存在")) {
                result = PubUtils.assignmentResult(null, 300, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("名称已存在")) {
                result = PubUtils.assignmentResult(null, 500, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("该手机号已被注册")) {
                result = PubUtils.assignmentResult(null, 301, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("名称不可为空")) {
                result = PubUtils.assignmentResult(null, 302, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("登录名不可为空")) {
                result = PubUtils.assignmentResult(null, 303, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("密码不可为空")) {
                result = PubUtils.assignmentResult(null, 304, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("手机号不可为空")) {
                result = PubUtils.assignmentResult(null, 305, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("邮箱不可为空")) {
                result = PubUtils.assignmentResult(null, 306, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("起始ip不可为空")) {
                result = PubUtils.assignmentResult(null, 307, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("结束ip不可为空")) {
                result = PubUtils.assignmentResult(null, 308, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("名称只由中文组成，长度为1-20")) {
                result = PubUtils.assignmentResult(null, 309, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("登录名只能由3-16的字母和数字组成")) {
                result = PubUtils.assignmentResult(null, 310, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("密码格式不正确，需要包含特殊字符字母数字，长度为8-16")) {
                result = PubUtils.assignmentResult(null, 311, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("邮箱格式不正确，应含有@ .在@后，以.com、.con结尾（qq,163等）")) {
                result = PubUtils.assignmentResult(null, 312, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("手机号格式不正确，必须有11位，并且为数字，是正常的手机号码开头")) {
                result = PubUtils.assignmentResult(null, 313, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("起始ip地址格式不正确")) {
                result = PubUtils.assignmentResult(null, 314, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } else if (message.equalsIgnoreCase("结束ip地址格式不正确")) {
                result = PubUtils.assignmentResult(null, 315, message);
                logger.error("新增管理员失败");
                userLogservice.getLog("新增用户", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            }
        } catch (Exception e) {
            logger.error("新增管理员异常，异常为" + e);
            result = PubUtils.assignmentResult(null, 500, "新增管理员失败");
        }
        return result;
    }


    /**
     * 更新管理员密码
     * @param username 登录名
     * @param passwordX 新密码
     */
    @PostMapping("updatePassword")
    @ResponseBody
    public HttpResult updatePassword(HttpServletRequest request,String username, String passwordX, String token) {
        HttpResult result ;
        String sessionToken = (String) TokenManager.getSession().getAttribute("token");
        if (!token.equalsIgnoreCase(sessionToken)) {
            result = PubUtils.assignmentResult(null, 500, "非法访问");
            return result;
        }
        username = DesUtils.aesDecrypt(username);
        passwordX = XssFilterUtil.dealString(passwordX);
        String ip = StringUtils.isBlank(PubUtils.getIpAddr(request)) ? "127.0.0.1" : PubUtils.getIpAddr(request);
        try {
            String privateKey = jedisManager.getValueByKey(RedisDB.SHORT_TIME_QUERY, username + ip);
            //秘钥用完即删
            jedisManager.deleteByKey(RedisDB.SHORT_TIME_QUERY, SerializeUtil.serialize(username + ip));
            passwordX = PubUtils.getPasswordSM2Verify(privateKey, passwordX);
            if (StringUtils.isBlank(passwordX)) {
                result = PubUtils.assignmentResult(null, 500, "密码传输完整性被破坏");
                userLogservice.getLog("修改管理员密码", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
                return result;
            }

            //增加判断密码是否包含用户名
            if (passwordX.contains(username)) {
                userLogservice.getLog("修改管理员密码", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
                return PubUtils.assignmentResult(null, 500, "管理员密码包含登录名");
            }

            if (!(PubUtils.patternPassword(passwordX) || PubUtils.patternUsername(username))) {
                userLogservice.getLog("修改管理员密码", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
                result = PubUtils.assignmentResult(null, 500, "管理员名、密码格式不正确");
                return result;
            }
            try {
                userService.modifyPassword(username, passwordX);
                userLogservice.getLog("修改管理员密码", "成功", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
                result = PubUtils.assignmentResult(null, 200, "修改密码成功");
            } catch (Exception e) {
                userLogservice.getLog("修改管理员密码", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
                result = PubUtils.assignmentResult(null, 500, e.getMessage());
                logger.error("用户修改密码成功后，保存记录出错。原因：" + e.toString());
            }
        } catch (Exception e) {
            logger.error("更新密码出错，异常为：" + e.toString());
            String eMessage = e.getMessage();
            if (eMessage.length() > 20) {
                eMessage = "内部出错";
            }
            result = PubUtils.assignmentResult(null, 500, eMessage);
            try {
                userLogservice.getLog("修改管理员密码", "失败", PubUtils.getIpAddr(request), LogTypeEnum.SYSTEM.toString(), 1);
            } catch (Exception u) {
                logger.error("用户修改密码失败后，保存记录出错。原因：" + u.toString());
            }
        }
        return result;
    }
}
