package com.lesingle.creation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lesingle.creation.common.exception.BusinessException;
import com.lesingle.creation.dto.user.CreateUserDTO;
import com.lesingle.creation.dto.user.UpdateUserDTO;
import com.lesingle.creation.dto.user.UserQueryDTO;
import com.lesingle.creation.entity.User;
import com.lesingle.creation.entity.UserRole;
import com.lesingle.creation.mapper.UserMapper;
import com.lesingle.creation.mapper.UserRoleMapper;
import com.lesingle.creation.service.UserService;
import com.lesingle.creation.vo.user.UserDetailVO;
import com.lesingle.creation.vo.user.UserListVO;
import com.lesingle.creation.vo.user.UserStatsVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    private final UserRoleMapper userRoleMapper;
    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDetailVO create(CreateUserDTO dto, Long tenantId, Long operatorId) {
        log.info("开始创建用户，用户名：{}", dto.getUsername());

        // 检查用户名是否已存在
        User existingUser = userMapper.selectByusername(tenantId, dto.getUsername());
        if (existingUser != null) {
            throw new BusinessException("用户名已存在");
        }

        // 如果提供了邮箱，检查邮箱是否已存在
        if (StringUtils.hasText(dto.getEmail())) {
            User existingEmail = userMapper.selectByEmail(tenantId, dto.getEmail());
            if (existingEmail != null) {
                throw new BusinessException("邮箱已被使用");
            }
        }

        // 如果提供了手机号，检查手机号是否已存在
        if (StringUtils.hasText(dto.getPhone())) {
            User existingPhone = userMapper.selectByPhone(dto.getPhone());
            if (existingPhone != null) {
                throw new BusinessException("手机号已被使用");
            }
        }

        // 创建用户
        User user = new User();
        user.setTenantId(tenantId);
        user.setUsername(dto.getUsername());
        user.setPassword(passwordEncoder.encode(dto.getPassword()));
        user.setNickname(dto.getNickname());
        user.setEmail(dto.getEmail());
        user.setPhone(dto.getPhone());
        user.setGender(dto.getGender());
        user.setAvatar(dto.getAvatar());
        user.setStatus(dto.getStatus() != null ? dto.getStatus() : "enabled");
        user.setValidState(1);
        user.setCreateBy(String.valueOf(operatorId));

        userMapper.insert(user);
        log.info("用户创建成功，用户 ID: {}", user.getId());

        // 如果提供了角色 ID，创建角色关联
        if (dto.getRoleIds() != null && !dto.getRoleIds().isEmpty()) {
            List<UserRole> userRoles = dto.getRoleIds().stream()
                    .map(roleId -> {
                        UserRole ur = new UserRole();
                        ur.setUserId(user.getId());
                        ur.setRoleId(roleId);
                        return ur;
                    })
                    .collect(Collectors.toList());
            userRoleMapper.insertBatch(userRoles);
            log.info("用户角色关联创建成功，角色数量：{}", dto.getRoleIds().size());
        }

        return convertToDetailVO(user);
    }

    @Override
    public Page<UserListVO> pageList(UserQueryDTO queryDTO, Long tenantId, boolean isSuperTenant) {
        log.info("分页查询用户列表，页码：{}, 每页大小：{}", queryDTO.getPage(), queryDTO.getPageSize());

        Page<User> userPage = new Page<>(queryDTO.getPage(), queryDTO.getPageSize());
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();

        // 超级租户可以查询所有用户，普通租户只能查询本租户用户
        if (!isSuperTenant) {
            wrapper.eq(User::getTenantId, tenantId);
        }

        // 关键字查询
        if (StringUtils.hasText(queryDTO.getKeyword())) {
            wrapper.and(w -> w
                    .like(User::getUsername, queryDTO.getKeyword())
                    .or()
                    .like(User::getNickname, queryDTO.getKeyword())
                    .or()
                    .like(User::getEmail, queryDTO.getKeyword())
                    .or()
                    .like(User::getPhone, queryDTO.getKeyword())
            );
        }

        // 用户类型筛选
        if (StringUtils.hasText(queryDTO.getUserType())) {
            wrapper.eq(User::getUserType, queryDTO.getUserType());
        }

        // 用户来源筛选
        if (StringUtils.hasText(queryDTO.getUserSource())) {
            wrapper.eq(User::getUserSource, queryDTO.getUserSource());
        }

        // 账号状态筛选
        if (StringUtils.hasText(queryDTO.getStatus())) {
            wrapper.eq(User::getStatus, queryDTO.getStatus());
        }

        wrapper.orderByDesc(User::getCreateTime);

        Page<User> resultPage = userMapper.selectPage(userPage, wrapper);

        // 转换为 VO
        List<UserListVO> voList = resultPage.getRecords().stream()
                .map(this::convertToListVO)
                .collect(Collectors.toList());

        Page<UserListVO> voPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal());
        voPage.setRecords(voList);

        return voPage;
    }

    @Override
    public UserDetailVO detail(Long id, Long tenantId, boolean isSuperTenant) {
        log.info("查询用户详情，用户 ID: {}", id);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 非超级租户只能查看本租户用户
        if (!isSuperTenant && !user.getTenantId().equals(tenantId)) {
            throw new BusinessException("无权查看该用户信息");
        }

        return convertToDetailVO(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDetailVO updateStatus(Long id, String status, Long operatorId) {
        log.info("更新用户状态，用户 ID: {}, 新状态：{}", id, status);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setStatus(status);
        updateUser.setUpdateBy(String.valueOf(operatorId));

        userMapper.updateById(updateUser);
        log.info("用户状态更新成功，用户 ID: {}", id);

        return convertToDetailVO(userMapper.selectById(id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserDetailVO update(Long id, UpdateUserDTO dto, Long tenantId) {
        log.info("更新用户，用户 ID: {}", id);

        User existingUser = userMapper.selectById(id);
        if (existingUser == null) {
            throw new BusinessException("用户不存在");
        }

        // 如果更新了用户名，检查是否冲突
        if (StringUtils.hasText(dto.getUsername())) {
            User conflictUser = userMapper.selectByusernameExclude(tenantId, dto.getUsername(), id);
            if (conflictUser != null) {
                throw new BusinessException("用户名已存在");
            }
        }

        // 如果更新了邮箱，检查是否冲突
        if (StringUtils.hasText(dto.getEmail())) {
            User conflictEmail = userMapper.selectByEmailExclude(tenantId, dto.getEmail(), id);
            if (conflictEmail != null) {
                throw new BusinessException("邮箱已被使用");
            }
        }

        // 更新用户信息
        User user = new User();
        user.setId(id);
        user.setUsername(dto.getUsername());
        if (StringUtils.hasText(dto.getPassword())) {
            user.setPassword(passwordEncoder.encode(dto.getPassword()));
        }
        user.setNickname(dto.getNickname());
        user.setEmail(dto.getEmail());
        user.setPhone(dto.getPhone());
        user.setGender(dto.getGender());
        user.setAvatar(dto.getAvatar());
        user.setStatus(dto.getStatus());

        userMapper.updateById(user);
        log.info("用户更新成功，用户 ID: {}", id);

        // 如果提供了 roleIds，更新角色关联
        if (dto.getRoleIds() != null) {
            // 先删除现有角色关联
            LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserRole::getUserId, id);
            userRoleMapper.delete(wrapper);
            log.info("已删除用户原有角色关联");

            // 创建新的角色关联
            if (!dto.getRoleIds().isEmpty()) {
                List<UserRole> userRoles = dto.getRoleIds().stream()
                        .map(roleId -> {
                            UserRole ur = new UserRole();
                            ur.setUserId(id);
                            ur.setRoleId(roleId);
                            return ur;
                        })
                        .collect(Collectors.toList());
                userRoleMapper.insertBatch(userRoles);
                log.info("用户新角色关联创建成功，角色数量：{}", dto.getRoleIds().size());
            }
        }

        return convertToDetailVO(userMapper.selectById(id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id, Long tenantId) {
        log.info("删除用户，用户 ID: {}", id);

        User user = userMapper.selectById(id);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 删除用户（逻辑删除）
        userMapper.deleteById(id);
        log.info("用户删除成功，用户 ID: {}", id);
    }

    @Override
    public UserStatsVO getStats() {
        log.info("获取用户统计信息");

        UserStatsVO stats = new UserStatsVO();

        // TODO: 实现用户统计逻辑
        // 需要统计总用户数、平台用户数、机构用户数、评委用户数等

        return stats;
    }

    /**
     * 转换为详情 VO
     */
    private UserDetailVO convertToDetailVO(User user) {
        UserDetailVO vo = new UserDetailVO();
        vo.setId(user.getId());
        vo.setTenantId(user.getTenantId());
        vo.setUsername(user.getUsername());
        vo.setNickname(user.getNickname());
        vo.setEmail(user.getEmail());
        vo.setPhone(user.getPhone());
        vo.setGender(user.getGender());
        vo.setAvatar(user.getAvatar());
        vo.setCity(user.getCity());
        vo.setBirthday(user.getBirthday());
        vo.setUserSource(user.getUserSource());
        vo.setUserType(user.getUserType());
        vo.setOrganization(user.getOrganization());
        vo.setStatus(user.getStatus());
        vo.setValidState(user.getValidState());
        vo.setCreateBy(user.getCreateBy());
        vo.setCreateTime(user.getCreateTime());
        vo.setUpdateBy(user.getUpdateBy());
        vo.setUpdateTime(user.getUpdateTime());

        // TODO: 获取用户角色
        vo.setRoleIds(new ArrayList<>());
        vo.setRoleNames(new ArrayList<>());

        return vo;
    }

    /**
     * 转换为列表 VO
     */
    private UserListVO convertToListVO(User user) {
        UserListVO vo = new UserListVO();
        vo.setId(user.getId());
        vo.setTenantId(user.getTenantId());
        vo.setUsername(user.getUsername());
        vo.setNickname(user.getNickname());
        vo.setEmail(user.getEmail());
        vo.setPhone(user.getPhone());
        vo.setGender(user.getGender());
        vo.setAvatar(user.getAvatar());
        vo.setUserType(user.getUserType());
        vo.setStatus(user.getStatus());
        vo.setCreateTime(user.getCreateTime());

        // TODO: 获取用户角色名称
        vo.setRoleNames(new ArrayList<>());

        return vo;
    }
}
