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

import cn.novalon.gym.manage.sys.core.domain.SysPermission;
import cn.novalon.gym.manage.sys.core.repository.ISysPermissionRepository;
import cn.novalon.gym.manage.db.converter.SysPermissionConverter;
import cn.novalon.gym.manage.db.dao.SysPermissionDao;
import cn.novalon.gym.manage.db.entity.SysPermissionEntity;
import org.springframework.data.domain.Sort;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * 权限仓储实现类
 * 
 * @author 张翔
 * @date 2026-03-25
 */
@Repository
public class SysPermissionRepository implements ISysPermissionRepository {

    private final SysPermissionDao sysPermissionDao;
    private final SysPermissionConverter sysPermissionConverter;
    private final R2dbcEntityTemplate r2dbcEntityTemplate;

    public SysPermissionRepository(SysPermissionDao sysPermissionDao, SysPermissionConverter sysPermissionConverter, R2dbcEntityTemplate r2dbcEntityTemplate) {
        this.sysPermissionDao = sysPermissionDao;
        this.sysPermissionConverter = sysPermissionConverter;
        this.r2dbcEntityTemplate = r2dbcEntityTemplate;
    }

    @Override
    public Mono<SysPermission> findById(Long id) {
        return sysPermissionDao.findByIdAndDeletedAtIsNull(id)
                .map(sysPermissionConverter::toDomain);
    }

    @Override
    public Mono<SysPermission> findByIdIncludingDeleted(Long id) {
        return sysPermissionDao.findById(id)
                .map(sysPermissionConverter::toDomain);
    }

    @Override
    public Mono<SysPermission> save(SysPermission sysPermission) {
        SysPermissionEntity entity = sysPermissionConverter.toEntity(sysPermission);
        if (entity.isNew()) {
            return r2dbcEntityTemplate.insert(SysPermissionEntity.class)
                    .using(entity)
                    .doOnNext(e -> e.markNotNew())
                    .map(sysPermissionConverter::toDomain);
        }
        return sysPermissionDao.save(entity)
                .map(sysPermissionConverter::toDomain);
    }

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

    @Override
    public Flux<SysPermission> findAll() {
        return sysPermissionDao.findByDeletedAtIsNull()
                .map(sysPermissionConverter::toDomain);
    }

    @Override
    public Flux<SysPermission> findAll(Sort sort) {
        return sysPermissionDao.findByDeletedAtIsNull(sort)
                .map(sysPermissionConverter::toDomain);
    }

    @Override
    public Mono<SysPermission> findByPermissionCode(String permissionCode) {
        return sysPermissionDao.findByPermissionCodeAndDeletedAtIsNull(permissionCode)
                .map(sysPermissionConverter::toDomain);
    }

    @Override
    public Mono<Long> count() {
        return sysPermissionDao.countByDeletedAtIsNull();
    }

    @Override
    public Mono<Boolean> existsByPermissionCode(String permissionCode) {
        return sysPermissionDao.existsByPermissionCodeAndDeletedAtIsNull(permissionCode);
    }

    @Override
    public Mono<SysPermission> updatePermission(SysPermission permission) {
        return sysPermissionDao.save(sysPermissionConverter.toEntity(permission))
                .map(sysPermissionConverter::toDomain);
    }

    @Override
    public Flux<SysPermission> findByRoleId(Long roleId) {
        return sysPermissionDao.findByRoleId(roleId)
                .map(sysPermissionConverter::toDomain);
    }

    @Override
    public Flux<SysPermission> findByRoleIds(java.util.List<Long> roleIds) {
        return sysPermissionDao.findByRoleIds(roleIds)
                .map(sysPermissionConverter::toDomain);
    }
}