package dev.lions.user.manager.resource;

import dev.lions.user.manager.api.SyncResourceApi;
import dev.lions.user.manager.dto.sync.HealthStatusDTO;
import dev.lions.user.manager.dto.sync.SyncResultDTO;
import dev.lions.user.manager.service.SyncService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class SyncResourceTest {

    @Mock
    SyncService syncService;

    @InjectMocks
    SyncResource syncResource;

    private static final String REALM = "test-realm";

    @Test
    void testCheckKeycloakHealth() {
        when(syncService.isKeycloakAvailable()).thenReturn(true);
        when(syncService.getKeycloakHealthInfo()).thenReturn(Map.of("version", "23.0.0"));

        HealthStatusDTO status = syncResource.checkKeycloakHealth();

        assertTrue(status.isKeycloakAccessible());
        assertTrue(status.isOverallHealthy());
        assertEquals("23.0.0", status.getKeycloakVersion());
    }

    @Test
    void testCheckKeycloakHealthError() {
        when(syncService.isKeycloakAvailable()).thenThrow(new RuntimeException("Connection refused"));

        HealthStatusDTO status = syncResource.checkKeycloakHealth();

        assertFalse(status.isOverallHealthy());
        assertTrue(status.getErrorMessage().contains("Connection refused"));
    }

    @Test
    void testSyncUsers() {
        when(syncService.syncUsersFromRealm(REALM)).thenReturn(10);

        SyncResultDTO result = syncResource.syncUsers(REALM);

        assertTrue(result.isSuccess());
        assertEquals(10, result.getUsersCount());
        assertEquals(REALM, result.getRealmName());
    }

    @Test
    void testSyncUsersError() {
        when(syncService.syncUsersFromRealm(REALM)).thenThrow(new RuntimeException("Sync failed"));

        SyncResultDTO result = syncResource.syncUsers(REALM);

        assertFalse(result.isSuccess());
        assertEquals("Sync failed", result.getErrorMessage());
    }

    @Test
    void testSyncRoles() {
        when(syncService.syncRolesFromRealm(REALM)).thenReturn(5);

        SyncResultDTO result = syncResource.syncRoles(REALM, null);

        assertTrue(result.isSuccess());
        assertEquals(5, result.getRealmRolesCount());
    }
}
