package com.dcit.authority.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.dcit.authority.constant.Const;
import com.dcit.authority.dto.DutyContactsDTO;
import com.dcit.authority.dto.SysUserBasicInfoDTO;
import com.dcit.authority.dto.SysUserDTO;
import com.dcit.authority.dto.UserRolesInfoDTO;
import com.dcit.authority.dto.form.ChangePasswordForm;
import com.dcit.authority.dto.form.SysUserInfoForm;
import com.dcit.authority.dto.form.UserRolesInfoForm;
import com.dcit.authority.dto.query.UserInfoQuery;
import com.dcit.authority.exception.AuthException;
import com.dcit.authority.model.SysUser;
import com.dcit.authority.model.SysUserRoles;
import com.dcit.authority.service.SysUserService;
import com.dcit.authority.shiro.ShiroKit;
import com.dcit.authority.utils.JsonWebTokenUtil;
import com.dcit.common.enums.ResultEnum;
import com.dcit.common.utils.BeanCopyUtil;
import com.dcit.common.utils.KeyUtil;
import com.dcit.common.utils.RandomValidateCode;
import com.dcit.common.utils.ResultVOUtil;
import com.dcit.common.utils.StrEncryptUtil;
import com.dcit.common.vo.ResultVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@Api(value="用户管理API")
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
	
	@Autowired
	private SysUserService sysUserService;
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@ApiOperation(value = "查询用户帐号是否存在")
    @PostMapping("/findUserByAccount/{account}")
	public ResultVO<Object> findUserByAccount(@PathVariable String account){
		SysUserBasicInfoDTO dto = sysUserService.getUserByAccount(account);
		if(null == dto){
			return ResultVOUtil.success();
		}else{
			return ResultVOUtil.error(ResultEnum.ACCOUNT_EXIST);
		}
	}
	

    @ApiOperation(value = "获取系统用户列表")
    @PostMapping("/getUserList")
    public ResultVO<Object> getUserList(@RequestBody UserInfoQuery userInfoQuery) {
    	
    	ModelMap modelMap = new ModelMap();
    	try {
    		PageHelper.startPage(userInfoQuery.getPage(),userInfoQuery.getSize());
	        Map<String, Object> params = new HashMap<String, Object>();
	        params.put("userName", userInfoQuery.getUserName());
	        params.put("account", userInfoQuery.getAccount());
	        params.put("deptId", userInfoQuery.getDeptId());
	        params.put("accountType", userInfoQuery.getAccountType());
	        List<SysUserDTO> sysUserList = sysUserService.getUserList(params);
	        PageInfo<SysUserDTO> pageInfo = new PageInfo<SysUserDTO>(sysUserList);
	        
	        modelMap.put("pageData", pageInfo.getList());
	        modelMap.put("total", pageInfo.getTotal());
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【获取系统用户列表】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
        
        return ResultVOUtil.success(modelMap);
    }
    
    @ApiOperation(value = "根据用户id查询用户详情")
    @GetMapping("/getUserInfoByUid/{uid}")
    public ResultVO<Object> getUserInfoByUid(@PathVariable String uid){
    	SysUser sysUser = sysUserService.selectByPrimaryKey(uid);
    	sysUser.setAccountPwd(null);
    	sysUser.setSalt(null);
    	
    	return ResultVOUtil.success(sysUser);
    }
    
    @ApiOperation(value = "新增编辑用户")
    @PostMapping("/addorEditUserInfo")
    public ResultVO<Object> addorEditUserInfo(@RequestBody SysUserInfoForm sysUserInfoForm, BindingResult bindingResult){
    	
    	if(bindingResult.hasErrors()){
			log.error("【新增编辑用户信息】参数不正确,sysUserInfoForm={}",sysUserInfoForm);
			throw new AuthException(ResultEnum.PARAM_ERROR.getCode(),bindingResult.getFieldError().getDefaultMessage());
		}
    	
    	SysUser sysUser = null;
    	
    	try {
    		if(StringUtils.isEmpty(sysUserInfoForm.getUid())){
        		sysUser = new SysUser();
        		BeanUtils.copyProperties(sysUserInfoForm, sysUser, BeanCopyUtil.getNullOrIgnorePropertyNames(sysUserInfoForm, null));
        		sysUser.setUid(KeyUtil.getUUIDKey());
        		sysUser.setSalt(RandomValidateCode.getRandomString(8));
        		sysUser.setAccountPwd(StrEncryptUtil.md5(Const.INIT_ACCOUNT_PWD + sysUser.getSalt()));
        		//sysUser.setCreateUser(ShiroKit.getUserId());
        		sysUserService.insertSelective(sysUser);
        	}else{
        		sysUser = sysUserService.selectByPrimaryKey(sysUserInfoForm.getUid());
        		if(null != sysUser){
        			BeanUtils.copyProperties(sysUserInfoForm, sysUser, BeanCopyUtil.getNullOrIgnorePropertyNames(sysUserInfoForm, null));
        			sysUser.setUpdateTime(new Date());
        			//sysUser.setUpdateUser(ShiroKit.getUserId());
        			
        			sysUserService.updateByPrimaryKey(sysUser);
        		}else{
        			log.error("【编辑用户信息】操作出错,记录不存在,sysUser={},sysUserInfoForm={}",sysUser,sysUserInfoForm);
    				throw new AuthException(ResultEnum.NOT_EXIST);
        		}
        	}
    		
    		sysUser.setAccountPwd(null);
    		sysUser.setSalt(null);
    		
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【新增编辑用户信息】操作出错,error={},sysUserInfoForm={}",e.getMessage(),sysUserInfoForm);
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
		
		return ResultVOUtil.success(sysUser);
    	
    }
    
    @ApiOperation(value = "删除用户")
    @GetMapping("/delSysUserInfoByUid/{uid}")
    public ResultVO<Object> delSysUserInfoByUid(@PathVariable String uid){
    	try {
			SysUser sysUser = sysUserService.selectByPrimaryKey(uid);
			
			if(null != sysUser){
    			sysUser.setAccountStatus("1");
    			sysUser.setUpdateTime(new Date());
    			//sysUser.setUpdateUser(ShiroKit.getUserId());
    			sysUserService.updateByPrimaryKeySelective(sysUser);
    		}else{
    			log.error("【删除用户信息】操作出错,记录不存在,uid={}",uid);
				throw new AuthException(ResultEnum.NOT_EXIST);
    		}
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【删除用户信息】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
    	return ResultVOUtil.success();
    }
    
    @ApiOperation(value = "锁定用户")
    @GetMapping("/lockSysUserByUid/{uid}")
    public ResultVO<Object> lockSysUserByUid(@PathVariable String uid){
    	try {
			SysUser sysUser = sysUserService.selectByPrimaryKey(uid);
			
			if(null != sysUser){
    			sysUser.setAccountStatus("2");
    			sysUser.setUpdateTime(new Date());
    			//sysUser.setUpdateUser(ShiroKit.getUserId());
    			sysUserService.updateByPrimaryKeySelective(sysUser);
    		}else{
    			log.error("【删除用户信息】操作出错,记录不存在,uid={}",uid);
				throw new AuthException(ResultEnum.NOT_EXIST);
    		}
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【删除用户信息】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
    	return ResultVOUtil.success();
    }
    
    @ApiOperation(value = "解锁用户")
    @GetMapping("/unLockSysUserByUid/{uid}")
    public ResultVO<Object> unLockSysUserByUid(@PathVariable String uid){
    	try {
			SysUser sysUser = sysUserService.selectByPrimaryKey(uid);
			
			if(null != sysUser){
    			sysUser.setAccountStatus("0");
    			sysUser.setUpdateTime(new Date());
    			//sysUser.setUpdateUser(ShiroKit.getUserId());
    			sysUserService.updateByPrimaryKeySelective(sysUser);
    		}else{
    			log.error("【删除用户信息】操作出错,记录不存在,uid={}",uid);
				throw new AuthException(ResultEnum.NOT_EXIST);
    		}
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【删除用户信息】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
    	return ResultVOUtil.success();
    }
    
    @ApiOperation(value = "查询用户角色列表")
    @GetMapping("/getUserRolesByUid/{uid}")
    public ResultVO<Object> getUserRolesByUid(@PathVariable String uid){
    	
    	List<UserRolesInfoDTO> userRolesList = null;
    	
    	UserRolesInfoDTO dto = null;
    	
    	try {
			userRolesList = sysUserService.selectUserRolesInfoByUid(uid);
			
			if(userRolesList.size() > 0){
				dto = userRolesList.get(0);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【查询用户角色列表】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
    	
    	return ResultVOUtil.success(dto);
    }
    
    @ApiOperation(value = "新增编辑用户角色")
    @PostMapping("/addOrEditUserRolesInfo")
    public ResultVO<Object> addOrEditUserRolesInfo(@RequestBody UserRolesInfoForm userRolesInfoForm, BindingResult bindingResult){
    	if(bindingResult.hasErrors()){
			log.error("【新增编辑用户角色】参数不正确,userRolesInfoForm={}",userRolesInfoForm);
			throw new AuthException(ResultEnum.PARAM_ERROR.getCode(),bindingResult.getFieldError().getDefaultMessage());
		}
    	
    	SysUserRoles sysUserRoles = new SysUserRoles();
    	
    	try {
    		
        	BeanUtils.copyProperties(userRolesInfoForm, sysUserRoles, BeanCopyUtil.getNullOrIgnorePropertyNames(userRolesInfoForm, null));
        	sysUserRoles.setId(KeyUtil.getUUIDKey());
        	//先删除用户的角色
        	sysUserService.deleteUserRolesByUserId(userRolesInfoForm.getUserId());
        	//再保存新的角色
        	sysUserService.addOrEditUserRoles(sysUserRoles);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【新增编辑用户角色】操作出错,error={},userRolesInfoForm={}",e.getMessage(),userRolesInfoForm);
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
    	return ResultVOUtil.success(sysUserRoles);
    }
    
    @ApiOperation(value = "删除用户已有角色")
    @GetMapping("/deleteUserRolesByRid/{rid}")
    public ResultVO<Object> deleteUserRolesByRid(@PathVariable String rid){
    	try {
			sysUserService.deleteUserRolesById(rid);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【删除用户角色】操作出错,rid={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
    	
    	return ResultVOUtil.success();
    }
    
    @ApiOperation(value = "重置登录密码")
    @GetMapping("/resetUserPwd/{uid}")
    public ResultVO<Object> resetUserPwd(@PathVariable String uid){
    	try {
			SysUser sysUser = sysUserService.selectByPrimaryKey(uid);
			
			if(null != sysUser){
				sysUser.setSalt(RandomValidateCode.getRandomString(8));
        		sysUser.setAccountPwd(StrEncryptUtil.md5(Const.INIT_ACCOUNT_PWD + sysUser.getSalt()));
    			sysUser.setUpdateTime(new Date());
    			//sysUser.setUpdateUser(ShiroKit.getUserId());
    			sysUserService.updateByPrimaryKeySelective(sysUser);
    		}else{
    			log.error("【重置登录密码】操作出错,记录不存在,uid={}",uid);
				throw new AuthException(ResultEnum.NOT_EXIST);
    		}
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【重置登录密码】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
    	return ResultVOUtil.success("系统初始密码：" + Const.INIT_ACCOUNT_PWD);
    }
    
    @ApiOperation(value = "用户修改登录密码")
    @PostMapping("/modifyPassword/{userId}")
	public ResultVO<Object> modifyPassword(@PathVariable String userId,@Valid @RequestBody ChangePasswordForm changePasswordForm,BindingResult bindingResult){
		
		if (bindingResult.hasErrors()) {
			log.error("【用户密码修改】参数不正确,enterApplyForm={}", changePasswordForm);
			throw new AuthException(ResultEnum.PARAM_ERROR.getCode(),
					bindingResult.getFieldError().getDefaultMessage());
		}
		
		try {
			SysUser sysUser = sysUserService.selectByPrimaryKey(userId);
			
			if(null == sysUser){
				log.error("【用户密码修改】用户不存在,userId={}", userId);
				throw new AuthException(ResultEnum.ACCOUNT_NO);
			}
			
			if(!sysUser.getAccountPwd().equals(StrEncryptUtil.md5(changePasswordForm.getOldPassword()+sysUser.getSalt()))){
				log.error("【用户密码修改】旧密码错误,enterApplyForm={}", changePasswordForm);
				throw new AuthException(ResultEnum.ACCOUNT_OLD_PWD_ERROR);
			}
			
			String saltStr = StrEncryptUtil.salt(8);//获取8位的salt
			sysUser.setAccountPwd(StrEncryptUtil.md5(changePasswordForm.getNewPassword()+saltStr));
			sysUser.setSalt(saltStr);
			sysUser.setUpdateTime(new Date());
			sysUserService.updateByPrimaryKeySelective(sysUser);
			
			
			//清空redis中的jwt
			stringRedisTemplate.delete(JsonWebTokenUtil.REDIS_PREFIX + sysUser.getAccount());
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("【用户修改登录密码】操作出错,error={}",e.getMessage());
			throw new AuthException(ResultEnum.OPERATION_FAIL);
		}
		
		return ResultVOUtil.success();
    }
    
    @ApiOperation(value = "获取值守通讯录")
    @GetMapping("/getDutyContactsList")
    public ResultVO<Object> getDutyContactsList(@RequestParam(required = false,defaultValue="") String deptId){
    	Map<String, Object> map = new HashMap<String, Object>();
    	map.put("deptId", deptId);
    	List<SysUserDTO> sysUserList = sysUserService.getUserList(map);
    	List<DutyContactsDTO> dtoList = new ArrayList<DutyContactsDTO>();
    	DutyContactsDTO dto = null;
    	for(SysUserDTO sysUserDTO : sysUserList){
    		dto = new DutyContactsDTO();
    		BeanUtils.copyProperties(sysUserDTO, dto, BeanCopyUtil.getNullOrIgnorePropertyNames(sysUserDTO, null));
    		
    		dtoList.add(dto);
    	}
    	
    	return ResultVOUtil.success(dtoList);
    }

}
