package com.platform.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.util.StringUtil;
import com.platform.dao.SysUserDao;
import com.platform.entity.*;
import com.platform.enums.ResultCodeEnum;
import com.platform.enums.SysRoleEnum;
import com.platform.exception.CommonBaseException;
import com.platform.page.Page;
import com.platform.page.PageHelper;
import com.platform.service.SysDeptService;
import com.platform.service.SysRoleService;
import com.platform.service.SysUserRoleService;
import com.platform.service.SysUserService;
import com.platform.utils.*;
import com.platform.vos.CurrentUserLoginVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;


/**
 * 系统用户
 *
 * @author 李鹏军
 * @email 939961241@qq.com
 * @date 2016年12月18日 上午9:46:09
 */
@Service("sysUserService")
@Slf4j
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private ZhiHouseService zhiHouseService;

    @Autowired
    private FdkkService fdkkService;


    @Override
    public Long getUserNumOfDept(Long dptId) {
        return sysUserDao.getUserNumOfDept(dptId);
    }

    @Override
    public IPage<SysUserEntity> getCompanyStaffList(String staffName, String deptName,
                                                    long pageNum, long pageSize , Long deptId , boolean excludeSuperAdmin) {
        IPage<SysUserEntity> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNum , pageSize);
        QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
        if(excludeSuperAdmin){
            //不捞取超级管理员
            queryWrapper.ne("role.role_id" , 5);
        }
        if(StringUtils.isNotBlank(staffName)){
            queryWrapper.like("sysUser.username" , staffName);
        }
        if(StringUtils.isNotBlank(deptName)){
            queryWrapper.like("dept.name" , deptName);
        }
        if(null != deptId){
            //只有非超级管理员才会上送deptId，用于过滤本公司的部门数据
            queryWrapper.eq("sysUser.dept_id" , deptId);
        }
        queryWrapper.orderByDesc("sysUser.create_time");

        return sysUserDao.getCompanyUserList(page , queryWrapper);
    }

    @Override
    public List<String> queryAllPerms(Long userId) {
        return sysUserDao.queryAllPerms(userId);
    }

    @Override
    public List<Long> queryAllMenuId(Long userId) {
        return sysUserDao.queryAllMenuId(userId);
    }

    @Override
    public IPage<SysUserEntity> getSysUserList(List<Long> deptIdList , String key , long brandId , long pageNum, long pageSize) {

        QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sysUser.status" , 1);
        if(!CollectionUtils.isEmpty(deptIdList)){
            queryWrapper.and(wrapper->wrapper.in("sysUser.dept_id" , deptIdList).or().eq("sysUser.is_platform_streamer",true));
        }
        if(StringUtils.isNotBlank(key)){
            queryWrapper.like("sysUser.username" , key);
        }
        IPage<SysUserEntity> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNum , pageSize);
        return sysUserDao.getBindList(page , queryWrapper,brandId);
    }


    @Override
    public SysUserEntity queryByMobileAndDeptId(String mobile, long deptId) {
        return sysUserDao.queryByMobileAndDeptId(mobile , deptId);
    }

    @Override
    public SysUserEntity queryByUserMobile(String mobile) {
        return sysUserDao.queryByUserMobile(mobile);
    }

    @Override
    public SysUserEntity queryByUserName(String username) {
        return sysUserDao.queryByUserName(username);
    }

    @Override
    public SysUserEntity queryObject(Long userId) {
        return sysUserDao.queryObject(userId);
    }

    @Override
    public List<SysUserEntity> queryList(Map<String, Object> map) {
        return sysUserDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return sysUserDao.queryTotal(map);
    }

    @Override
    //@Transactional(isolation = Isolation.READ_COMMITTED)
    @Transactional
    public void save(SysUserEntity user) {
        //检查角色是否越权
        checkRole(user);

        user.setCreateTime(new Date());
        //sha256加密
        user.setPassword(new Sha256Hash(Constant.DEFAULT_PASS_WORD).toHex());
        sysUserDao.save(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());

        //保存用户与品牌关系
//        sysUserBrandService.saveOrUpdate(user.getUserId(), user.getBrandIdList());
    }

    @Override
    @Transactional
    public void addNewUserWithoutCheck(SysUserEntity user) {
        user.setCreateTime(new Date());
        int insert = sysUserDao.save(user);
        if(insert !=  1){
            log.error("新增系统管理员[{}]失败" , user.getUsername());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateUserAndAddDeptAdminRolls(SysUserEntity userEntity) {
        if(null == userEntity){
            return -1;
        }
        int update = sysUserDao.update(userEntity);
        if(update != 1){
            log.error("更新用户数据(部门id)失败");
            throw new CommonBaseException(ResultCodeEnum.D101 , "更新用户数据失败");
        }

        //默认开通公司管理员的权限
        int insert = sysUserRoleService.onlySave(userEntity.getUserId(), 7L);
        if(insert != 1){
            log.error("给用户[{}]开通普通管理员角色失败" , userEntity.getMobile());
            throw new CommonBaseException(ResultCodeEnum.D101 , "新增普通管理员权限失败");
        }
        return 1;
    }


    @Override
    public void updateOnly(SysUserEntity user) {
        sysUserDao.update(user);
    }

    @Override
    @Transactional
    public void update(SysUserEntity user) {
        if(ObjectUtils.isEmpty(user.getUserId())){
            throw new CommonBaseException(500,"id 为空！");
        }
        if(user.getRoleIdList().contains(SysRoleEnum.PLATFORM_STREAMER.getCode())){
            user.setIsPlatformStreamer(true);
            user.setRoleIdList(Collections.singletonList(8L));
        }else{
            user.setIsPlatformStreamer(false);
        }
        SysUserEntity userEntity = queryObject(user.getUserId());
        //检查角色是否越权
        checkRole(user);

        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(new Sha256Hash(Constant.DEFAULT_PASS_WORD).toHex());
        } else {
            user.setPassword(new Sha256Hash(user.getPassword()).toHex());
        }

        sysUserDao.update(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());

        // 更新企业员工数
        if (!StringUtils.equals(userEntity.getDeptId()+"",user.getDeptId()+"")) {
            if (!ObjectUtils.isEmpty(userEntity.getDeptId()) && userEntity.getDeptId() != -1L) {
                Long userNumOfDept = getUserNumOfDept(userEntity.getDeptId());
                if(!ObjectUtils.isEmpty(userNumOfDept)){
                    SysDeptEntity deptEntity = sysDeptService.queryObject(userEntity.getDeptId());
                    deptEntity.setCurStaffNum(userNumOfDept.intValue());
                    sysDeptService.update(deptEntity);
                }
            }
            if (!ObjectUtils.isEmpty(user.getDeptId()) && user.getDeptId() != -1L) {
                Long userNumOfDept = getUserNumOfDept(user.getDeptId());
                if(!ObjectUtils.isEmpty(userNumOfDept)){
                    SysDeptEntity deptEntity = sysDeptService.queryObject(user.getDeptId());
                    deptEntity.setCurStaffNum(userNumOfDept.intValue());
                    sysDeptService.update(deptEntity);
                }
            }
        }
    }

    @Override
    @Transactional
    public void deleteBatch(Long[] userId) {
        sysUserDao.deleteBatch(userId);
    }

    @Override
    public void updatePassword(String mobile,String password, String fdkkPassword, String fdkkUser) {
        CurrentUserLoginVo userEntity = ShiroUtils.getUserEntity();
        ResponseEntity<String> loginResult;
        if(!ObjectUtils.isEmpty(password)){
            // 对指房宝密码解密
            password = Base64Converter.decode(Base64Converter.subText(password));
            // 登录指房宝进行当前密码校验
            loginResult = zhiHouseService.login(mobile, password);
            if(loginResult.getStatusCode()!= HttpStatus.OK){
                throw new CommonBaseException(500,"请求失败");
            }
        }
        if(!ObjectUtils.isEmpty(fdkkPassword)){
            // 对4d看看密码解密
            String decryptFdkkPassword = Base64Converter.decode(Base64Converter.subText(fdkkPassword));
            // 登录4dkankan
            loginResult = fdkkService.login(fdkkUser,decryptFdkkPassword);
            if(loginResult.getStatusCode()!= HttpStatus.OK){
                throw new CommonBaseException(500,"请求失败");
            }
            JSONObject result = JSONObject.parseObject(loginResult.getBody());
            if (result.getInteger("code") == 3015) {
                throw new CommonBaseException(500, "此账号未注册，请先注册后再绑定。");
            }
            if(result.getInteger("code") == 3014){
                throw new CommonBaseException(500, "四维看看账号密码有误，请重新输入。");
            }
            if (result.getInteger("code") != Result.CODE_SUCCESS) {
                throw new CommonBaseException(500, "请求失败，请重试");
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userEntity.getUserId());
        if(!ObjectUtils.isEmpty(fdkkPassword)){
            map.put("fdkkUser", fdkkUser);
            map.put("fdkkPassword", fdkkPassword);
        }
        sysUserDao.updatePassword(map);
    }

    /**
     * 检查角色是否越权
     */
    private void checkRole(SysUserEntity user) {
        //如果不是超级管理员，则需要判断用户的角色是否自己创建
        if (user.getCreateUserId() == Constant.SUPER_ADMIN || CollectionUtils.isEmpty(user.getRoleIdList())) {
            return;
        }
        List<Long> roleIdList = new ArrayList<>();
       /*         //查询用户创建者[user.getCreateUserId()]所有创建的角色列表
        List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

        //再带上创建者自己当前的角色
        List<Long> curRoleList = sysUserRoleService.queryRoleIdList(user.getCreateUserId());
        if(!CollectionUtils.isEmpty(curRoleList)){
            roleIdList.addAll(curRoleList);
        }*/
        //这里还需要获取role_id大于最高权限的所有role_id
        List<Long> roleList = sysUserRoleService.queryRoleIdList(user.getCreateUserId());
        long cur = 10000000L;
        for(Long roleId : roleList){
            if(null == roleId){
                continue;
            }
            if(roleId.compareTo(cur) < 0){
                cur = roleId;
            }
        }
        if(cur == 10000000L){
            return;
        }
        //这里获取系统默认以及个人账户创建的角色列表
        List<SysRoleEntity> sysRoleEntityList= sysRoleService.queryGreaterRoleById(cur , user.getCreateUserId());
        if(!CollectionUtils.isEmpty(sysRoleEntityList)){
            for (SysRoleEntity entity : sysRoleEntityList){
                roleIdList.add(entity.getRoleId());
            }
        }
        //判断是否越权
        if (!roleIdList.containsAll(user.getRoleIdList())) {
            throw new RRException("创建者无权限创建此角色的员工");
        }
    }


    @Override
    public Page<UserWindowDto> findPage(UserWindowDto userWindowDto, int pageNum) {
        PageHelper.startPage(pageNum, Constant.pageSize);
        sysUserDao.queryListByBean(userWindowDto);
        return PageHelper.endPage();
    }

    @Override
    public List<SysUserEntity> getSysUserListByDeptIds(List<Long> deptList) {
        if(ObjectUtils.isEmpty(deptList)){
            return new ArrayList<>();
        }
        return sysUserDao.getSysUserListByDeptIds(deptList);
    }
}
