package cn.novalon.gym.manage.db.repository;

import cn.novalon.gym.manage.db.converter.UserRoleConverter;
import cn.novalon.gym.manage.db.dao.UserRoleDao;
import cn.novalon.gym.manage.db.entity.UserRoleEntity;
import cn.novalon.gym.manage.sys.core.domain.UserRole;
import cn.novalon.gym.manage.sys.core.repository.IUserRoleRepository;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Repository
public class UserRoleRepository implements IUserRoleRepository {

    private final UserRoleDao userRoleDao;
    private final UserRoleConverter userRoleConverter;

    public UserRoleRepository(UserRoleDao userRoleDao, UserRoleConverter userRoleConverter) {
        this.userRoleDao = userRoleDao;
        this.userRoleConverter = userRoleConverter;
    }

    @Override
    public Mono<UserRole> save(UserRole userRole) {
        UserRoleEntity entity = userRoleConverter.toEntity(userRole);
        return userRoleDao.save(entity)
                .map(userRoleConverter::toDomain);
    }

    @Override
    public Mono<Void> deleteById(Long id) {
        return userRoleDao.deleteById(id);
    }

    @Override
    public Mono<Void> deleteByUserId(Long userId) {
        return userRoleDao.deleteByUserId(userId).then();
    }

    @Override
    public Mono<Void> deleteByRoleId(Long roleId) {
        return userRoleDao.deleteByRoleId(roleId).then();
    }

    @Override
    public Flux<UserRole> findByUserId(Long userId) {
        return userRoleDao.findByUserId(userId, Sort.by(Sort.Direction.DESC, "created_at"))
                .map(userRoleConverter::toDomain);
    }

    @Override
    public Flux<UserRole> findByRoleId(Long roleId) {
        return userRoleDao.findByRoleId(roleId, Sort.by(Sort.Direction.DESC, "created_at"))
                .map(userRoleConverter::toDomain);
    }

    @Override
    public Mono<Long> countByUserId(Long userId) {
        return userRoleDao.countByUserId(userId);
    }

    @Override
    public Mono<Long> countByRoleId(Long roleId) {
        return userRoleDao.countByRoleId(roleId);
    }

    @Override
    public Flux<UserRole> findAll() {
        return userRoleDao.findAll()
                .map(userRoleConverter::toDomain);
    }

    @Override
    public Mono<UserRole> findById(Long id) {
        return userRoleDao.findById(id)
                .map(userRoleConverter::toDomain);
    }
}
