package cn.wisenergy.service.impl;


import cn.wisenergy.common.utils.Md5Util;
import cn.wisenergy.common.utils.exception.BASE_RESP_CODE_ENUM;
import cn.wisenergy.common.utils.exception.BaseCustomException;
import cn.wisenergy.mapper.WorkRoleMapper;
import cn.wisenergy.mapper.WorkUserMapper;
import cn.wisenergy.mapper.WorkUserRoleMapper;
import cn.wisenergy.model.app.*;
import cn.wisenergy.model.dto.*;
import cn.wisenergy.model.enums.LevelEnum;
import cn.wisenergy.model.enums.ManagerEnum;
import cn.wisenergy.service.WorkCentreService;
import cn.wisenergy.service.WorkDeptService;
import cn.wisenergy.service.WorkSubmitAdoptService;
import cn.wisenergy.service.WorkUserService;
import cn.wisenergy.service.utils.UserRoleLevelUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <p>
 * 服务实现类
 *
 * @author chenqi
 * @since 2021-01-19
 */
@Service
@Slf4j
public class WorkUserServiceImpl implements WorkUserService {
    @Autowired
    private WorkUserMapper workUserMapper;

    @Autowired
    private WorkSubmitAdoptService workSubmitAdoptService;

    @Autowired
    private WorkDeptService workDeptService;

    @Autowired
    private WorkCentreService workCentreService;


    @Autowired
    private WorkRoleMapper workRoleMapper;

    @Autowired
    private WorkUserRoleMapper workUserRoleMapper;

    private static final String LOGIN_SOURCE = "PC";

    // 用户在职状态码
    private static final Integer ON_THE_JOB_STATUS = 1;


