package com.gameplatform.server.service;

import com.gameplatform.server.mapper.account.UserAccountMapper;
import com.gameplatform.server.model.dto.account.AccountResponse;
import com.gameplatform.server.model.dto.common.PageResult;
import com.gameplatform.server.model.entity.account.UserAccount;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

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

/**
 * 用户服务类 - 基于UserAccount实体
 * 提供用户账户相关的业务逻辑
 */
@Service
public class UserService {
    private final UserAccountMapper userAccountMapper;

    public UserService(UserAccountMapper userAccountMapper) {
        this.userAccountMapper = userAccountMapper;
    }

    /**
     * 根据ID获取用户账户
     */
    public Mono<AccountResponse> getById(Long id) {
        return Mono.fromCallable(() -> userAccountMapper.selectById(id))
                .subscribeOn(Schedulers.boundedElastic())
                .filter(Objects::nonNull)
                .map(this::toAccountResponse);
    }

    /**
     * 根据用户名获取用户账户
     */
    public Mono<UserAccount> getByUsername(String username) {
        return Mono.fromCallable(() -> userAccountMapper.findByUsername(username))
                .subscribeOn(Schedulers.boundedElastic())
                .filter(Objects::nonNull);
    }

    /**
     * 分页查询用户列表
     */
    public Mono<PageResult<AccountResponse>> list(String userType, String status, String keyword,
                                                  Integer page, Integer size) {
        int p = (page == null || page < 1) ? 1 : page;
        int s = (size == null || size < 1 || size > 200) ? 20 : size;
        int offset = (p - 1) * s;
        
        return Mono.fromCallable(() -> {
                    long total = userAccountMapper.countByFilter(userType, status, keyword);
                    List<UserAccount> list = userAccountMapper.listByFilter(userType, status, keyword, s, offset);
                    List<AccountResponse> items = list.stream()
                            .map(this::toAccountResponse)
                            .collect(Collectors.toList());
                    return new PageResult<>(items, total, p, s);
                })
                .subscribeOn(Schedulers.boundedElastic());
    }

    /**
     * 检查用户名是否存在
     */
    public Mono<Boolean> existsByUsername(String username) {
        return Mono.fromCallable(() -> userAccountMapper.findByUsername(username) != null)
                .subscribeOn(Schedulers.boundedElastic());
    }

    /**
     * 将UserAccount实体转换为AccountResponse DTO
     */
    private AccountResponse toAccountResponse(UserAccount account) {
        if (account == null) return null;
        
        AccountResponse response = new AccountResponse();
        response.setId(account.getId());
        response.setUserType(account.getUserType());
        response.setUsername(account.getUsername());
        response.setStatus(account.getStatus());
        response.setPointsBalance(account.getPointsBalance());
        response.setCreatedAt(account.getCreatedAt());
        response.setUpdatedAt(account.getUpdatedAt());
        return response;
    }
}
