package org.xyzh.system.service.impl;

import org.apache.dubbo.config.annotation.DubboService;
import org.xyzh.api.system.service.SysUserService;
import org.xyzh.api.system.vo.SysUserVO;
import org.xyzh.api.system.vo.UserDeptRoleVO;
import org.xyzh.common.core.domain.ResultDomain;
import org.xyzh.common.core.page.PageRequest;
import org.xyzh.common.dto.sys.TbSysUserDTO;
import org.xyzh.common.dto.sys.TbSysUserInfoDTO;
import org.xyzh.common.dto.sys.TbSysUserRoleDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.xyzh.common.core.page.PageParam;
import org.xyzh.common.core.page.PageDomain;

import org.xyzh.common.utils.id.IdUtil;
import org.xyzh.common.utils.NonUtils;
import org.xyzh.common.utils.StringUtils;
import org.xyzh.common.utils.crypto.AesEncryptUtil;
import org.xyzh.system.mapper.user.TbSysUserMapper;
import org.xyzh.system.mapper.user.TbSysUserInfoMapper;
import org.xyzh.system.mapper.user.TbSysUserRoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;

/**
 * @description    用户服务实现类
 * @filename    SysUserServiceImpl.java
 */
@DubboService(
    version = "1.0.0",
    group = "system",
    timeout = 3000,
    retries = 0
)
public class SysUserServiceImpl implements SysUserService {

