package com.jpsoft.shinestar.modules.sys.controller;

import com.github.pagehelper.Page;
import com.jpsoft.shinestar.modules.base.entity.CompanyInfo;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.utils.DES3;
import com.jpsoft.shinestar.modules.common.utils.PojoUtils;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.sys.entity.Role;
import com.jpsoft.shinestar.modules.sys.entity.User;
import com.jpsoft.shinestar.modules.sys.entity.UserCompany;
import com.jpsoft.shinestar.modules.sys.entity.UserRole;
import com.jpsoft.shinestar.modules.sys.service.RoleService;
import com.jpsoft.shinestar.modules.sys.service.UserCompanyService;
import com.jpsoft.shinestar.modules.sys.service.UserRoleService;
import com.jpsoft.shinestar.modules.sys.service.UserService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/sys/user")
public class UserController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserCompanyService userCompanyService;

    @Value("${jwt.secret}")
    private String jwtSecret;

    @ApiOperation(value="创建空记录")
    @GetMapping("create")
    public MessageResult<User> create(){
        MessageResult<User> msgResult = new MessageResult<>();

        User user = new User();

        msgResult.setData(user);
        msgResult.setResult(true);

        return msgResult;
    }

    @ApiOperation(value="添加信息")
    @PostMapping("add")
    public MessageResult<User> add(@RequestBody User user, @RequestAttribute  String subject){
        MessageResult<User> msgResult = new MessageResult<>();

        try {
            if(StringUtils.isEmpty(user.getUserName())){
                throw new Exception("用户名不能为空!");
            }

            if(StringUtils.isEmpty(user.getPassword())){
                throw new Exception("密码不能为空!");
            }

            User existUser = userService.findByUserName(user.getUserName());

            if (existUser!=null){
                throw new Exception("用户名已存在!");
            }

            user.setId(UUID.randomUUID().toString());
            DES3 des3 = new DES3();
            user.setPassword(des3.encrypt(jwtSecret,user.getPassword()));
            user.setCreateBy(subject);
            user.setCreateTime(new Date());
            user.setDelFlag(false);

            int affectCount = userService.insert(user);

            if (affectCount > 0) {
                if(user.getRoles()!=null){
                    for (String roleId : user.getRoles()) {
                        UserRole ur = new UserRole();

                        ur.setId(UUID.randomUUID().toString());
                        ur.setUserId(user.getId());
                        ur.setRoleId(roleId);
                        ur.setCreateBy(subject);
                        ur.setCreateTime(new Date());
                        ur.setDelFlag(false);

                        userRoleService.insert(ur);
                    }
                }

                if(user.getOtherCompanyIds()!=null) {
                    affectCount = userCompanyService.deleteByUserId(user.getId());

                    for (String otherCompanyId : user.getOtherCompanyIds()) {
                        UserCompany uc = new UserCompany();

                        uc.setId(UUID.randomUUID().toString());
                        uc.setUserId(user.getId());
                        uc.setCompanyId(otherCompanyId);
                        uc.setCreateBy(subject);
                        uc.setCreateTime(new Date());
                        uc.setDelFlag(false);

                        affectCount += userCompanyService.insert(uc);
                    }
                }

                msgResult.setResult(true);
                msgResult.setData(user);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库添加失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="获取信息")
    @GetMapping("edit/{id}")
    public MessageResult<User> edit(@PathVariable("id") String id){
        MessageResult<User> msgResult = new MessageResult<>();

        try {
            User user = userService.get(id);

            if (user != null) {
                List<Role> roles = userRoleService.findRoleByUserId(user.getId());
                user.setRoles(roles.stream().map((role)->role.getId()).collect(Collectors.toList()));

                List<CompanyInfo> otherCompanys = userCompanyService.findByUserId(user.getId());
                user.setOtherCompanyIds(otherCompanys.stream().map((otherCompany)->otherCompany.getId()).collect(Collectors.toList()));

                msgResult.setResult(true);
                msgResult.setData(user);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库不存在该记录!");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="更新用户")
    @PostMapping("update")
    @Transactional(rollbackFor = Exception.class)
    public MessageResult<User> update(@RequestBody User user,@RequestAttribute String subject){
        MessageResult<User> msgResult = new MessageResult<>();

        try {
            //设置密码为空 不做修改
            user.setPassword(null);

            int affectCount = userService.update(user);

            user.setUpdateBy(subject);
            user.setUpdateTime(new Date());

            if(user.getRoles()!=null){
                affectCount += userRoleService.deleteByUserId(user.getId());

                for (String roleId : user.getRoles()) {
                    UserRole ur = new UserRole();

                    ur.setId(UUID.randomUUID().toString());
                    ur.setUserId(user.getId());
                    ur.setRoleId(roleId);
                    ur.setCreateBy(subject);
                    ur.setCreateTime(new Date());
                    ur.setDelFlag(false);

                    affectCount += userRoleService.insert(ur);
                }
            }

            if(user.getOtherCompanyIds()!=null) {
                affectCount += userCompanyService.deleteByUserId(user.getId());

                for (String otherCompanyId : user.getOtherCompanyIds()) {
                    UserCompany uc = new UserCompany();

                    uc.setId(UUID.randomUUID().toString());
                    uc.setUserId(user.getId());
                    uc.setCompanyId(otherCompanyId);
                    uc.setCreateBy(subject);
                    uc.setCreateTime(new Date());
                    uc.setDelFlag(false);

                    affectCount += userCompanyService.insert(uc);
                }
            }

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(user);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库更新失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="删除用户")
    @PostMapping("delete/{id}")
    public MessageResult<Integer> delete(@PathVariable("id") String id,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            User user = userService.get(id);
            user.setDelFlag(true);
            user.setUpdateBy(subject);
            user.setUpdateTime(new Date());

            int affectCount = userService.update(user);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value="批量删除")
    @PostMapping("batchDelete")
    public MessageResult<Integer> batchDelete(@RequestBody List<String> idList,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            int affectCount = 0;

            for (String id : idList) {
                User user = userService.get(id);
                user.setDelFlag(true);
                user.setUpdateBy(subject);
                user.setUpdateTime(new Date());

                affectCount += userService.update(user);
            }

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value="列表")
    @RequestMapping(value = "pageList",method = RequestMethod.POST)
    public MessageResult<Map> pageList(
            String userName,String realName,String companyId,String roleId,
            @RequestParam(name="pageIndex",defaultValue = "1") int pageIndex,
            @RequestParam(name="pageSize",defaultValue = "10") int pageSize,
            @RequestAttribute String subject){
        MessageResult<Map> msgResult = new MessageResult<>();

        Map<String,Object> searchParms = new HashMap<>();

        List<Sort> sortList = new ArrayList<>();
        sortList.add(new Sort("a.create_time","asc"));

        if (StringUtils.isNotEmpty(userName)) {
            searchParms.put("userName","%" + userName + "%");
        }

        if (StringUtils.isNotEmpty(realName)) {
            searchParms.put("realName","%" + realName + "%");
        }

        if (StringUtils.isNotEmpty(companyId)) {
            searchParms.put("companyId",companyId);
        }

        if (StringUtils.isNotEmpty(roleId)) {
            searchParms.put("roleId",roleId);
        }

        if (!userService.hasRole(subject,"SYSADMIN")) {
            Role role = roleService.findByName("SYSADMIN");
            searchParms.put("noRoleId", role.getId());
        }

        Page<User> page = userService.pageSearch(searchParms,pageIndex,pageSize,sortList);

        msgResult.setResult(true);

        msgResult.setData(PojoUtils.pageWrapper(page));

        return msgResult;
    }

    @ApiOperation(value="修改用户密码")
    @PostMapping("changeUserPassword")
    public MessageResult<Integer> changeUserPassword(String userId,String newPwd,@RequestAttribute String subject) {

        MessageResult<Integer> msgResult = new MessageResult<>();

        try {

            User user = userService.get(userId);

            DES3 des3 = new DES3();

            user.setPassword(des3.encrypt(jwtSecret, newPwd));
            user.setUpdateBy(subject);
            user.setUpdateTime(new Date());

            int affectCount = userService.update(user);

            if(affectCount>0){
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            }
            else{
                msgResult.setResult(false);
                msgResult.setMessage("修改失败！");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value="登录用户修改密码")
    @PostMapping("changeLoginPassword")
    public MessageResult<Integer> changeLoginPassword(
            @RequestParam(name="oldPassword",defaultValue = "") String oldPassword,
            @RequestParam(name="newPassword",defaultValue = "") String newPassword,
            @RequestAttribute String subject) {

        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            DES3 des3 = new DES3();
            User user = userService.get(subject);

            oldPassword = des3.encrypt(jwtSecret, oldPassword);
            //不相同
            if(!user.getPassword().equals(oldPassword)){
                throw new Exception("旧密码输入错误");
            }

            user.setPassword(des3.encrypt(jwtSecret, newPassword));
            user.setUpdateBy(subject);
            user.setUpdateTime(new Date());

            int affectCount = userService.update(user);

            if(affectCount>0){
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            }
            else{
                msgResult.setResult(false);
                msgResult.setMessage("修改失败！");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }
}
