package cn.wisenergy.chnmuseum.party.web.controller;

import cn.wisenergy.chnmuseum.party.auth.SHA256PasswordEncryptionService;
import cn.wisenergy.chnmuseum.party.auth.SecureRandomSaltService;
import cn.wisenergy.chnmuseum.party.common.enums.AuditStatusEnum;
import cn.wisenergy.chnmuseum.party.common.log.MethodLog;
import cn.wisenergy.chnmuseum.party.common.log.OperModule;
import cn.wisenergy.chnmuseum.party.common.log.OperType;
import cn.wisenergy.chnmuseum.party.common.util.DateUtil80;
import cn.wisenergy.chnmuseum.party.common.util.RandomUtil;
import cn.wisenergy.chnmuseum.party.common.vo.GenericPageParam;
import cn.wisenergy.chnmuseum.party.core.annotations.OperationLog;
import cn.wisenergy.chnmuseum.party.model.*;
import cn.wisenergy.chnmuseum.party.service.RoleService;
import cn.wisenergy.chnmuseum.party.service.TUserRoleService;
import cn.wisenergy.chnmuseum.party.service.impl.TBoxOperationServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cn.wisenergy.chnmuseum.party.web.controller.base.BaseController;
import cn.wisenergy.chnmuseum.party.service.TUserService;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <pre>
 * 用户 前端控制器
 * </pre>
 *
 * @author Danny Lee
 * @since 2021-03-22
 */
@Slf4j
@RestController
@RequestMapping("/tUser")
@Api(tags = {"用户操作接口"})
public class TUserController extends BaseController {

    @Resource
    private TUserService userService;

    @Resource
    private TUserRoleService tUserRoleService;

    @Resource
    private RoleService roleService;

    @Resource
    private TBoxOperationServiceImpl boxOperationService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    private static final String SHIRO_JWT_TOKEN = "shiro:jwt:token";
    //用户登录是否被锁定    一小时 redisKey 前缀
    private String SHIRO_IS_LOCK = "shiro_is_lock_";

    /**
     * 获取用户分页列表
     *
     * @param
     * @return
     */
    @ApiOperation(value = "获取用户分页列表")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "_index", value = "分页起始偏移量", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "_size", value = "返回条数", paramType = "query", dataType = "Integer")
    })
    @RequestMapping(value = "/getPageList", method = RequestMethod.GET)
    @RequiresPermissions("/user/getPageList")
//    @MethodLog(operModule = OperModule.USER, operType = OperType.SELECT)
    public Map<String, Object> getUserList(String userName) {
        try {
            Page<TUser> list = userService.getList(getPage(), userName);
            return getResult(list);
        } catch (Exception e) {
            logger.error("查询成员列表出错!", e);
        }
        return getFailResult();
    }

    /**
     * 查询成员列表
     *
     * @param
     * @return
     */
    @ApiOperation(value = "获取用户列表")
    @RequestMapping(value = "/getUserList", method = RequestMethod.GET)
    @RequiresPermissions("/user/getUserList")
//    @MethodLog(operModule = OperModule.USER, operType = OperType.SELECT)
    public Map<String, Object> getUserList(String type, String status, String auditStatus) {
        UpdateWrapper<TUser> wrapper = new UpdateWrapper<>();
        try {
            if (StringUtils.isNotBlank(type)) {
                wrapper.eq("type", type);
            }
            if (StringUtils.isNotBlank(status)) {
                wrapper.eq("status", status);
            }
            if (StringUtils.isNotBlank(auditStatus)) {
                wrapper.eq("audit_status", auditStatus);
            }
            wrapper.eq("is_deleted", false);
            wrapper.orderByDesc("create_time");
            List<TUser> list = userService.list(wrapper);
            return getResult(list);
        } catch (Exception e) {
            logger.error("查询成员列表出错!", e);
        }
        return getFailResult();
    }


    @ApiOperation(value = "获取用户详情", notes = "获取用户详情")
    @GetMapping("/getById")
    @RequiresPermissions("/user/getById")
