package com.yfd.platform.system.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.system.domain.LoginUser;
import com.yfd.platform.system.domain.SysRole;
import com.yfd.platform.system.domain.SysUser;
import com.yfd.platform.system.mapper.SysRoleMapper;
import com.yfd.platform.system.mapper.SysUserMapper;
import com.yfd.platform.system.service.IUserService;
import com.yfd.platform.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户服务实现类
 * </p>
 *
 * @author zhengsl
 * @since 2021-10-27
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements IUserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;


    @Resource
    private PasswordEncoder passwordEncoder;
    /**
     * 用户头像图片路径
     */
    @Value("${file-space.system}")
    private String systempath;

    /**********************************
     * 用途说明:获取当前用户账号及名称
     * 参数说明
     * 返回值说明: 系统管理员[admin]
     ***********************************/
    @Override
    public String getUsername() {
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginuser = (LoginUser) authentication.getPrincipal();
        String acountname =
                loginuser.getUser().getNickname();
        return acountname;
        //return "admin";
    }

    @Override
    public Map<String, String> getNameInfo() {
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginuser = (LoginUser) authentication.getPrincipal();
        String nickname = loginuser.getUser().getNickname();
        String username = loginuser.getUser().getUsername();
        Map<String, String> map = new HashMap<>();
        map.put("nickname", nickname);
        map.put("username", username);
        return map;
    }

    @Override
    public SysUser getUserInfo() {
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginuser = (LoginUser) authentication.getPrincipal();
        return loginuser.getUser();
    }

    @Override
    public ResponseResult getLoginUserInfo() {
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginuser = (LoginUser) authentication.getPrincipal();
        SysUser user = loginuser.getUser();
        //根据用户ID获取组织
        Map<String, String> userInfo =
                sysUserMapper.getOrganizationByid(user.getId());
        List<SysRole> roles =
                sysRoleMapper.selectList(new QueryWrapper<SysRole>().inSql(
                        "id ", "SELECT roleid FROM sys_role_users ru WHERE ru" +
                                ".userid = '" + user.getId() + "'"));
        List<String> collect =
                roles.stream().map(SysRole::getRolename).collect(Collectors.toList());
        ResponseResult responseResult = new ResponseResult();
        responseResult.put("userInfo", userInfo);
        responseResult.put("roles", collect);
        responseResult.put("permissions", loginuser.getPermissions());
        return responseResult;
    }

    /***********************************
     * 用途说明：新增用户
     * 参数说明
     *sysUser   新增用户对象
     * id       创建者id
     * roleId   角色id
     * 返回值说明: 提示字符串
     ************************************/
    @Override
    public Map addUser(SysUser sysUser, String roleids) {
        //返回信息
        Map result = new HashMap<String, String>();
        sysUser.setId(IdUtil.fastSimpleUUID());
        //普通用户
        sysUser.setUsertype(1);
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //设置缺省密码
        String cryptPassword = passwordEncoder.encode("123456");
        sysUser.setPassword(cryptPassword);
        sysUser.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
        sysUser.setLastmodifier(getUsername());
        //账号有效
        sysUser.setStatus(1);
        //判断注册的登录账号是否存在
        if (isExistAccount(sysUser.getUsername())) {
            //新增用户
            boolean ok = this.save(sysUser);
            //新增用户分配权限
            if (StrUtil.isNotEmpty(roleids)) {
                String[] roles = roleids.split(",");
                for (String roleid : roles) {
                    //系统生成id
                    String id = IdUtil.fastSimpleUUID();
                    //新增sys_role_users表数据
                    ok = ok && sysUserMapper.addUserRoles(id, roleid,
                            sysUser.getId());
                }
            }
            //判断新增是否成功  消息提示
            if (ok) {
                result.put("status", "sucess");
                result.put("msg", "新增用户成功！");

            } else {
                result.put("status", "error");
                result.put("msg", "新增用户失败！");
            }
        } else {
            result.put("status", "error");
            result.put("msg", "用户账号已存在，不能重复添加！");
        }
        return result;
    }

    /***********************************
     * 用途说明:查询系统用户
     * 参数说明
     *page     分页集合参数
     *orgid    所属组织
     *username 用户名称
     * mobile  手机号
     * status  状态
     * 返回值说明: 用户分页集合
     ************************************/
    @Override
    public List<Map> list(String total, String size, String orgid,
                          String username, String mobile, String status) {
        List<Map> list = sysUserMapper.list(total, size, orgid, username,
                mobile, status);
        for (Map map : list) {
            List<Map> mapList =
                    sysUserMapper.getLevel(map.get("id").toString());
            String roleid = "";
            String level = "";
            String rolename = "";
            for (Map map1 : mapList) {
                roleid += map1.get("id") + ",";
                level += map1.get("level") + ",";
                rolename += map1.get("rolename") + ",";
            }
            if (roleid.endsWith(",")) {
                roleid = roleid.substring(0, roleid.length() - 1);
            }
            if (level.endsWith(",")) {
                level = level.substring(0, level.length() - 1);
            }
            if (rolename.endsWith(",")) {
                rolename = rolename.substring(0, rolename.length() - 1);
            }

            map.put("roleid", roleid);
            map.put("level", level);
            map.put("rolename", rolename);
        }
        return list; //返回分页集合
    }

    /***********************************
     * 用途说明：根据ID修改用户
     * 参数说明
     *sysUser   用户对象
     *roleids  角色id
     * 返回值说明: 是否更新成功
     ************************************/
    @Override
    public Map updateById(SysUser sysUser, String roleids) {
        //返回信息
        Map result = new HashMap<String, String>();
        //获取当前用户 最近修改者替换
        sysUser.setLastmodifier(getUsername());
        //获取当前时间 最近修改日期替换
        sysUser.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
        //根据修改
        boolean ok = this.updateById(sysUser);
        if (ok) {
            //将 roleids 按逗号分割为数组 roles，遍历每个角色ID。若用户原有角色中不包含该角色，调用 addUserRoles 方法向关联表（如 sys_role_users）插入新记录。
            if (StrUtil.isNotEmpty(roleids)) {
                String[] roles = roleids.split(",");
                List<String> list = sysUserMapper.getRoleid(sysUser.getId());
                for (String role : roles) {
                    if (!list.contains(role)) {
                        //系统生成id
                        String id = IdUtil.fastSimpleUUID();
                        //新增sys_role_users表数据
                        ok = ok && sysUserMapper.addUserRoles(id, role,
                                sysUser.getId());
                    }
                }
                //删除不包含的角色   调用 delInRoleUsersByUserid 方法，删除用户原有但不在 roles 中的角色关联
                sysUserMapper.delInRoleUsersByUserid(sysUser.getId(), roles);

            } else {
                //根据用户id 删除该用户角色关联
                ok = ok && sysUserMapper.delRoleUsersByUserid(sysUser.getId());
            }
            result.put("status", "sucess");
            result.put("msg", "用户信息修改成功！");
        } else {
            result.put("status", "error");
            result.put("msg", "用户信息修改失败！");
        }

        return result;
    }

    @Override
    public Map getOneById(String id) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        Map map = this.getMap(queryWrapper.eq("id", id));
        List<Map> mapList = sysUserMapper.getLevel(id);
        String roleid = "";
        String level = "";
        String rolename = "";
        for (Map map1 : mapList) {
            roleid += map1.get("id") + ",";
            level += map1.get("level") + ",";
            rolename += map1.get("rolename") + ",";
        }
        if (roleid.endsWith(",")) {
            roleid = roleid.substring(0, roleid.length() - 1);
        }
        if (level.endsWith(",")) {
            level = level.substring(0, level.length() - 1);
        }
        if (rolename.endsWith(",")) {
            rolename = rolename.substring(0, rolename.length() - 1);
        }

        map.put("roleid", roleid);
        map.put("level", level);
        map.put("rolename", rolename);
        return map;
    }

    /***********************************
     * 用途说明：用户分配角色
     * 参数说明
     *listId     用户id与角色id
     * 返回值说明: 判断是否添加成功
     ************************************/
    @Override
    public boolean setUserRoles(String roleid, String userids) {
        boolean isOk = true;
        //拆分userid 数组
        String[] temp = userids.split(",");
        //遍历userid
        for (String userid : temp) {
            //根据角色id与用户id查询
            List<Map> list = sysUserMapper.getRoleUsersByid(roleid, userid);
            //判断是否用户已分配此权限
            if (list.size() == 0) {
                //系统生成id
                String id = IdUtil.fastSimpleUUID();
                //新增sys_role_users表数据
                isOk = isOk && sysUserMapper.addUserRoles(id, roleid, userid);
            }
        }
        return isOk;
    }

    /***********************************
     * 用途说明：根据id删除用户
     * 参数说明
     *id         用户id
     * 返回值说明: 判断是否删除成功
     ************************************/
    @Override
    public boolean deleteById(String id) {
        //根据id查询
        SysUser sysUser = this.getById(id);
        //账号头像存储地址
        String imgName =
                systempath + File.separator + "user" + File.separator + sysUser.getAvatar();
        if ("admin".equals(sysUser.getUsername())) {
            return false;
        } else {
            boolean isOk = this.removeById(id);
            //判断是否删除成功
            if (isOk) {
                //根据用户id 删除该用户角色关联
                sysUserMapper.delRoleUsersByUserid(id);
                //判断是否存在 账号头像 存在删除
                if (StrUtil.isNotEmpty(sysUser.getAvatar())) {
                    FileUtil.del(imgName);
                }
                return false;
            } else {
                return false;
            }
        }
    }

    /***********************************
     * 用途说明：重置用户密码(管理员)
     * 参数说明
     *id        重置密码的 用户id
     * 返回值说明: 判断是重置成功
     ************************************/
    @Override
    public boolean resetPassword(String id) throws Exception {
        boolean isOk = false;
        //根据当前用户id 查询角色表的级别 currentUser.getUser() 获取当前用户id
        String level = sysUserMapper.getMaxLevel(id);
        //判断是否获取级别
        if (StrUtil.isNotEmpty(level)) {
            //判断当前用户级别 管理员及以上权限
            if (Integer.parseInt(level) <= 2) {
                UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
                //根据id 修改密码，密码修改时间，最近修改者，最近修改日期     将密码修改为 123456
                String cryptPassword = passwordEncoder.encode("123456");
                updateWrapper.eq("id", id).set("password", cryptPassword).set(
                        "pwdresettime",
                        new Timestamp(System.currentTimeMillis())).set(
                        "lastmodifydate",
                        new Timestamp(System.currentTimeMillis())).set(
                        "lastmodifier", getUsername());
                //是否修改成功
                isOk = this.update(updateWrapper);
            }
        }
        return isOk;
    }

    /***********************************
     * 用途说明：设置账号状态(管理员)
     * 参数说明
     *id        用户id
     * status   设置状态
     * 返回值说明: 判断是否设置成功
     ************************************/
    @Override
    public boolean setStatus(String id, String status) {
        boolean isOk = false;
        //根据当前用户id 查询角色表的级别 currentUser.getUser() 获取当前用户id
        String level = sysUserMapper.getMaxLevel(id);
        //判断当前用户级别 管理员及以上权限
        if (Integer.parseInt(level) <= 2) {
            UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
            //根据id修改用户状态，最近修改人，最近修改时间
            updateWrapper.eq("id", id).set("status", status).set(
                    "lastmodifydate",
                    new Timestamp(System.currentTimeMillis())).set(
                    "lastmodifier", getUsername());
            //是否修改成功
            isOk = this.update(updateWrapper);
        }
        return isOk;
    }

    /***********************************
     * 用途说明：上传用户头像
     * 参数说明
     * id           用户id
     * img          账号头像
     * 返回值说明:  判断是否上传
     ***********************************/
    @Override
    public boolean uploadAvatar(String id, MultipartFile img) {
        //根据id查询
        SysUser sysUser = this.getById(id);
        //账号头像存储地址
        String imgPath = systempath + "user";
        String avatar = sysUser.getAvatar();
        if (StrUtil.isNotBlank(avatar)) {
            String imgName = imgPath + File.separator + avatar;
            FileUtil.del(imgName);
        }
        //上传图片 并获取图片名称   (图片格式修改成png)
        String imgName = FileUtil.upload(img, imgPath,
                IdUtil.fastSimpleUUID() + "." + FileUtil.getExtensionName(img.getOriginalFilename())).getName();
        //修改 账户头像
        sysUser.setAvatar(imgName);
        //修改 最近修改者
        sysUser.setLastmodifier(getUsername());
        //修改 最近修改日期
        sysUser.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
        //更新用户表
        boolean isOk = this.updateById(sysUser);
        return isOk;
    }

    /***********************************
     * 用途说明：新增系统角色用户对照表 对用户分配角色(单个)
     * 参数说明
     * id       生成的id
     * roleid   角色id
     * userid   用户id
     * 返回值说明:
     ************************************/
    @Override
    public boolean addUserRoles(String roleid, String userid) {
        boolean isOk = true;
        //根据角色id与用户id查询
        List<Map> list = sysUserMapper.getRoleUsersByid(roleid, userid);
        //判断是否用户已分配此权限
        if (list.size() == 0) {
            //系统生成id
            String id = IdUtil.fastSimpleUUID();
            //新增sys_role_users表数据
            isOk = sysUserMapper.addUserRoles(id, roleid, userid);
        }
        return isOk;
    }

   /* @Override
    public Page<SysUser> queryUsers(String orgid,
                                    String username, Page<SysUser> page) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        // 分页查询中的条件查询
        if (StrUtil.isNotBlank(username)) {
            queryWrapper.like(SysUser::getUsername, username);
        }
        queryWrapper.eq(SysUser::getOrgid, orgid);
        return sysUserMapper.selectPage(page, queryWrapper);
    }*/

    @Override
    public Page<Map<String, Object>> queryUsers(String orgid,
                                                String nickname,
                                                Page<SysUser> page)  {
        //增加权限控制（usertype:0-超级管理员 1-系统管理员 2-普通用户）
        Page<Map<String, Object>> mapPage = null;
        SysUser currentUser=this.getUserInfo();
        int  usertype=currentUser.getUsertype();
        if(usertype==0 ||usertype==1) { //管理员才能查询用户数据
            mapPage = sysUserMapper.queryUsers(orgid,
                    nickname, page);
            List<Map<String, Object>> list = new ArrayList<>();
            List<Map<String, Object>> records = mapPage.getRecords();
            for (Map<String, Object> record : records) {
                String id = (String) record.get("id");
                List<SysRole> sysRoles = sysRoleMapper.getRoleByUserId(id);
                record.put("roles", sysRoles);
                list.add(record);
            }
            mapPage.setRecords(list);
            return mapPage;
        }else{
            return mapPage;
        }
    }

    /***********************************
     * 用途说明：根据ID批量删除用户
     * 参数说明
     *ids        用户id集合
     * 返回值说明: 判断是否删除成功
     ************************************/
    @Override
    public boolean deleteUserByIds(String id) {
        String[] splitId = id.split(",");
        List<String> ids = Arrays.asList(splitId);
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysUser::getId, ids);
        List<SysUser> sysUsers = sysUserMapper.selectList(queryWrapper);
        List<String> names =
                sysUsers.stream().map(SysUser::getUsername).collect(Collectors.toList());
        if (names.contains("admin")) {
            return false;
        } else {
            int result = sysUserMapper.deleteBatchIds(ids);
            if (result <= 0) {
                return false;
            }
            // 根据ID删除用户与角色的关联信息
            sysUserMapper.delRoleUsersByUserIds(ids);
            List<String> avatars =
                    sysUsers.stream().map(SysUser::getAvatar).collect(Collectors.toList());
            if (avatars.size() > 0) {
                for (String avatar : avatars) {
                    //账号头像存储地址
                    String imgName =
                            systempath + File.separator + "user" + File.separator + avatar;
                    FileUtil.del(imgName);
                }
            }
            return true;
        }
    }

    @Override
    public Map<String, Object> queryUserRole(String userId) {
        Map<String, Object> map = sysUserMapper.queryUserRole(userId);
        return map;
    }

    @Override
    public List<Map<String, Object>> queryUserRoleList(String userId) {
        List<Map<String, Object>> list = sysUserMapper.queryUserRoleList(userId);
        return list;
    }

    /***********************************
     * 用途说明:比较登录名称是否有重复
     * 参数说明
     * account  登录名称
     * 返回值说明: 重复返回 false 否则返回 true
     ************************************/
    private boolean isExistAccount(String username) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        if (this.list(queryWrapper.eq("username", username)).size() > 0) {
            //判断 查询登录账号 结果集是否为null  重复返回 false 否则返回 tree
            return false;
        } else {
            return true;
        }
    }
}
