package com.dora.service.impl;

import com.dora.dto.AdminUserDto;
import com.dora.dto.ApiResponse;
import com.dora.dto.PageResultDto;
import com.dora.dto.UserBalanceDto;
import com.dora.entity.User;
import com.dora.exception.BusinessException;
import com.dora.mapper.UserBalanceMapper;
import com.dora.mapper.UserMapper;
import com.dora.service.AdminUserService;
import com.dora.service.UserBalanceService;
import com.dora.util.AdminSecurityUtil;
import com.dora.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 后台用户管理服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AdminUserServiceImpl implements AdminUserService {

    private final UserMapper userMapper;
    private final UserBalanceMapper userBalanceMapper;
    private final UserBalanceService userBalanceService;
    private final JwtUtil jwtUtil;

    @Override
    public ApiResponse<AdminUserDto.UserListResponse> getUserList(AdminUserDto.UserListRequest request) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 查询用户列表", adminId);

            // 计算分页参数
            int offset = (request.getPage() - 1) * request.getSize();
            
            // 查询用户列表
            List<AdminUserDto.UserListItem> users = userMapper.selectUserListForAdmin(
                    request.getKeyword(),
                    request.getRole(),
                    request.getIsVerified(),
                    request.getPromotionLevel(),
                    request.getCreateTimeStart(),
                    request.getCreateTimeEnd(),
                    request.getMembershipType(),
                    request.getSortField(),
                    request.getSortOrder(),
                    offset,
                    request.getSize(),
                    request.getIsDeleted()
            );

            // 查询总数
            Long total = (long) userMapper.countUserListForAdmin(
                    request.getKeyword(),
                    request.getRole(),
                    request.getIsVerified(),
                    request.getPromotionLevel(),
                    request.getCreateTimeStart(),
                    request.getCreateTimeEnd(),
                    request.getMembershipType(),
                    request.getIsDeleted()
            );

            // 构建响应
            AdminUserDto.UserListResponse response = new AdminUserDto.UserListResponse();
            response.setUsers(users);
            response.setTotal(total);
            response.setPage(request.getPage());
            response.setSize(request.getSize());
            response.setTotalPages((int) Math.ceil((double) total / request.getSize()));

            return ApiResponse.success(response);
        } catch (Exception e) {
            log.error("查询用户列表失败", e);
            return ApiResponse.error(500, "查询用户列表失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<AdminUserDto.UserDetailResponse> getUserDetail(Long userId) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 查询用户详情，用户ID: {}", adminId, userId);

            // 查询用户详情
            AdminUserDto.UserDetailResponse userDetail = userMapper.selectUserDetailForAdmin(userId);
            if (userDetail == null) {
                return ApiResponse.error(404, "用户不存在");
            }

            // 查询用户余额信息
            try {
                UserBalanceDto.UserBalanceResponse balanceInfo = userBalanceService.getUserBalanceInfo(userId);
                // 将余额信息转换为BalanceInfo格式
                AdminUserDto.BalanceInfo balanceInfoConverted = new AdminUserDto.BalanceInfo();
                balanceInfoConverted.setBalance(balanceInfo.getBalance());
                balanceInfoConverted.setTotalIncome(balanceInfo.getTotalIncome());
                balanceInfoConverted.setTotalWithdrawn(balanceInfo.getTotalWithdrawn());
                balanceInfoConverted.setFrozenAmount(balanceInfo.getFrozenAmount());
                balanceInfoConverted.setAvailableBalance(balanceInfo.getAvailableBalance());
                userDetail.setBalanceInfo(balanceInfoConverted);
            } catch (Exception e) {
                log.warn("获取用户余额信息失败，用户ID: {}", userId, e);
                // 余额信息获取失败不影响用户详情查询
            }

            return ApiResponse.success(userDetail);
        } catch (Exception e) {
            log.error("查询用户详情失败，用户ID: {}", userId, e);
            return ApiResponse.error(500, "查询用户详情失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> updateUser(AdminUserDto.UserUpdateRequest request) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 更新用户信息，用户ID: {}", adminId, request.getUserId());

            // 检查用户是否存在
            User existingUser = userMapper.selectById(request.getUserId());
            if (existingUser == null) {
                return ApiResponse.error(404, "用户不存在");
            }

            // 构建更新对象
            User updateUser = new User();
            updateUser.setId(request.getUserId());
            updateUser.setUpdateTime(LocalDateTime.now());

            // 更新字段
            if (StringUtils.hasText(request.getUsername())) {
                // 检查用户名是否已被其他用户使用
                User userWithSameUsername = userMapper.selectByUsername(request.getUsername());
                if (userWithSameUsername != null && !userWithSameUsername.getId().equals(request.getUserId())) {
                    return ApiResponse.error(400, "用户名已被使用");
                }
                updateUser.setUsername(request.getUsername());
            }

            if (StringUtils.hasText(request.getRealUsername())) {
                updateUser.setRealUsername(request.getRealUsername());
            }

            if (StringUtils.hasText(request.getIdNumber())) {
                updateUser.setIdNumber(request.getIdNumber());
            }

            if (request.getRole() != null) {
                updateUser.setRole(request.getRole());
            }

            if (request.getMembershipExpiresAt() != null) {
                updateUser.setMembershipExpiresAt(request.getMembershipExpiresAt());
            }

            if (request.getIsVerified() != null) {
                updateUser.setIsVerified(request.getIsVerified());
            }

            if (request.getPromotionLevel() != null) {
                updateUser.setPromotionLevel(request.getPromotionLevel());
            }

            if (request.getPoints() != null) {
                updateUser.setPoints(request.getPoints());
            }

            if (request.getPointsExpiresAt() != null) {
                updateUser.setPointsExpiresAt(request.getPointsExpiresAt());
            }

            // 执行更新
            int result = userMapper.updateById(updateUser);
            if (result > 0) {
                log.info("用户信息更新成功，用户ID: {}", request.getUserId());
                return ApiResponse.success("用户信息更新成功");
            } else {
                return ApiResponse.error(500, "用户信息更新失败");
            }
        } catch (Exception e) {
            log.error("更新用户信息失败，用户ID: {}", request.getUserId(), e);
            return ApiResponse.error(500, "更新用户信息失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> updateUserStatus(AdminUserDto.UserStatusUpdateRequest request) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 更新用户状态，用户ID: {}, 状态: {}", adminId, request.getUserId(), request.getIsDeleted());

            // 检查用户是否存在
            User existingUser = userMapper.selectById(request.getUserId());
            if (existingUser == null) {
                return ApiResponse.error(404, "用户不存在");
            }

            // 执行状态更新
            int result = userMapper.updateUserStatus(request.getUserId(), request.getIsDeleted());
            if (result > 0) {
                String statusText = request.getIsDeleted() == 1 ? "禁用" : "启用";
                log.info("用户状态更新成功，用户ID: {}, 状态: {}", request.getUserId(), statusText);
                return ApiResponse.success("用户" + statusText + "成功");
            } else {
                return ApiResponse.error(500, "用户状态更新失败");
            }
        } catch (Exception e) {
            log.error("更新用户状态失败，用户ID: {}", request.getUserId(), e);
            return ApiResponse.error(500, "更新用户状态失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<AdminUserDto.UserStatistics> getUserStatistics() {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 查询用户统计信息", adminId);

            // 查询统计信息
            AdminUserDto.UserStatistics statistics = userMapper.selectUserStatistics();
            return ApiResponse.success(statistics);
        } catch (Exception e) {
            log.error("查询用户统计信息失败", e);
            return ApiResponse.error(500, "查询用户统计信息失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> resetUserPassword(Long userId, String newPassword) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 重置用户密码，用户ID: {}", adminId, userId);

            // 检查用户是否存在
            User existingUser = userMapper.selectById(userId);
            if (existingUser == null) {
                return ApiResponse.error(404, "用户不存在");
            }

            // 生成新的密码哈希（使用简单的MD5，实际项目中应该使用更安全的方式）
            String newPasswordJwt = java.security.MessageDigest.getInstance("MD5")
                    .digest(newPassword.getBytes())
                    .toString();

            // 更新密码
            User updateUser = new User();
            updateUser.setId(userId);
            updateUser.setPasswordJwt(newPasswordJwt);
            updateUser.setUpdateTime(LocalDateTime.now());

            int result = userMapper.updateById(updateUser);
            if (result > 0) {
                log.info("用户密码重置成功，用户ID: {}", userId);
                return ApiResponse.success("用户密码重置成功");
            } else {
                return ApiResponse.error(500, "用户密码重置失败");
            }
        } catch (Exception e) {
            log.error("重置用户密码失败，用户ID: {}", userId, e);
            return ApiResponse.error(500, "重置用户密码失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> batchUpdateUserRole(List<Long> userIds, Integer role, LocalDateTime membershipExpiresAt) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 批量更新用户角色，用户数量: {}, 角色: {}", adminId, userIds.size(), role);

            if (userIds == null || userIds.isEmpty()) {
                return ApiResponse.error(400, "用户ID列表不能为空");
            }

            int successCount = 0;
            for (Long userId : userIds) {
                try {
                    int result = userMapper.updateRoleAndMembership(userId, role, membershipExpiresAt);
                    if (result > 0) {
                        successCount++;
                    }
                } catch (Exception e) {
                    log.warn("更新用户角色失败，用户ID: {}", userId, e);
                }
            }

            log.info("批量更新用户角色完成，成功: {}, 总数: {}", successCount, userIds.size());
            return ApiResponse.success(String.format("批量更新完成，成功更新 %d/%d 个用户", successCount, userIds.size()));
        } catch (Exception e) {
            log.error("批量更新用户角色失败", e);
            return ApiResponse.error(500, "批量更新用户角色失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public ApiResponse<String> batchUpdatePromotionLevel(List<Long> userIds, Integer promotionLevel) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 批量更新用户推广等级，用户数量: {}, 推广等级: {}", adminId, userIds.size(), promotionLevel);

            if (userIds == null || userIds.isEmpty()) {
                return ApiResponse.error(400, "用户ID列表不能为空");
            }

            int successCount = 0;
            for (Long userId : userIds) {
                try {
                    int result = userMapper.updatePromotionLevel(userId, promotionLevel);
                    if (result > 0) {
                        successCount++;
                    }
                } catch (Exception e) {
                    log.warn("更新用户推广等级失败，用户ID: {}", userId, e);
                }
            }

            log.info("批量更新用户推广等级完成，成功: {}, 总数: {}", successCount, userIds.size());
            return ApiResponse.success(String.format("批量更新完成，成功更新 %d/%d 个用户", successCount, userIds.size()));
        } catch (Exception e) {
            log.error("批量更新用户推广等级失败", e);
            return ApiResponse.error(500, "批量更新用户推广等级失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<String> exportUserData(AdminUserDto.UserListRequest request) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 导出用户数据", adminId);

            // TODO: 实现用户数据导出功能
            // 这里可以调用第三方服务或使用POI等库生成Excel文件
            // 暂时返回占位符
            return ApiResponse.error(501, "用户数据导出功能暂未实现");
        } catch (Exception e) {
            log.error("导出用户数据失败", e);
            return ApiResponse.error(500, "导出用户数据失败: " + e.getMessage());
        }
    }

    @Override
    public ApiResponse<PageResultDto<AdminUserDto.UserOperationLog>> getUserOperationLogs(Long userId, Integer page, Integer size) {
        try {
            // 验证管理员权限
            Long adminId = AdminSecurityUtil.getCurrentAdminId();
            log.info("管理员 {} 查询用户操作日志，用户ID: {}", adminId, userId);

            // TODO: 实现用户操作日志查询功能
            // 这里需要创建用户操作日志表和相关查询逻辑
            // 暂时返回空结果
            PageResultDto<AdminUserDto.UserOperationLog> result = new PageResultDto<>(
                0L, (long) page, (long) size, java.util.Collections.emptyList()
            );

            return ApiResponse.success(result);
        } catch (Exception e) {
            log.error("查询用户操作日志失败，用户ID: {}", userId, e);
            return ApiResponse.error(500, "查询用户操作日志失败: " + e.getMessage());
        }
    }
}
