package io.gisbi.application.system.service.impl;

import cn.hutool.Hutool;
import cn.hutool.core.util.IdUtil;
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 io.gisbi.application.system.domain.Role;
import io.gisbi.application.system.domain.User;
import io.gisbi.application.system.mapper.RoleMapper;
import io.gisbi.application.system.mapper.UserMapper;
import io.gisbi.application.system.service.IUserService;
import io.gisbi.utils.AuthUtils;
import io.gisbi.utils.RsaUtils;
import io.micrometer.common.util.StringUtils;
import io.netty.channel.ChannelInboundHandlerAdapter;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author lilin
 * @since 2025-05-08
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ChannelInboundHandlerAdapter.class);

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;


    public static final String DEFAULT_IS_VALID = "1";
    //定义密码常量
    public static final String PASSWORD_VALID = "123456";


    /***********************************
     * 用途说明：新增系统用户
     * 参数说明
     * user     用户对象
     * roleids  角色ID
     * 返回值说明:  是否新增成功
     ***********************************/
    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务控制
    public Map addUser(User user, String roleids) {
        //返回信息
        Map<String, String> result = new HashMap<>();
        //普通用户
        //设置缺省密码
        String cryptPassword = RsaUtils.encryptStr(PASSWORD_VALID);
        user.setPassword(cryptPassword);
        //最近修改日期
        user.setLastmodifydate(LocalDateTime.now());
        //最近修改者
        user.setLastmodifier(AuthUtils.getUser().getUserId().toString());
        //账号有效  状态 1-有效 0-停用
        user.setStatus(DEFAULT_IS_VALID);
        //判断注册的登录账号是否存在
        if (!isExistAccount(user.getAppId(), StrUtil.trim(user.getUsername()))) {
            //新增用户
            boolean ok = this.save(user);
            //新增用户分配权限
            if (StringUtils.isNotEmpty(roleids)) {
                String[] roles = roleids.split(",");
                for (String roleid : roles) {
                    //系统生成id
                    String id = IdUtil.fastSimpleUUID();
                    //新增app_role_users表数据
                    ok = ok && userMapper.addUserRoles(id, user.getAppId(), roleid, user.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;
    }

    /***********************************
     * 用途说明：修改用户信息
     * 参数说明
     * user     用户对象
     * roleids  角色ID
     * 返回值说明:  是否新增成功
     ***********************************/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map updateById(User user, String roleids) {
        Map<String, String> result = new HashMap<>();
        try {
            // 设置最近修改人和时间
            user.setLastmodifier(AuthUtils.getUser().getUserId().toString());
            user.setLastmodifydate(LocalDateTime.now());
            //修改用户信息
            boolean ok = this.updateById(user);
            if (ok) {
                //判断角色id是否为空 如果不为空 先删除 后增加  如果为空删除用户下所有角色信息
                if (StringUtils.isNotEmpty(roleids)) {
                    String[] roles = roleids.split(",");
                    Set<String> roleSet = new HashSet<>(Arrays.asList(roles));

                    //首先根绝用户ID，删除用户角色关联表中的数据
                    ok = ok && userMapper.delRoleUsersByUserid(user.getId());

                    // 添加新角色
                    for (String role : roles) {
                        //系统生成id
                        String id = IdUtil.fastSimpleUUID();
                        ok = ok && userMapper.addUserRoles(id, user.getAppId(), role, user.getId());
                    }
                } else {
                    // 删除所有关联角色
                    ok = ok && userMapper.delRoleUsersByUserid(user.getId());
                }

                result.put("status", "success");
                result.put("msg", "用户信息修改成功！");
            } else {
                result.put("status", "error");
                result.put("msg", "用户信息修改失败！");
            }
        } catch (Exception e) {
            // 记录日志
            LOGGER.error("用户信息修改过程中发生异常", e);
            result.put("status", "error");
            result.put("msg", "用户信息修改失败，请稍后再试！");
        }
        return result;
    }

    /***********************************
     * 用途说明：查询用户信息
     * 参数说明
     * orgid     所属组织ID
     * nickname  用户昵称
     * page      分页条件
     * 返回值说明:  用户信息集合
     ***********************************/
    @Override
    public Page<Map<String, Object>> queryUsers(String orgid, String appId, String nickname, Page<User> page) {

        //当前用户类型  用户类型 0-管理员 1-普通用户
        int usertype = 0;//currentUser.getUsertype();
        if (usertype == 0 || usertype == 1) {
            //根据条件分页查询用户信息    查询到的用户信息挨个查询角色信息
            Page<Map<String, Object>> mapPage = userMapper.queryUsers(orgid, appId, nickname, page);

            List<Map<String, Object>> records = mapPage != null ? mapPage.getRecords() : new ArrayList<>();
            if (records.isEmpty()) {
                return mapPage;
            }

            List<Map<String, Object>> list = new ArrayList<>(records.size());
            //根据用户ID获取对应的角色信息
            for (Map<String, Object> record : records) {

                Object idObj = record.get("id");
                if (idObj == null) {
                    continue; // 跳过无效记录
                }
                // 更安全地处理id
                String id = idObj.toString();
                List<Role> roles = roleMapper.getRoleByUserId(id);
                if (roles == null) {
                    // 防止null值
                    roles = Collections.emptyList();
                }
                record.put("roles", roles);
                list.add(record);
            }
            mapPage.setRecords(list);
            return mapPage;
        } else {
            // 明确返回null比返回未初始化的mapPage更好
            return null;
        }
    }

    /***********************************
     * 用途说明：根据id删除用户
     * 参数说明
     *id         用户id
     * 返回值说明: 判断是否删除成功
     ************************************/
    @Override
    public Boolean deleteUserById(String id) {
        //根据id查询
        User user = this.getById(id);
        //如果是管理员不能删除
        if ("admin".equals(user.getUsername())) {
            return false;
        } else {
            //删除用户及对应的橘色信息
            boolean isOk = this.removeById(id);
            //判断是否删除成功
            if (isOk) {
                //根据用户id 删除该用户角色关联
                userMapper.delRoleUsersByUserid(id);
                return true;
            } else {
                return false;
            }
        }
    }

    /***********************************
     * 用途说明：根据ID批量删除用户
     * 参数说明
     *ids        用户id集合
     * 返回值说明: 判断是否删除成功
     ************************************/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUserByIds(String ids) {

        List<String> idList = Arrays.asList(ids.split(","));

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(User::getId, idList);
        List<User> sysUsers = userMapper.selectList(queryWrapper);

        List<String> names = sysUsers.stream().map(User::getUsername).collect(Collectors.toList());
        if (names.contains("admin")) {
            return false;
        } else {
            //批量删除用户
            int result = userMapper.deleteBatchIds(idList);
            if (result <= 0) {
                return false;
            }
            // 根据ID删除用户与角色的关联信息
            userMapper.delRoleUsersByUserIds(idList);
            return true;
        }
    }

    /***********************************
     * 用途说明：重置用户密码(管理员)
     * 参数说明
     *id        重置密码的 用户id
     * 返回值说明: 判断是否重置成功
     ************************************/
    @Override
    public boolean resetPassword(String id) {
        boolean isOk = false;
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        //根据id 修改密码，密码修改时间，最近修改者，最近修改日期     将密码修改为 123456
        String cryptPassword = PASSWORD_VALID;
        updateWrapper.eq("id", id).set("password", cryptPassword)
                .set("pwdresettime", LocalDateTime.now())
                .set("lastmodifydate", LocalDateTime.now())
                .set("lastmodifier", AuthUtils.getUser().getUserId().toString());
        //是否修改成功
        isOk = this.update(updateWrapper);
        return isOk;
    }

    /***********************************
     * 用途说明：设置账号状态(管理员)
     * 参数说明
     *id        用户id
     * status   设置状态
     * 返回值说明: 判断是否设置成功
     ************************************/
    @Override
    public boolean setStatus(String id, String status) {
        boolean isOk = false;
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        //根据id修改用户状态，最近修改人，最近修改时间
        updateWrapper.eq("id", id)
                .set("status", status)
                .set("lastmodifydate", LocalDateTime.now())
                .set("lastmodifier", AuthUtils.getUser().getUserId().toString());
        //是否修改成功
        isOk = this.update(updateWrapper);
        return isOk;
    }



    /***********************************
     * 用途说明：角色添加用户
     * 参数说明
     * roleid       角色id
     * userid       用户id
     * 返回值说明:  是否新增成功
     ***********************************/
    @Override
    public boolean addUserRole(String roleid, String userid) {
        boolean isOk = true;
        if (StringUtils.isEmpty(roleid) || StringUtils.isEmpty(userid)) {
            return false;
        }
        User user = userMapper.selectById(userid);
        //根据角色id与用户id查询
        List<Map> list = userMapper.getRoleUsersByid(roleid, userid);
        //判断是否用户已分配此权限
        if (list.size() == 0) {
            //系统生成id
            String id = IdUtil.fastSimpleUUID();
            //新增app_role_users表数据
            isOk = userMapper.addUserRoles(id, user.getAppId(), roleid, userid);
        }
        return isOk;
    }


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


}