    @Override
    public WorkUser getById(Integer id) {
        log.info("WorkUserServiceImpl[]getById[]input.param.id:{}" + id);
        if (null == id) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        WorkUser workUser = workUserMapper.selectById(id);
        if (null == workUser) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_USER_INFO_FAIL);
        }
        return workUser;
    }

    @Override
    public WorkUser getDeptManagerByIds(List<Integer> ids) {
        log.info("WorkUserServiceImpl[]getDeptManagerByIds[]input.param.ids:{}" + ids);
        if (CollectionUtils.isEmpty(ids)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        QueryWrapper<WorkUser> wrapper = new QueryWrapper<>();
        wrapper.eq("level", 2);
        wrapper.in("id", ids);
        return workUserMapper.selectOne(wrapper);

    }

    @Override
    public ResultUser changePassword(Integer userId, String oldPassword, String newPassword) {
        log.info("WorkUserServiceImpl[]changePassword[]input.param{}" + userId + oldPassword + newPassword);
        if (userId == null || StringUtils.isEmpty(oldPassword) || StringUtils.isEmpty(newPassword)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }

        //新密码与旧密码相同
        if (oldPassword.equals(newPassword)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.NEW_PASSWORD_IS_HTE_SAME_OLD_PASSWORD);
        }
        //根据主键和密码查找
        Map<String, Object> map = new HashMap<>();
        map.put("id", userId);
        map.put("password", Md5Util.digestMD5(oldPassword));
        WorkUser user = workUserMapper.getUserInfo(map);
        if (user == null) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.UPDATE_PASSWORD_FAIL_OLD_PASSWORD_ERROR);
        }
        //更新信息
        user.setPassword(Md5Util.digestMD5(newPassword));
        Integer count = workUserMapper.updateUserInfo(user);
        if (count == null) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_UPDATE_PASSWORD_FAIL);
        }
        return getResultUser(user);
    }

    @Override
    public OrganizationDto getOrganizationStructure() {
        log.info("WorkUserServiceImpl[]getOrganizationStructure[]");
        OrganizationDto organizationDto = new OrganizationDto();
        PageHelper.clearPage();
        List<OrganizationStructureDto> allDeptByAllCentreId = workDeptService.getAllDeptByAllCentreId();
        QueryWrapper<WorkUser> wrapper = new QueryWrapper<>();
        wrapper.eq("status", 1);
        List<WorkUser> workUsers = workUserMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(workUsers)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.DEPT_NOT_HAVE_USER);
        }

        UserDto userDto;
        for (OrganizationStructureDto organizationStructureDto : allDeptByAllCentreId) {
            List<DeptUserDto> deptUserDtos = organizationStructureDto.getDeptUserDtos();
            for (DeptUserDto deptUserDto : deptUserDtos) {
                List<UserDto> userDtos = new ArrayList<>();
                for (WorkUser workUser : workUsers) {
                    if (workUser.getDeptId().equals(deptUserDto.getDeptId())) {
                        userDto = getUserDto(workUser);
                        userDtos.add(userDto);
                    }
                }
                deptUserDto.setUserDtos(userDtos);
            }
        }
        organizationDto.setOrganizationStructureDtos(allDeptByAllCentreId);

        List<WorkUser> users = workUserRoleMapper.getUserRoleDeptDtoByRoleId(1);
        if (!CollectionUtils.isEmpty(users)) {
            List<OrganizationStructureDto> allDeptByAllCentre = workDeptService.getAllDeptByAllCentreId();
            UserDto userDto1;
            for (OrganizationStructureDto organizationStructureDto : allDeptByAllCentre) {
                List<DeptUserDto> deptUserDtos = organizationStructureDto.getDeptUserDtos();
                for (DeptUserDto deptUserDto : deptUserDtos) {
                    List<UserDto> UserDtos1 = new ArrayList<>();
                    for (WorkUser user : users) {
                        if (user.getDeptId().equals(deptUserDto.getDeptId())) {
                            userDto1 = getUserDto(user);
                            UserDtos1.add(userDto1);
                        }
                    }
                    deptUserDto.setUserDtos(UserDtos1);
                }
            }
            organizationDto.setOrganizationDtos(allDeptByAllCentre);
        }
        return organizationDto;
    }


    @Override
    public AllRoleAndUserRoleDto getUserRoleDto(Integer userId, Integer page, Integer pageSize, Integer status, String key) {
        log.info("WorkUserServiceImpl[]getUserRoleDto[]input.param.userId:{},page:{},pageSize:{},status:{},key:{}" + userId, page, pageSize, status, key);
        if (!UserRoleLevelUtils.isManagerLevel(userId, LevelEnum.ACCOUNTMANAGEMENT.getLevelName())) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.THE_USER_NOT_MANAGER_PLASE_MANAGER_LOGIN);
        }
        page = page == null ? 1 : page;
        pageSize = pageSize == null ? 10 : pageSize;
        Page<UserRoleDto> startPage = PageHelper.startPage(page, pageSize);
        List<UserRoleDto> userRoleDtos = workUserMapper.getUserRoleDto(status, key);
        if (CollectionUtils.isEmpty(userRoleDtos)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_DATA_IS_NULL);
        }
        List<WorkRole> workRoles = new ArrayList<>();
        WorkRole workRole = workRoleMapper.selectById(0);
        workRoles.add(workRole);
        for (UserRoleDto userRoleDto : userRoleDtos) {
            if (CollectionUtils.isEmpty(userRoleDto.getWorkRoles())) {
                userRoleDto.setWorkRoles(workRoles);
            }
        }
        PageInfo<UserRoleDto> pageInfo = startPage.toPageInfo();
        pageInfo.setList(userRoleDtos);
        List<WorkRole> allWorkRole = UserRoleLevelUtils.getAllWorkRole();
        if (CollectionUtils.isEmpty(allWorkRole)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_DATA_IS_NULL);
        }

        PageHelper.startPage(page, pageSize);
        AllRoleAndUserRoleDto allRoleAndUserRoleDto = new AllRoleAndUserRoleDto();
        allRoleAndUserRoleDto.setPageInfo(pageInfo);
        allRoleAndUserRoleDto.setWorkRoles(allWorkRole);
        return allRoleAndUserRoleDto;
    }

    @Transactional
    @Override
    public Boolean modifyRole(Integer userId, List<Integer> roleIds, Integer status) {
        log.info("WorkUserServiceImpl[]modifyRole[].input.param.userId:{},roleIds:{},status:{}" + userId, roleIds, status);
        PageHelper.clearPage();
        if (CollectionUtils.isEmpty(roleIds)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.CHOOSEATLEASTONEROLE);
        }
        if (UserRoleLevelUtils.levelIsRepeat(roleIds)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.DUPLICATEROLEPERMISSIONS);
        }
        if (null == userId) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        WorkUser workUser = workUserMapper.selectById(userId);
        if (null == workUser) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_DATA_IS_NULL);
        }
        WorkDept workDept = workDeptService.getById(workUser.getDeptId());
        WorkCentre centre = workCentreService.getCentreById(workDept.getCentreId());
        List<Integer> roles = workUserRoleMapper.getRole(userId);
        // 如果当前用户有部门和中心权限，则删除对应表的管理
        int DeptUpdateIndex = 0;
        int centreUpdateIndex = 0;

        if (!CollectionUtils.isEmpty(roles)) {
            for (Integer role : roles) {
                // 部门经理
                if (2 == role) {
                    workDeptService.updateManagerIdISNullById(workDept.getId());
                    System.out.println("部门经理被我设置为空了");
                    DeptUpdateIndex++;
                }
                // 中心管理
                if (3 == role) {
                    workCentreService.updateManagerIdIsNullById(centre.getId());
                    centreUpdateIndex++;
                }
            }
        }
        workUserRoleMapper.deleteByUserId(userId);
        int i = workUserMapper.updateStatusById(userId, status);
        if (i == 0) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.UPDATE_DATA_FAIL);
        }
        if (1 == roleIds.size() && 0 == roleIds.get(0)) {
            return true;
        }
        if (roleIds.size() > 1) {
            for (Integer roleId : roleIds) {
                if (roleId == 0) {
                    throw new BaseCustomException(BASE_RESP_CODE_ENUM.ORDINARY_MEMBERS_ARE_MANAGEMENT);
                }
            }
        }
        //判断当前是否已经有部门经理和中心管理
        for (Integer roleId : roleIds) {
            // 设置部门经理
            if (2 == roleId) {
                if (0 == DeptUpdateIndex && null != workDept.getDeptManagerId()) {
                    throw new BaseCustomException(BASE_RESP_CODE_ENUM.DEPARTMENT_MANAGER_ALREADY_EXISTS);
                }
                workDept.setDeptManagerId(userId);
                workDeptService.updateById(workDept);
            }
            // 设置中心管理员
            if (3 == roleId) {
                if (0 == centreUpdateIndex && null != centre.getCentreManagerId()) {
                    throw new BaseCustomException(BASE_RESP_CODE_ENUM.CENTERMANAGERALREADYEXISTS);
                }
                centre.setCentreManagerId(userId);
                workCentreService.updateById(centre);
            }
        }
        workUserRoleMapper.insertBatch(userId, roleIds);
        return true;
    }

    @Override
    public Boolean reSetPassword(Integer userId) {
        log.info("WorkUserServiceImpl[]reSetPassword[].input.userId" + userId);
        if (null == userId) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        // 验证用户是否存在
        WorkUser user = workUserMapper.getUserById(userId);
        WorkUser workUser = new WorkUser();
        workUser.setId(userId);
        if (null == user) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_USER_INFO_FAIL);
        }
        workUser.setPassword(Md5Util.digestMD5(user.getPhone()));
        int i = workUserMapper.updateById(workUser);
        return i>0;
    }

    @Override
    public ResultUser login(String loginName, String password, String source) {
        log.info("WorkUserServiceImpl[]login[].input.param" + loginName + password + source);
        if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(password)) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        //MD5加密
        String md5Password = Md5Util.digestMD5(password);

        HashMap<String, Object> map = new HashMap<>();
        map.put("loginName", loginName);
        map.put("password", md5Password);
        WorkUser user = workUserMapper.getUserInfo(map);
        if (null == user) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.USER_LOGIN_NAME_OR_PASSWORD_IS_ERROR);
        }
        // 是否离职状态
        if (user.getStatus() != ON_THE_JOB_STATUS) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.LEAVE_JOB_USER);
        }

        // 如果登录来源是PC,判断用户是不是管理员
        List<Integer> roles = UserRoleLevelUtils.getRole(user.getId());
        if (LOGIN_SOURCE.equals(source)) {
            if (roles.contains(ManagerEnum.NOT_MANAGER.getCode())) {
                throw new BaseCustomException(BASE_RESP_CODE_ENUM.THE_USER_NOT_MANAGER_PLASE_MANAGER_LOGIN);
            }
        }
        // 限制审核的天数
        WorkSubmitAdopt byId = workSubmitAdoptService.getById(1);

        //将用户对象转换为dto
        ResultUser resultUser = getResultUser(user);
        resultUser.setDay(byId.getSubmitTime());
        List<Integer> levelIds = UserRoleLevelUtils.getlevelIds(roles);
        List<WorkLevel> workLevels = UserRoleLevelUtils.getlevelByIds(levelIds);
        if (!CollectionUtils.isEmpty(workLevels)) {
            Collections.sort(workLevels);
            resultUser.setWorkLevels(workLevels);
        }
        return resultUser;
    }

    @Override
    public ResultUser getResultUserById(Integer userId) {
        log.info("UserServiceImpl[]getUserById[]input.param.userId" + userId);
        if (null == userId) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.INPUT_PARAM_IS_NULL);
        }
        WorkUser user = workUserMapper.getUserById(userId);
        //查询失败
        if (null == user) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_USER_INFO_FAIL);
        }
        ResultUser resultUser = getResultUser(user);
        log.info("UserServiceImpl[]getUserById[]get.user.info.success");
        return resultUser;
    }

    //获取用户传输实体
    private ResultUser getResultUser(WorkUser workUser) {
        log.info("WorkUSerServiceImpl[]getResultUser[]input.method");
        ResultUser resultUser = new ResultUser();
        try {
            BeanUtils.copyProperties(resultUser, workUser);
        } catch (Exception e) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_USER_INFO_FAIL);
        }
        return resultUser;
    }

    private UserDto getUserDto(WorkUser workUser) {
        log.info("WorkUSerServiceImpl[]getUserDto[]input.method");
        UserDto userDto = new UserDto();
        try {
            BeanUtils.copyProperties(userDto, workUser);
        } catch (Exception e) {
            throw new BaseCustomException(BASE_RESP_CODE_ENUM.QUERY_USER_INFO_FAIL);
        }
        return userDto;
    }

}
