package cn.estsh.i3plus.core.apiservice.controller.busi;

import cn.estsh.i3plus.core.api.iservice.busi.IPersonnelService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysMessageService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysUserInfoService;
import cn.estsh.i3plus.core.api.iservice.busi.ISysUserService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.EncryptTool;
import cn.estsh.i3plus.platform.common.tool.StringTool;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.platform.common.util.PlatformConstWords;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ImppEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.*;
import cn.estsh.impp.framework.base.controller.CoreBaseController;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.exception.ImppExceptionEnum;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.ResultBean;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Description : 系统用户操作服务
 * @Reference :
 * @Author : wei.peng
 * @Date : 2018-10-25 21:46
 * @Modify :
 **/
@RestController
@Api(description = "系统用户服务")
@RequestMapping(PlatformConstWords.BASE_URL + "/sys-user")
public class SysUserController extends CoreBaseController{

    public static final Logger LOGGER = LoggerFactory.getLogger(SysUserController.class);

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysUserInfoService sysUserInfoService;

    @Autowired
    private ISysMessageService sysMessageService;

    @Autowired
    private IPersonnelService personnelService;

    @PostMapping(value = "/insert")
    @ApiOperation(value = "新增用户", notes = "新增系统用户")
    public ResultBean insertSysUser(SysUser sysUser,String[] roleIds) {
        try {
            ConvertBean.modelSafeArrayNumber(roleIds,true);

            ValidatorBean.beginValid(sysUser)
                            .numberCheck("userInfoId",sysUser.getUserInfoId())
                            .notNull("userLoginName",sysUser.getUserLoginName())
                            .notNull("userEmail",sysUser.getUserEmail())
                            .notNull("userLoginPassword",sysUser.getUserLoginPassword());

            if(roleIds == null || roleIds.length <= 0){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("角色信息不能为空")
                        .build();
            }

            // 用户唯一校验
            personnelService.checkSysUserOnly(sysUser);

            SysUserInfo userInfo = sysUserInfoService.getSysUserInfoById(sysUser.getUserInfoId());
            if(userInfo == null){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                        .setErrorDetail("用户信息不存在请重新操作")
                        .build();
            }

            //新增初始化
            sysUser.setUserName(userInfo.getName());
            sysUser.setUserStatus(CommonEnumUtil.USER_STATUS.ENABLE.getValue());
            sysUser.setIsValid(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
            sysUser.setUserType(CommonEnumUtil.USER_TYPE.USER.getValue());
            sysUser.setUserLoginNum(0);
            ConvertBean.modelInitialize(sysUser,AuthUtil.getSessionUser());

            SysUser user = sysUserService.insertSysUser(sysUser);

            // 更新用户关系
            personnelService.refreshRefSysUserRole(user.getId(),StringTool.getArrayLong(roleIds));

            return ResultBean.success("操作成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultObject(user);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping(value = "/update")
    @ApiOperation(value = "修改用户", notes = "修改用户信息")
    public ResultBean updateSysUser(SysUser sysUser,String[] roleIds) {
        try {
            ConvertBean.modelSafeArrayNumber(roleIds,true);
            ValidatorBean.beginValid(sysUser)
                    .numberCheck("id",sysUser.getUserInfoId())
                    .numberCheck("userInfoId",sysUser.getUserInfoId())
                    .notNull("userLoginName",sysUser.getUserLoginName())
                    .notNull("userEmail",sysUser.getUserEmail());

            if(roleIds == null || roleIds.length <= 0){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("角色信息不能为空")
                        .build();
            }

            // 用户唯一校验
            personnelService.checkSysUserOnly(sysUser);

            // 用户信息封装
            SysUserInfo userInfo = sysUserService.getSysUserInfoById(sysUser.getUserInfoId());
            SysUser user = sysUserService.getSysUserById(sysUser.getId());
            if(userInfo == null){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode())
                        .setErrorDetail("用户信息不存在请重新操作")
                        .build();
            }

            // 修改密码
            if(sysUser.getUserLoginPassword() != null && sysUser.getUserLoginPassword().trim().length() > 0){
                String md5 = EncryptTool.hexMD5(sysUser.getUserLoginPassword());
                user.setUserLoginPassword(md5);
            }

            user.setUserInfoId(userInfo.getId());
            user.setUserName(userInfo.getName());
            user.setUserLoginName(sysUser.getUserLoginName());
            user.setUserEmail(sysUser.getUserEmail());
            user.setUserPhone(sysUser.getUserPhone());
            ConvertBean.modelUpdate(sysUser,AuthUtil.getSessionUser());

            // 更新用户关系
            personnelService.refreshRefSysUserRole(user.getId(),StringTool.getArrayLong(roleIds));
            sysUserService.updateSysUser(user);

            return ResultBean.success("操作成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultObject(user);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping(value = "/status")
    @ApiOperation(value = "修改用户状态", notes = "根据ID修改用户状态")
    public ResultBean updateStatus(String id, int status) {
        try {
            // 数据校验
            ValidatorBean.checkNotNull(id, "用户id 不能为空");
            ValidatorBean.checkNotZero(status, "用户状态不能为空");

            sysUserService.updateSysUserStatus(Long.parseLong(id), status, AuthUtil.getSessionUser());
            return new ResultBean(true);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping(value = "/batch-status")
    @ApiOperation(value = "批量修改系统功能状态", notes = "根据ID修改系统功能状态")
    public ResultBean updateBatchStatus(String[] ids,int status) {
        try {
            ids = ConvertBean.modelSafeArrayNumber(ids,true);

            // 数据校验
            ValidatorBean.checkNotNull(ids, "功能id 不能为空");
            ValidatorBean.checkNotZero(status, "功能状态不能为空");

            sysUserService.updateBatchSysUserStatus(StringTool.getArrayLong(ids),status,AuthUtil.getSessionUser());

            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PutMapping(value = "/update-password")
    @ApiOperation(value = "修改密码", notes = "修改当前登录用户密码")
    public ResultBean updateSysUserPassword(String password,String newPwd) {
        try {
            SessionUser sessionUser = AuthUtil.getSessionUser();
            // 数据校验
            ValidatorBean.checkNotNull(password, "旧密码不能为空");
            ValidatorBean.checkNotNull(newPwd, "新密码不能为空");

            personnelService.checkSysUserPassword(newPwd);

            sysUserService.updateSysUserPassword(sessionUser.getUser().getId(),password,newPwd.trim());

            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value = "/list")
    @ApiOperation(value = "查询所有用户", notes = "查询所有系统用户")
    public ResultBean findAll() {
        try {
            List<SysUser> list = sysUserService.list();
            return ResultBean.success("操作成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultList(list);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value="/query-user-by-pager")
    @ApiOperation(value="查询系统用户",notes="组合查询用户，外带分页查询(isValid = 1)")
    public ResultBean querySysUserByPager(SysUser user, Pager pager){
        try{
            ListPager<SysUser> listPager = sysUserService.querySysUserByPager(user, pager);
            return ResultBean.success("操作成功").setListPager(listPager).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @DeleteMapping(value = "/delete/{id}")
    @ApiOperation(value = "删除账号", notes = "删除制定账号信息")
    public ResultBean delete(@PathVariable("id") String id) {
        try {
            // 数据校验
            ValidatorBean.checkNotNull(id, "用户id 不能为空");

            sysUserService.deleteSysUserById(Long.parseLong(id));
            return ResultBean.success().setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @DeleteMapping(value = "/batch-delete")
    @ApiOperation(value = "根据id批量删除", notes = "根据id批量删除")
    public ResultBean deleteBatchSysUserByIds(String[] ids){
        try{
            ids = ConvertBean.modelSafeArrayNumber(ids,true);
            if(ids.length == 0){
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("请选择需要删除的用户。")
                        .build();
            }

            sysUserService.deleteBatchSysUserById(StringTool.getArrayLong(ids),AuthUtil.getSessionUser());
            return ResultBean.success("操作成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping(value = "/find-ref-role/{userId}")
    @ApiOperation(value = "查询角色的所有角色权限关系", notes = "查询角色的所有角色权限关系")
    public ResultBean findRefRoleMenu(@PathVariable("userId") String userId) {
        try {
            ValidatorBean.checkNotNull(userId, "用户 id 不能为空");
            List<SysRefUserRole> list = sysUserService.findSysRefUserRoleByUserId(Long.parseLong(userId));
            return ResultBean.success("操作成功")
                    .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode())
                    .setResultList(list);
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/reset-pwd/{id}")
    @ApiOperation(value = "密码重置",notes = "根据id重置用户密码")
    public ResultBean updateResetPassword(@PathVariable String id){
        try {
            SysUser user = sysUserService.getSysUserById(Long.parseLong(id));
            if(user != null){
                Integer num = personnelService.checkSysUserResetPassword(user);
                num = CommonConstWords.LOCK_USER_RESET_PASSWORD - num;


                String password = RandomStringUtils.random(6, true, false);
                user.setUserLoginPassword(EncryptTool.hexMD5(password));
                sysUserService.updateSysUser(user);

                String content = "系统提示：\n" +
                        "\t"+getSessionUser().getUserName()+"使用密码重置功能帮您重置了【"+user.getUserLoginName()+"】账号的密码，" +
                        "新密码是："+password+"";

                SysMessage message = new SysMessage();
                message.setMessageTitle("重置密码");
                message.setMessageContent(content);
                message.setMessageType(ImppEnumUtil.MESSAGE_TYPE.MAIL.getValue());
                message.setMessageContentType(ImppEnumUtil.MESSAGE_TYPE_CONTENT.TEXT.getValue());
                message.setMessageSenderId(getSessionUser().getUser().getId());
                message.setMessageSenderNameRdd(getSessionUser().getUserName());
                message.setMessageReceiversId(user.getId().toString());
                message.setMessageReceiversNameRdd(user.getUserName());
                message.setMessageReceiverType(ImppEnumUtil.MESSAGE_RECEIVER_TYPE.INTERNAL.getValue());

                sysMessageService.doSendSysMessage(message);

                LOGGER.info("系统提示：{} 使用密码重置功能帮{}重置了{}账号的密码，新密码是：{}",
                        getSessionUser().getUserName(),user.getUserName(),user.getUserLoginName(),password);

                String result = "操作成功，【"+user.getUserName()+"】账号今日重置密码次数剩余" +num+ "次";
                return ResultBean.success(result).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
            }else{
                return ResultBean.success("操作失败")
                        .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode())
                        .setErrorMsg("用户不存在");
            }
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @GetMapping("/verification/get-email")
    @ApiOperation(value = "发送验证码",notes = "发送邮件验证码")
    public ResultBean getEmailVerification(String email){
        try {
            SysUser user = sysUserService.getSysUserByEmail(email);
            if(user != null){
                String verification = RandomStringUtils.random(6, true, false);

                String redisKey = CommonConstWords.SESSION_VERIFICATION_USER_EMAIL + "_" + getSessionUser().getUserId();
                redisCore.putObject(redisKey, verification + "-" + email, 180);

                String content = "系统提示：\n" +
                        "\t密码找回验证码：【"+verification+"】";

                SysMessage message = new SysMessage();
                message.setMessageTitle("验证码");
                message.setMessageContent(content);
                message.setMessageType(ImppEnumUtil.MESSAGE_TYPE.MAIL.getValue());
                message.setMessageContentType(ImppEnumUtil.MESSAGE_TYPE_CONTENT.TEXT.getValue());
                message.setMessageSenderId(getSessionUser().getUser().getId());
                message.setMessageSenderNameRdd(getSessionUser().getUserName());
                message.setMessageReceiversId(user.getId().toString());
                message.setMessageReceiversNameRdd(user.getUserName());
                message.setMessageSendTime(TimeTool.getNowTime(true));
                message.setMessageReceiverType(ImppEnumUtil.MESSAGE_RECEIVER_TYPE.INTERNAL.getValue());

                sysMessageService.doSendSysMessage(message);

                LOGGER.info("系统提示：\t 密码找回验证码【{}】",verification);
                return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
            }else{
                return ResultBean.success("操作失败")
                        .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode())
                        .setErrorMsg("用户不存在");
            }
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    @PostMapping("/password/update-verification")
    @ApiOperation(value = "修改密码",notes = "通过邮箱的验证码修改密码")
    public ResultBean getEmailVerification(String password,String email,String verification){
        try {
            ValidatorBean.checkNotNull(verification,"验证码不能为空");
            ValidatorBean.checkNotNull(password,"新密码不能为空");
            ValidatorBean.checkNotNull(email,"邮件不能为空");

            personnelService.checkSysUserPassword(password);

            String redisKey = CommonConstWords.SESSION_VERIFICATION_USER_EMAIL + "_" + getSessionUser().getUserId();
            Object redisValue = redisCore.getObject(redisKey);
            if(redisValue != null){
                if(redisValue.toString().indexOf(verification) >= 0 ){
                    if(redisValue.toString().indexOf(email) >= 0 ){
                        SysUser user = sysUserService.getSysUserByEmail(email);
                        user.setUserLoginPassword(EncryptTool.hexMD5(password));
                        sysUserService.updateSysUser(user);
                        return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
                    }else {
                        return ResultBean.fail("操作失败")
                                .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode())
                                .setErrorMsg("请勿修改邮箱信息");
                    }
                }else {
                    return ResultBean.fail("操作失败")
                            .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode())
                            .setErrorMsg("验证码错误请重新输入");
                }
            }else {
                return ResultBean.fail("操作失败")
                        .setCode(ResourceEnumUtil.MESSAGE.FAIL.getCode())
                        .setErrorMsg("验证码已过期");
            }
        } catch (ImppBusiException busExcep) {
            return ResultBean.fail(busExcep);
        } catch (Exception e) {
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }


}