    private static final Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);

    private static final String MSG_USER_PARAM_REQUIRED = "用户参数不能为空";
    private static final String MSG_USER_ID_REQUIRED = "用户ID不能为空";
    private static final String MSG_QUERY_PARAM_REQUIRED = "查询条件不能为空";
    private static final String MSG_PAGE_PARAM_REQUIRED = "分页参数不能为空";

    @Resource
    private TbSysUserMapper userMapper;

    @Resource
    private TbSysUserInfoMapper userInfoMapper;

    @Resource
    private TbSysUserRoleMapper userRoleMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AesEncryptUtil aesEncryptUtil;

    @Transactional
    @Override
    public ResultDomain<TbSysUserDTO> registerUser(SysUserVO userVO) {
        try {
            logger.info("开始注册用户：{}", userVO.getUsername());
            userVO.setPhone(aesEncryptUtil.decrypt(userVO.getPhone()));
            // 检查用户是否已存在
            if (checkUserExists(userVO)) {
                return ResultDomain.failure("用户已存在");
            }
            
            // 转换为 DTO
            TbSysUserDTO dto = SysUserVO.toDTO(userVO);
            
            // 设置用户基本信息
            Date now = new Date();
            if (StringUtils.isBlank(dto.getUserId())) {
                dto.setUserId(IdUtil.generateID());
            }
            dto.setPhone(userVO.getPhone());
            dto.setCreateTime(now);
            dto.setDeleted(false);
            
            // 加密密码
            if (StringUtils.isNotBlank(dto.getPassword())) {
                dto.setPassword(passwordEncoder.encode(aesEncryptUtil.decrypt(dto.getPassword())));
            }
            
            // 插入用户主表
            int rows = userMapper.insertUser(dto);
            if (rows <= 0) {
                logger.warn("插入用户失败, userVO:", userVO.toString());
                return ResultDomain.failure("插入用户失败");
            }
            
            // 创建用户信息表
            TbSysUserInfoDTO userInfo = new TbSysUserInfoDTO();
            userInfo.setUserId(dto.getUserId());
            userInfo.setCreateTime(now);
            userInfo.setAvatar("default");
            userInfoMapper.insertUserInfo(userInfo);
            
            // 分配默认角色（role_guest）
            TbSysUserRoleDTO userRole = new TbSysUserRoleDTO();
            userRole.setUserId(dto.getUserId());
            userRole.setRoleId("role_guest");
            userRole.setCreateTime(now);
            userRoleMapper.insertUserRole(userRole);
            
            return ResultDomain.success("注册用户成功", dto);
            
        } catch (Exception e) {
            logger.error("注册用户失败：{}", userVO.getUsername(), e);
            return ResultDomain.failure("注册用户失败：" + e.getMessage());
        }
    }
    
    /**
     * 检查用户是否已存在
     * @param userVO 用户信息
     * @return true-存在，false-不存在
     */
    private boolean checkUserExists(SysUserVO userVO) {
        SysUserVO filter = new SysUserVO();
        
        // 检查用户名是否存在
        if (StringUtils.isNotBlank(userVO.getUsername())) {
            filter.setUsername(userVO.getUsername());
            List<SysUserVO> users = userMapper.getUserByFilter(filter);
            if (users != null && !users.isEmpty()) {
                logger.warn("用户名已存在: {}", userVO.getUsername());
                return true;
            }
        }
        
        // 检查手机号是否存在
        if (StringUtils.isNotBlank(userVO.getPhone())) {
            filter = new SysUserVO();
            filter.setPhone(userVO.getPhone());
            List<SysUserVO> users = userMapper.getUserByFilter(filter);
            if (users != null && !users.isEmpty()) {
                logger.warn("手机号已存在: {}", userVO.getPhone());
                return true;
            }
        }
        
        // 检查邮箱是否存在
        if (StringUtils.isNotBlank(userVO.getEmail())) {
            filter = new SysUserVO();
            filter.setEmail(userVO.getEmail());
            List<SysUserVO> users = userMapper.getUserByFilter(filter);
            if (users != null && !users.isEmpty()) {
                logger.warn("邮箱已存在: {}", userVO.getEmail());
                return true;
            }
        }
        
        return false;
    }

    @Override
    public ResultDomain<TbSysUserDTO> insertUser(SysUserVO userVO) {
        if (userVO == null) {
            return ResultDomain.failure(MSG_USER_PARAM_REQUIRED);
        }
        
        ResultDomain<TbSysUserDTO> rows = registerUser(userVO);
        TbSysUserDTO dto = rows.getData();

        if (rows.getSuccess()) {
            logger.info("新增用户成功, userId={}", dto.getUserId());
            return ResultDomain.success("新增用户成功", dto);
        }
        logger.warn("新增用户失败, userId={}", dto.getUserId());
        return ResultDomain.failure("新增用户失败");
    }

    @Override
    public ResultDomain<TbSysUserDTO> updateUser(SysUserVO userVO) {
        if (userVO == null || StringUtils.isBlank(userVO.getUserId())) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        TbSysUserDTO dto = SysUserVO.toDTO(userVO);
        dto.setUpdateTime(new Date());
        int rows = userMapper.updateUser(dto);
        if (rows > 0) {
            logger.info("更新用户成功, userId={}", dto.getUserId());
            return ResultDomain.success("更新用户成功", dto);
        }
        logger.warn("更新用户失败, userId={}", dto.getUserId());
        return ResultDomain.failure("更新用户失败");
    }

    @Override
    public ResultDomain<Boolean> deleteUser(TbSysUserDTO userDTO) {
        if (userDTO == null || StringUtils.isBlank(userDTO.getUserId())) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        int rows = userMapper.deleteUser(userDTO);
        if (rows > 0) {
            logger.info("删除用户成功, userId={}", userDTO.getUserId());
            return ResultDomain.success("删除用户成功", Boolean.TRUE);
        }
        logger.warn("删除用户失败, userId={}", userDTO.getUserId());
        return ResultDomain.failure("删除用户失败");
    }

    @Override
    public ResultDomain<SysUserVO> getUser(SysUserVO filter) {
        if (filter == null) {
            return ResultDomain.failure(MSG_QUERY_PARAM_REQUIRED);
        }
        List<SysUserVO> list = userMapper.getUserByFilter(filter);
        if (list == null || list.isEmpty()) {
            return ResultDomain.failure("未找到用户");
        }
        return ResultDomain.success("获取用户成功", list.get(0));
    }

    @Override
    public ResultDomain<SysUserVO> getLoginUser(SysUserVO filter) {
        // 登录查询语义与 getUser 相同（可根据用户名/手机号/邮箱/wechatId查询）
        if(NonUtils.isNotNull(filter.getPhone())){
            // 确保 phoneHash 被正确设置
            filter.setPhone(filter.getPhone());
            logger.info("登录查询 - phone: {}, phoneHash: {}", filter.getPhone(), filter.getPhoneHash());
        }
        if(NonUtils.isNotNull(filter.getWechatId())){
            logger.info("登录查询 - wechatId: {}", filter.getWechatId());
        }
        List<SysUserVO> list = userMapper.getUserByFilter(filter);
        logger.info("登录查询结果数量: {}", list != null ? list.size() : 0);
        if (list == null || list.isEmpty()) {
            return ResultDomain.failure("用户不存在");
        }
        return ResultDomain.success("查询成功", list.get(0));
    }

    @Override
    public ResultDomain<SysUserVO> getUserList(SysUserVO filter) {
        List<SysUserVO> list = userMapper.getUserByFilter(filter);
        if (list == null) {
            list = Collections.emptyList();
        }
        return ResultDomain.success("获取用户列表成功", list);
    }

    @Override
    public ResultDomain<SysUserVO> getUserPage(PageRequest<SysUserVO> pageRequest) {
        if (pageRequest == null) {
            return ResultDomain.failure(MSG_PAGE_PARAM_REQUIRED);
        }
        PageParam pageParam = pageRequest.getPageParam();
        TbSysUserDTO filter = SysUserVO.toDTO(pageRequest.getFilter());
        int total = userMapper.getUserCount(filter);
        pageParam.setTotal(total);
        pageParam.setTotalPages(pageParam.getPageSize() == 0 ? 0 : (int) Math.ceil((double) total / pageParam.getPageSize()));
        List<SysUserVO> data = userMapper.getUserPageByFilter(filter, pageParam);
        if (data == null) {
            data = Collections.emptyList();
        }
        PageDomain<SysUserVO> pageDomain = new PageDomain<>(pageParam, data);
        return ResultDomain.success("分页查询用户成功", pageDomain);
    }

    @Override
    public ResultDomain<SysUserVO> getUserByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return ResultDomain.failure("用户名不能为空");
        }
        SysUserVO userVO = new SysUserVO();
        userVO.setUsername(username);
        List<SysUserVO> list = userMapper.getUserByFilter(userVO);
        if (list == null || list.isEmpty()) {
            return ResultDomain.failure("未找到用户");
        }
        return ResultDomain.success("根据用户名获取用户成功", list.get(0));
    }

    @Override
    public ResultDomain<Boolean> updateUserPassword(String userId, String oldPassword, String newPassword) {
        if (StringUtils.isBlank(userId)) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        if (StringUtils.isBlank(newPassword)) {
            return ResultDomain.failure("新密码不能为空");
        }
        TbSysUserDTO dto = new TbSysUserDTO();
        dto.setUserId(userId);
        dto.setPassword(newPassword);
        dto.setUpdateTime(new Date());
        int rows = userMapper.updateUser(dto);
        if (rows > 0) {
            logger.info("更新用户密码成功, userId={}", userId);
            return ResultDomain.success("更新用户密码成功", Boolean.TRUE);
        }
        logger.warn("更新用户密码失败, userId={}", userId);
        return ResultDomain.failure("更新用户密码失败");
    }

    @Override
    public ResultDomain<String> resetUserPassword(String userId) {
        if (StringUtils.isBlank(userId)) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        String newPwd = IdUtil.generateID();
        if (newPwd.length() > 12) {
            newPwd = newPwd.substring(0, 12);
        }
        TbSysUserDTO dto = new TbSysUserDTO();
        dto.setUserId(userId);
        dto.setPassword(newPwd);
        dto.setUpdateTime(new Date());
        int rows = userMapper.updateUser(dto);
        if (rows > 0) {
            logger.info("重置用户密码成功, userId={}", userId);
            return ResultDomain.success("重置用户密码成功", newPwd);
        }
        logger.warn("重置用户密码失败, userId={}", userId);
        return ResultDomain.failure("重置用户密码失败");
    }

    @Override
    public ResultDomain<Boolean> updateUserStatus(String userId, String status) {
        if (StringUtils.isBlank(userId)) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        TbSysUserDTO dto = new TbSysUserDTO();
        dto.setUserId(userId);
        dto.setStatus(status);
        dto.setUpdateTime(new Date());
        int rows = userMapper.updateUser(dto);
        if (rows > 0) {
            logger.info("更新用户状态成功, userId={}", userId);
            return ResultDomain.success("更新用户状态成功", Boolean.TRUE);
        }
        logger.warn("更新用户状态失败, userId={}", userId);
        return ResultDomain.failure("更新用户状态失败");
    }

    @Override
    public ResultDomain<TbSysUserInfoDTO> updateUserInfo(TbSysUserInfoDTO userInfoDTO) {
        if (userInfoDTO == null || StringUtils.isBlank(userInfoDTO.getUserId())) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        userInfoDTO.setUpdateTime(new Date());
        int rows = userInfoMapper.updateUserInfo(userInfoDTO);
        if (rows > 0) {
            logger.info("更新用户信息成功, userId={}", userInfoDTO.getUserId());
            return ResultDomain.success("更新用户信息成功", userInfoDTO);
        }
        logger.warn("更新用户信息失败, userId={}", userInfoDTO.getUserId());
        return ResultDomain.failure("更新用户信息失败");
    }

    @Override
    public ResultDomain<SysUserVO> getUserInfo(String userId) {
        if (StringUtils.isBlank(userId)) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        TbSysUserInfoDTO info = userInfoMapper.getUserInfoById(userId);
        if (info == null) {
            return ResultDomain.failure("未找到用户信息");
        }
        SysUserVO vo = new SysUserVO();
        vo.setUserId(userId);
        vo.setAvatar(info.getAvatar());
        vo.setGender(info.getGender());
        vo.setUsername(info.getUsername());
        vo.setLevel(info.getLevel());
        vo.setIdCard(info.getIdCard());
        vo.setAddress(info.getAddress());
        vo.setCreateTime(info.getCreateTime());
        vo.setUpdateTime(info.getUpdateTime());
        vo.setDeleteTime(info.getDeleteTime());
        vo.setDeleted(info.getDeleted());
        return ResultDomain.success("获取用户信息成功", vo);
    }

    @Override
    public ResultDomain<TbSysUserRoleDTO> addUserRole(TbSysUserRoleDTO userRoleDTO) {
        if (userRoleDTO == null || StringUtils.isBlank(userRoleDTO.getUserId()) || StringUtils.isBlank(userRoleDTO.getRoleId())) {
            return ResultDomain.failure("用户ID和角色ID不能为空");
        }
        if (userRoleDTO.getCreateTime() == null) {
            userRoleDTO.setCreateTime(new Date());
        }
        if (userRoleDTO.getDeleted() == null) {
            userRoleDTO.setDeleted(false);
        }
        int rows = userRoleMapper.insertUserRole(userRoleDTO);
        if (rows > 0) {
            logger.info("新增用户角色关联成功, userId={}, roleId={}", userRoleDTO.getUserId(), userRoleDTO.getRoleId());
            return ResultDomain.success("新增用户角色关联成功", userRoleDTO);
        }
        logger.warn("新增用户角色关联失败, userId={}, roleId={}", userRoleDTO.getUserId(), userRoleDTO.getRoleId());
        return ResultDomain.failure("新增用户角色关联失败");
    }

    @Override
    public ResultDomain<Boolean> removeUserRole(TbSysUserRoleDTO userRoleDTO) {
        if (userRoleDTO == null || StringUtils.isBlank(userRoleDTO.getUserId()) || StringUtils.isBlank(userRoleDTO.getRoleId())) {
            return ResultDomain.failure("用户ID和角色ID不能为空");
        }
        int rows = userRoleMapper.deleteUserRole(userRoleDTO);
        if (rows > 0) {
            logger.info("删除用户角色关联成功, userId={}, roleId={}", userRoleDTO.getUserId(), userRoleDTO.getRoleId());
            return ResultDomain.success("删除用户角色关联成功", Boolean.TRUE);
        }
        logger.warn("删除用户角色关联失败, userId={}, roleId={}", userRoleDTO.getUserId(), userRoleDTO.getRoleId());
        return ResultDomain.failure("删除用户角色关联失败");
    }

    @Override
    public ResultDomain<Boolean> setUserRoles(String userId, String[] roleIds) {
        if (StringUtils.isBlank(userId)) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        // 先删除现有的用户角色关系
        List<UserDeptRoleVO> exists = userRoleMapper.getUserRoleByUserId(userId);
        if (exists != null) {
            for (UserDeptRoleVO vo : exists) {
                if (vo == null || StringUtils.isBlank(vo.getRoleId())) {
                    continue;
                }
                TbSysUserRoleDTO del = new TbSysUserRoleDTO();
                del.setUserId(userId);
                del.setRoleId(vo.getRoleId());
                userRoleMapper.deleteUserRole(del);
            }
        }
        // 批量插入新角色
        if (roleIds != null) {
            Date now = new Date();
            for (String rid : roleIds) {
                if (StringUtils.isBlank(rid)) {
                    continue;
                }
                TbSysUserRoleDTO add = new TbSysUserRoleDTO();
                add.setUserId(userId);
                add.setRoleId(rid);
                add.setCreateTime(now);
                add.setDeleted(false);
                userRoleMapper.insertUserRole(add);
            }
        }
        logger.info("设置用户角色成功, userId={}, count={}", userId, roleIds == null ? 0 : roleIds.length);
        return ResultDomain.success("设置用户角色成功", Boolean.TRUE);
    }

    @Override
    public ResultDomain<UserDeptRoleVO> getUserWithDeptRole(String userId) {
        if (StringUtils.isBlank(userId)) {
            return ResultDomain.failure(MSG_USER_ID_REQUIRED);
        }
        List<UserDeptRoleVO> list = userRoleMapper.getUserRoleByUserId(userId);
        if (list == null) {
            list = Collections.emptyList();
        }
        return ResultDomain.success("获取用户部门角色成功", list);
    }

    
}
