/**
 * Copyright (c) 2018 人人开源 All rights reserved.
 * 
 * https://www.renren.io
 * 
 * 版权所有,侵权必究!
 */
package com.zt.modules.sys.service;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.PrettyPrinter;
import com.zt.common.constant.CacheKey;
import com.zt.common.constant.Constant;
import com.zt.common.db.query.QueryFilter;
import com.zt.common.exception.RenException;
import com.zt.common.service.BaseService;
import com.zt.common.servlet.Result;
import com.zt.common.utils.CacheUtils;
import com.zt.common.utils.TreeUtils;
import com.zt.core.context.User;
import com.zt.core.context.UserContext;
import com.zt.core.oss.service.ISysOssConfigService;
import com.zt.core.oss.service.ISysOssService;
import com.zt.core.security.BCryptPasswordEncoder;
import com.zt.core.security.Md5Utils;
import com.zt.core.sys.model.SysDept;
import com.zt.core.sys.model.SysUser;
import com.zt.core.sys.service.ISysUserService;
import com.zt.life.sys.dto.OssDto;
import com.zt.modules.sys.dao.SysUserDao;
import com.zt.modules.sys.dto.RoleDto;
import com.zt.modules.sys.dto.UserTreeDto;
import com.zt.modules.sys.enums.UserStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 系统用户
 *
 * @author hehz
 */