//    @MethodLog(operModule = OperModule.USER, operType = OperType.SELECT)
    public Map<String, Object> getById(String id) {
        TUser tUser = userService.selectById(id);
        List<Role> list = roleService.selectRoleByUserId(id);
        tUser.setRoleList(list);
        return getResult(tUser);
    }

    //新增
    @OperationLog("新增成员")
    @ApiOperation(value = "新增成员")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @RequiresPermissions("/user/add")
    @MethodLog(operModule = OperModule.USER, operType = OperType.ADD)
    public Map<String, Object> add(@RequestBody TUser user) {
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        try {
            if (StringUtils.isBlank(user.getUserName())) {
                resultMap.put("resultCode", 400);
                resultMap.put("message", "账号不能为空!");
                return resultMap;
            } else {
                user.setUserName(StringUtils.trimToNull(user.getUserName()));
            }
            if (StringUtils.isBlank(user.getPassword())) {
                user.setPassword("123456");
            } else {
                user.setPassword(StringUtils.trimToNull(user.getPassword()));
            }
            if (StringUtils.isBlank(user.getRealName())) {
                resultMap.put("resultCode", 400);
                resultMap.put("message", "姓名不能为空!");
                return resultMap;
            } else {
                user.setRealName(StringUtils.trimToNull(user.getRealName()));
            }

            if (user.getRoleList() == null || user.getRoleList().size() < 1) {
                resultMap.put("resultCode", 400);
                resultMap.put("message", "请选择角色!");
                return resultMap;
            }
            if (StringUtils.isBlank(user.getOrgId())) {
                resultMap.put("resultCode", 400);
                resultMap.put("message", "请选择机构!");
                return resultMap;
            }

            QueryWrapper<TUser> ew = new QueryWrapper<>();
            if (StringUtils.isNoneBlank(user.getUserName())) {
                user.setUserName(user.getUserName().trim());
                ew.eq("is_deleted", 0);
                ew.eq("user_name", user.getUserName());
                TUser one = this.userService.getOne(ew);
                if (one != null) {
                    resultMap.put("resultCode", 400);
                    resultMap.put("message", "账号已存在!");
                    return resultMap;
                }
            }

            byte[] passwordSalt = SecureRandomSaltService.generateSalt();
            byte[] passwordHash = SHA256PasswordEncryptionService
                    .createPasswordHash(user.getPassword(), passwordSalt);
            user.setPasswordSalt(passwordSalt);
            user.setPasswordHash(passwordHash);
            user.setCreateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
            user.setUpdateTime(user.getCreateTime());
            user.setStatus("1");
            user.setAuditStatus("4");
            user.setIsDeleted(false);

            boolean ret = this.userService.save(user);

            List<Role> list = user.getRoleList();
            List<TUserRole> list1 = new ArrayList<>();
            for (Role role : list) {
                TUserRole entity = new TUserRole();
                entity.setUserId(user.getId());
                entity.setRoleId(role.getId());
                entity.setIsDeleted(false);
                list1.add(entity);
            }

            this.tUserRoleService.saveBatch(list1);

            if (!ret) {
                // 新增失败, 500
                resultMap.put("resultCode", 500);
                resultMap.put("message", "服务器忙");
                return resultMap;
            }
            resultMap.put("resultCode", 200);
            resultMap.put("message", "添加成功");
            // 201
            return resultMap;
        } catch (Exception e) {
            resultMap.put("resultCode", 500);
            resultMap.put("message", "服务器忙");
            logger.error("新增成员错误!", e);
        }
        return resultMap;
    }


    // 编辑用户信息
    @OperationLog("修改成员信息")
    @ApiOperation(value = "编辑用户信息(必须传 1username 2name 3roleId)")
    @PutMapping(value = "/update")
    @RequiresPermissions("/user/update")
    @MethodLog(operModule = OperModule.USER, operType = OperType.UPDATE)
    public ResponseEntity<Map<String, Object>> edit(@RequestBody TUser user) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            boolean ret = false;
            if (user.getId() != null) {
                if ("1".equals(user.getId()) && user.getStatus() == "2") {
                    resultMap.put("status", 400);
                    resultMap.put("message", "该账号不能被禁用");
                    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
                }

                user.setUserName(StringUtils.trimToNull(user.getUserName()));
                user.setPassword(StringUtils.trimToNull(user.getPassword()));
                user.setRealName(StringUtils.trimToNull(user.getRealName()));
                user.setUpdateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
                ret = userService.updateById(user);
                //查询当前用户拥有的角色
                QueryWrapper<TUserRole> userRoleWrapper = new QueryWrapper<>();
                userRoleWrapper.eq("user_id", user.getId());
                boolean remove = tUserRoleService.remove(userRoleWrapper);


                List<Role> list = user.getRoleList();
                if (list != null && list.size() > 0) {
                    ArrayList<TUserRole> list1 = new ArrayList<>();
                    for (Role r : list) {
                        TUserRole userRole = new TUserRole();
                        userRole.setUserId(user.getId());
                        userRole.setRoleId(r.getId());
                        userRole.setIsDeleted(false);
                        list1.add(userRole);
                    }

                    ret = this.tUserRoleService.saveBatch(list1);
                }
            } else {
                // 更新失败, 400
                resultMap.put("resultCode", 400);
                resultMap.put("message", "请选择用户");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
            }

            if (!ret) {
                // 更新失败, 500
                resultMap.put("resultCode", 500);
                resultMap.put("message", "服务器忙");
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resultMap);
            }
            // 204
            resultMap.put("resultCode", 201);
            resultMap.put("message", "更新成功");
            return ResponseEntity.status(HttpStatus.CREATED).body(resultMap);
        } catch (Exception e) {
            logger.error("更新错误!", e);
        }
        // 500
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    }

    /**
     * 删除
     *
     * @param userId
     * @return
     */
    @OperationLog("删除成员")
    @ApiOperation(value = "删除成员")
    @DeleteMapping(value = "/delete")
    @RequiresPermissions("/user/delete")
    @MethodLog(operModule = OperModule.USER, operType = OperType.DELETE)
    public ResponseEntity<Map<String, Object>> delete(String userId) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if ("1".equals(userId)) {
                resultMap.put("status", 400);
                resultMap.put("message", "该账号不能被删除");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
            }
            TUser entity = new TUser();
            entity.setId(userId);
            entity.setUpdateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
            entity.setIsDeleted(true);
            boolean ret1 = this.userService.updateById(entity);

            QueryWrapper<TUserRole> userRoleWrapper = new QueryWrapper<>();
            userRoleWrapper.eq("user_id", userId);
            boolean ret2 = this.tUserRoleService.remove(userRoleWrapper);

            if (!ret1 || !ret2) {
                resultMap.put("resultCode", 400);
                resultMap.put("message", "删除失败");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
            }
            resultMap.put("resultCode", 201);
            resultMap.put("message", "删除成功");
            return ResponseEntity.status(HttpStatus.CREATED).body(resultMap);
        } catch (Exception e) {
            logger.error("删除用户出错!", e);
        }
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
    }


    /**
     * 禁用
     *
     * @param userId
     * @return
     */
    @OperationLog("禁用成员")
    @ApiOperation(value = "禁用")
    @RequestMapping(value = "/disable", method = RequestMethod.PUT)
    @RequiresPermissions("/user/disable")
    @MethodLog(operModule = OperModule.USER, operType = OperType.DISABLE)
    public ResponseEntity<Map<String, Object>> disableTUser(String userId) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            TUser entity = new TUser();
            entity.setId(userId);
            //提交禁用审核,没有真正禁用
            entity.setAuditStatus("1");
            Integer code = AuditStatusEnum.TBC.getCode();
            entity.setAuditStatus(code.toString());
            entity.setUpdateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
            boolean ret = this.userService.updateById(entity);

            //获取该用户的登陆token
            String userToken = stringRedisTemplate.opsForValue().get(SHIRO_JWT_TOKEN + userId);
            if (null != userToken) {
                stringRedisTemplate.delete(userToken);
                stringRedisTemplate.delete(SHIRO_JWT_TOKEN + userId);
            }
            if (!ret) {
                resultMap.put("resultCode", 400);
                resultMap.put("message", "禁用失败");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
            }
            resultMap.put("resultCode", 201);
            resultMap.put("message", "禁用成功");
            return ResponseEntity.status(HttpStatus.CREATED).body(resultMap);
        } catch (Exception e) {
            logger.error("禁用用户出错!", e);
        }
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
    }


    // 启动
    @OperationLog("启用成员")
    @ApiOperation(value = "启用")
    @RequestMapping(value = "/enable", method = RequestMethod.PUT)
    @RequiresPermissions("/user/enable")
    @MethodLog(operModule = OperModule.USER, operType = OperType.UNABLE)
    public ResponseEntity<Map<String, Object>> enableUser(String userId) {
        try {
            Map<String, Object> map = new HashMap<>();

            TUser entity = new TUser();
            entity.setId(userId);
            entity.setStatus("1");
            entity.setUpdateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
            boolean ret = this.userService.updateById(entity);
            if (!ret) {
                map.put("resultCode", "500");
                map.put("message", "服务器错误");
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(map);
            }
            map.put("resultCode", "201");
            map.put("message", "启用成功");
            return ResponseEntity.status(HttpStatus.CREATED).body(map);
        } catch (Exception e) {
            logger.error("用户启用出错!", e);
        }
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(
                null);
    }


    @OperationLog("修改密码")
    @ApiOperation(value = "管理员更改自己的登录密码", notes = "管理员更改自己的登录密码")
    @RequestMapping(value = "/editPwd", method = RequestMethod.PUT)
    @RequiresPermissions("/user/editPwd")
    @MethodLog(operModule = OperModule.USER, operType = OperType.UPDATE)
    public ResponseEntity<Map<String, Object>> editPwd(@RequestParam(value = "oldPassWord", required = true) String oldPassWord,
                                                       @RequestParam(value = "password", required = true) String password) {
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        try {
            boolean ret = false;
            TUser user = this.userService.getById(this.getUserId());
            byte[] salt = user.getPasswordSalt();
            if (new String(SHA256PasswordEncryptionService.createPasswordHash(oldPassWord, salt))
                    .equals(new String(user.getPasswordHash()))) {
                salt = SecureRandomSaltService.generateSalt();
                user.setPasswordSalt(salt);
                user.setPasswordHash((SHA256PasswordEncryptionService.createPasswordHash(password, salt)));
                user.setUpdateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
                ret = this.userService.updateById(user);
            } else {
                logger.error("旧密码不正确");
                resultMap.put("resultCode", 400);
                resultMap.put("message", "旧密码不正确");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
            }
            if (!ret) {
                resultMap.put("resultCode", 500);
                resultMap.put("message", "修改失败");
                // 更新失败, 500
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resultMap);
            }
            resultMap.put("resultCode", 200);
            resultMap.put("message", "修改成功");
            return ResponseEntity.status(HttpStatus.OK).body(resultMap);
        } catch (Exception e) {
            logger.error("更新密码错误!", e);
        }
        // 500
        resultMap.put("resultCode", 500);
        resultMap.put("message", "修改失败");
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resultMap);
    }


    // 管理员重置密码
    @OperationLog("重置密码")
    @ApiOperation(value = "管理员重置密码", notes = "管理员重置密码")
    @RequestMapping(value = "/resetPassword", method = RequestMethod.PUT)
    @RequiresPermissions("/user/resetPassword")
    @MethodLog(operModule = OperModule.USER, operType = OperType.UPDATE)
    public ResponseEntity<Map<Object, String>> resetPassword(String userId) {
        try {
            Map<Object, String> map = new LinkedHashMap<>();
            TUser user = new TUser();
            user.setId(userId);
            String newPassword = "123456";
            byte[] passwordSalt = SecureRandomSaltService.generateSalt();
            byte[] passwordHash = SHA256PasswordEncryptionService.createPasswordHash(newPassword, passwordSalt);
            user.setPasswordSalt(passwordSalt);
            user.setPasswordHash(passwordHash);
            user.setUpdateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
            boolean ret = userService.updateById(user);
            if (!ret) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
            }
            stringRedisTemplate.delete(SHIRO_IS_LOCK + userService.getById(userId).getUserName());
            map.put("resultCode", "201");
            map.put("message", "重置密码成功");
            map.put("data", newPassword);
            return ResponseEntity.status(HttpStatus.CREATED).body(map);
        } catch (Exception e) {
            logger.error("重置密码出错!", e);
        }
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
    }


    @PutMapping("/updateAuditStatus")
    @RequiresPermissions("/user/updateAuditStatus")
    @ApiOperation(value = "更新用户审核状态", notes = "更新用户审核状态")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "id", value = "标识ID", dataType = "String", paramType = "path"),
            @ApiImplicitParam(name = "status", value = "状态", paramType = "query", dataType = "String")
    })
    @MethodLog(operModule = OperModule.USER, operType = OperType.UPDATE)
    public Map<String, Object> updateStatus(@NotNull(message = "机构用户不能为空") @PathVariable("id") String id, @RequestParam("status") AuditStatusEnum status) {
        UpdateWrapper<TUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.eq("audit_status", status.getCode());
        //当禁用审核通过后,真正禁用
        if ("4".equals(status.getCode().toString())) {
            updateWrapper.eq("status", "2");
        }

        boolean flag = userService.update(updateWrapper);
        if (flag) {
            return getSuccessResult();
        }
        return getFailResult();
    }

    //新增
    @OperationLog("新增机顶盒账号")
    @ApiOperation(value = "新增机顶盒账号")
    @RequestMapping(value = "/BoxAdd", method = RequestMethod.POST)
    @RequiresPermissions("/user/BoxAdd")
