package cn.novalon.gym.manage.sys.core.service.impl;

import cn.novalon.gym.manage.sys.audit.service.IAuditLogService;
import cn.novalon.gym.manage.sys.core.domain.SysConfig;
import cn.novalon.gym.manage.sys.core.repository.ISysConfigRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * 系统配置服务单元测试类
 * 
 * @author 张翔
 * @date 2026-03-31
 */
@ExtendWith(MockitoExtension.class)
class SysConfigServiceTest {

    @Mock
    private ISysConfigRepository repository;

    @Mock
    private IAuditLogService auditLogService;

    private SysConfigService configService;

    private SysConfig testConfig;

    @BeforeEach
    void setUp() {
        configService = new SysConfigService(repository, auditLogService);

        testConfig = new SysConfig();
        testConfig.setId(1L);
        testConfig.setConfigKey("app.name");
        testConfig.setConfigValue("Novalon Manage System");
        testConfig.setConfigName("Application Name");
        testConfig.setConfigType("system");
    }

    @Test
    void testFindAll() {
        when(repository.findByDeletedAtIsNull()).thenReturn(Flux.just(testConfig));

        StepVerifier.create(configService.findAll())
                .expectNext(testConfig)
                .verifyComplete();

        verify(repository).findByDeletedAtIsNull();
    }

    @Test
    void testFindById() {
        when(repository.findById(1L)).thenReturn(Mono.just(testConfig));

        StepVerifier.create(configService.findById(1L))
                .expectNext(testConfig)
                .verifyComplete();

        verify(repository).findById(1L);
    }

    @Test
    void testFindById_NotFound() {
        when(repository.findById(999L)).thenReturn(Mono.empty());

        StepVerifier.create(configService.findById(999L))
                .expectNextCount(0)
                .verifyComplete();

        verify(repository).findById(999L);
    }

    @Test
    void testFindByConfigKey() {
        when(repository.findByConfigKeyAndDeletedAtIsNull("app.name")).thenReturn(Mono.just(testConfig));

        StepVerifier.create(configService.findByConfigKey("app.name"))
                .expectNext(testConfig)
                .verifyComplete();

        verify(repository).findByConfigKeyAndDeletedAtIsNull("app.name");
    }

    @Test
    void testFindByConfigKey_NotFound() {
        when(repository.findByConfigKeyAndDeletedAtIsNull("unknown.key")).thenReturn(Mono.empty());

        StepVerifier.create(configService.findByConfigKey("unknown.key"))
                .expectNextCount(0)
                .verifyComplete();

        verify(repository).findByConfigKeyAndDeletedAtIsNull("unknown.key");
    }

    @Test
    void testSave() {
        when(repository.save(testConfig)).thenReturn(Mono.just(testConfig));

        StepVerifier.create(configService.save(testConfig))
                .expectNext(testConfig)
                .verifyComplete();

        verify(repository).save(testConfig);
    }

    @Test
    void testDeleteById() {
        when(repository.findById(1L)).thenReturn(Mono.just(testConfig));
        when(repository.deleteByIdAndDeletedAtIsNull(1L)).thenReturn(Mono.empty());

        StepVerifier.create(configService.deleteById(1L))
                .verifyComplete();

        verify(repository).findById(1L);
        verify(repository).deleteByIdAndDeletedAtIsNull(1L);
    }

    @Test
    void testGetConfigValue() {
        when(repository.findByConfigKeyAndDeletedAtIsNull("app.name")).thenReturn(Mono.just(testConfig));

        StepVerifier.create(configService.getConfigValue("app.name"))
                .expectNext("Novalon Manage System")
                .verifyComplete();

        verify(repository).findByConfigKeyAndDeletedAtIsNull("app.name");
    }

    @Test
    void testGetConfigValue_NotFound() {
        when(repository.findByConfigKeyAndDeletedAtIsNull("unknown.key")).thenReturn(Mono.empty());

        StepVerifier.create(configService.getConfigValue("unknown.key"))
                .expectNextCount(0)
                .verifyComplete();

        verify(repository).findByConfigKeyAndDeletedAtIsNull("unknown.key");
    }

    @Test
    void testFindAll_Empty() {
        when(repository.findByDeletedAtIsNull()).thenReturn(Flux.empty());

        StepVerifier.create(configService.findAll())
                .expectNextCount(0)
                .verifyComplete();

        verify(repository).findByDeletedAtIsNull();
    }

    @Test
    void testSave_NewConfig() {
        SysConfig newConfig = new SysConfig();
        newConfig.setConfigKey("new.key");
        newConfig.setConfigValue("new value");
        newConfig.setConfigName("New Config");
        newConfig.setConfigType("custom");

        when(repository.save(newConfig)).thenReturn(Mono.just(newConfig));

        StepVerifier.create(configService.save(newConfig))
                .expectNext(newConfig)
                .verifyComplete();

        verify(repository).save(newConfig);
    }
}