@Service
public class SysUserService extends BaseService implements ISysUserService {
    @Autowired
    private SysRoleUserService sysRoleUserService;
    @Autowired
    private SysJobUserService sysJobUserService;
    @Autowired
    private SysPostUserService sysPostUserService;
    @Autowired
    private SysDeptService sysDeptService;
    @Autowired
    private SysParamsService paramsService;
    @Autowired
    SysMapService sysMapService;
    @Autowired
    private ISysOssConfigService sysOssConfigService;
    public List page(QueryFilter queryFilter) {
        // 普通管理员,只能查询所属部门及子部门的数据
        User user = UserContext.getUser();
        if (!user.isSuperAdmin()) {
            queryFilter.addParam("deptIds", sysDeptService.getWithDescendantIds(user.getDeptId()));
        }
        // 查询
        return queryFilter.getPageList(baseDao.getList(queryFilter.getParams()));
    }
    public List list(QueryFilter queryFilter) {
        // 普通管理员,只能查询所属部门及子部门的数据
        User user = UserContext.getUser();
        if (!user.isSuperAdmin()) {
            queryFilter.addParam("deptIds", sysDeptService.getWithDescendantIds(user.getDeptId()));
        }
        return baseDao.getList(queryFilter.getParams());
    }
    /**
     * 用户树
     *
     * @return
     */
    public List getUserDeptTree() {
        List deptList = TreeUtils.toList(sysDeptService.getDeptTree());
        List list = deptList.stream().map(d -> {
            UserTreeDto dto = new UserTreeDto();
            dto.setId(d.getId());
            dto.setPid(d.getPid());
            dto.setName(d.getName());
            dto.setType(d.isCompany() ? 1 : 2);
            return dto;
        }).collect(Collectors.toList());
        List users = this.getByDeptIds(deptList.stream().map(d -> d.getId()).collect(Collectors.toList()));
        users.stream().forEach(u -> {
            UserTreeDto dto = new UserTreeDto();
            dto.setId(u.getId());
            dto.setPid(u.getDeptId());
            dto.setName(u.getRealName());
            dto.setType(3);
            list.add(dto);
        });
        return TreeUtils.build(list);
    }
    public SysUser getByUsername(String username) {
        return baseDao.getByUsername(username);
    }
    public List checkUserArea(Long userId,String localServer) {
        return baseDao.checkUserArea(userId,localServer);
    }
    @Override
    @Cacheable(value = Constant.Cache.USER, key = "'id:' + #id")
    public SysUser get(Long id) {
/*        SysUser entity = baseDao.getEntity(id);
        return entity;*/
        return super.get(id);
    }
    /**
     * 根据部门ID查询
     */
    @Override
    public List getByDeptId(Long deptId) {
        return baseDao.selectList(new QueryWrapper().lambda().eq(SysUser::getDeptId, deptId));
    }
    /**
     * 根据部门ID查询
     */
    @Override
    public List getByDeptIds(List deptIds) {
        if (CollectionUtil.isNotEmpty(deptIds)) {
            return baseDao.getByDeptIds(deptIds);
            //return baseDao.selectList(new QueryWrapper().lambda().in(SysUser::getDeptId, deptIds));
        } else {
            return new ArrayList<>();
        }
    }
    @Transactional(rollbackFor = Exception.class)
    public void insert(SysUser entity) {
        if (this.getByUsername(entity.getUsername()) != null) {
            throw new RenException("用户名已存在!");
        }
        //entity.setStatus(UserStatus.ENABLE.getValue());
        // 密码加密
        String password = Md5Utils.hash(paramsService.getValue(Constant.ParamKey.INIT_PASSWORD_KEY));
        entity.setPassword(password);
        entity.setIsLocked(0);
        entity.setCompanyId(sysDeptService.getCompanyIdByDeptId(entity.getDeptId()));
        // 保存用户
        sysOssConfigService.updateOss(entity.getId(), entity.getFiles());
        sysOssConfigService.updateOss(entity.getId(), entity.getFiles2());
        super.insert(entity);
        sysPostUserService.saveOrUpdate(entity.getId(), entity.getPostIdList());
        sysJobUserService.saveOrUpdate(entity.getId(), entity.getJobIdList());
        sysMapService.saveOrUpdate("userTeamggroup", entity.getId(), entity.getTeamgroupIds());
        sysMapService.saveOrUpdate("userShip", entity.getId(), entity.getShipIds());
    }
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUser entity) {
        // 更新用户
        entity.setCompanyId(sysDeptService.getCompanyIdByDeptId(entity.getDeptId()));
        sysOssConfigService.updateOss(entity.getId(), entity.getFiles());
        sysOssConfigService.updateOss(entity.getId(), entity.getFiles2());
        super.update(entity);
        // 保存岗位用户关系
        sysPostUserService.saveOrUpdate(entity.getId(), entity.getPostIdList());
        // 保存职位用户关系
        sysJobUserService.saveOrUpdate(entity.getId(), entity.getJobIdList());
        sysMapService.saveOrUpdate("userTeamggroup", entity.getId(), entity.getTeamgroupIds());
        sysMapService.saveOrUpdate("userShip", entity.getId(), entity.getShipIds());
        // 处理缓存
        CacheUtils.remove(Constant.Cache.USER, CacheKey.USER_ID.getKey() + entity.getId());
    }
    @CacheEvict(value = Constant.Cache.USER, allEntries = true)
    public void delete(Long[] ids) {
        // 删除用户
        super.deleteLogic(ids);
        // 删除角色用户关系
        sysRoleUserService.deleteByUserIds(ids);
    }
    /**
     * 修改密码
     *
     * @param id          用户ID
     * @param newPassword 新密码
     */
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(Long id, String newPassword) {
//        newPassword = Md5Utils.hash(newPassword);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        newPassword = encoder.encode(newPassword);
        SysUser entity = get(id);
        if (entity != null) {
            entity.setPassword(newPassword);
            baseDao.updatePassword(entity);
            // 处理缓存
            CacheUtils.remove(Constant.Cache.USER, CacheKey.USER_ID.getKey() + id);
        }
    }
    /**
     * 重置用户密码
     *
     * @param id
     */
    public void resetPassword(Long id) {
        updatePassword(id, paramsService.getValue(Constant.ParamKey.INIT_PASSWORD_KEY));
    }
    /**
     * 登录验证修改当前用户的状态
     *
     * @param id
     * @param loginErrorCount
     * @param isLocked
     * @param lastLoginErrorTime
     */
    public void updateLogin(Long id, Integer loginErrorCount, Integer isLocked, Date lastLoginErrorTime) {
        return;
        //baseDao.updateLogin(id, loginErrorCount, isLocked, lastLoginErrorTime);
    }
    public List isGetByUsernameList(String username, Long unitid, String code, String password) {
        List getByUsernameList = baseDao.isGetByUsernameList(username, unitid, code, password);
        return getByUsernameList;
    }
    public List isDomainName(String code) {
        return baseDao.isDomainName(code);
    }
    public Map adminRole() {
        //User sysUser = new User();
        Map sysUser = new Hashtable();
        sysUser.put("isAdmin", false);
        sysUser.put("isAssistant", false);
        List roles = sysRoleUserService.getUserRoles(UserContext.getUser().getId());
        if (roles != null && roles.size() > 0) {
            if (roles.stream().filter(p -> p.getCode().equals("xtglybm") || p.getCode().equals("all")).count() > 0) {
                sysUser.put("isAdmin", true);
            }
        }
        return sysUser;
    }
    public User userRoleInfo(String username, String systemId) {
        Long userId = null;
        if (username == null)
            userId = UserContext.getUser().getId();
        User user = baseDao.userRoleInfo(userId, username, systemId);
        return user;
    }
    public String getRoles() {
        Long userId = UserContext.getUser().getId();
        return baseDao.getRoles(userId);
    }
    public String getRoleNames(Long userId) {
        return baseDao.getRoleNames(userId);
    }
    public List getNewConnectUser(String newShipTeam) {
        return baseDao.getNewConnectUser(newShipTeam);
    }
    public Integer checkTestHome(String systemId) {
        Long userId = UserContext.getUser().getId();
        Integer num =  baseDao.checkTestHome(systemId,userId);
        return num;
    }
    public List getUsersList(String type, String deptId) {
        List list = baseDao.getUsersList(type,deptId);
        return list;
    }
    public String getUsersName(String id) {
        return baseDao.getUsersName(id);
    }
    public String getNames(String ids) {
        String[] NamesData = ids.split(",");
        List nameList =new ArrayList<>();
        for (String item : NamesData) {
            nameList.add(this.getUsersName(item));
        }
        String names = String.join(", ", nameList);
        return names;
    }
    public SysUser getUserInfo(Long id) {
        SysUser data = super.get(id);
        if (data != null) {
            OssDto ossDto= sysOssConfigService.getOssByBusiType(data.getId() , "users_avatar");
            if (ossDto != null) {
                data.setFiles(ossDto);
            }
            OssDto ossDto2= sysOssConfigService.getOssByBusiType(data.getId() , "users_sign");
            if (ossDto2 != null) {
                data.setFiles2(ossDto2);
            }
        }
        return data;
    }
}