//    @MethodLog(operModule = OperModule.USER, operType = OperType.ADD)
    public ResponseEntity<Map<String, Object>> BoxAdd(TUser user) {
        Map<String, Object> resultMap = new LinkedHashMap<String, Object>();
        try {
            if (StringUtils.isBlank(user.getUserName())) {
                resultMap.put("resultCode", 400);
                resultMap.put("message", "账号不能为空!");
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
            } else {
                user.setUserName(StringUtils.trimToNull(user.getUserName()));
            }

            user.setPassword(RandomUtil.createLetterRandom(6));

            QueryWrapper<TUser> ew = new QueryWrapper<>();
            if (StringUtils.isNoneBlank(user.getUserName())) {
                user.setUserName(user.getUserName().trim());
                ew.eq("is_deleted", 0);
                ew.eq("user_name", user.getUserName());
                TUser one = this.userService.getOne(ew);
                if (one != null) {
                    resultMap.put("resultCode", 400);
                    resultMap.put("message", "账号已存在!");
                    return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resultMap);
                }
            }

            byte[] passwordSalt = SecureRandomSaltService.generateSalt();
            byte[] passwordHash = SHA256PasswordEncryptionService
                    .createPasswordHash(user.getPassword(), passwordSalt);
            user.setPasswordSalt(passwordSalt);
            user.setPasswordHash(passwordHash);
            user.setCreateTime(DateUtil80.getDateTimeOfTimestamp(System.currentTimeMillis()));
            user.setUpdateTime(user.getCreateTime());
            user.setIsDeleted(false);
            user.setPermanent(true);
            user.setStatus("1");
            user.setAuditStatus("4");
            user.setType("3");

            boolean ret = this.userService.save(user);

            TBoxOperation tBoxOperation = new TBoxOperation();
            tBoxOperation.setOrganId(user.getOrgId());
            tBoxOperation.setAreaId(user.getAreaId());
            tBoxOperation.setStatus(1);
            tBoxOperation.setCreateTime(LocalDateTime.now());
            tBoxOperation.setUpdateTime(LocalDateTime.now());
            ret = boxOperationService.save(tBoxOperation);

            if (!ret) {
                // 新增失败, 500
                resultMap.put("resultCode", 500);
                resultMap.put("message", "服务器忙");
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                        .body(resultMap);
            }
            resultMap.put("resultCode", 200);
            resultMap.put("message", "添加成功");
            resultMap.put("data", user.getPassword());
            // 201
            return ResponseEntity.status(HttpStatus.CREATED).body(resultMap);
        } catch (Exception e) {
            resultMap.put("resultCode", 500);
            resultMap.put("message", "服务器忙");
            logger.error("新增成员错误!", e);
        }
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resultMap);
    }

}