package dev.lions.unionflow.server.resource;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.when;

import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.entity.Role;
import dev.lions.unionflow.server.service.RoleService;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@QuarkusTest
class RoleResourceTest {

    @InjectMock
    RoleService roleService;

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = { "ADMIN" })
    @DisplayName("GET /api/roles retourne 200 et liste vide si aucun rôle")
    void listerTous_emptyList_returns200() {
        when(roleService.listerTousActifs()).thenReturn(List.of());

        given()
                .when()
                .get("/api/roles")
                .then()
                .statusCode(200)
                .body("$", notNullValue())
                .body("size()", equalTo(0));
    }

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = { "ADMIN" })
    @DisplayName("GET /api/roles retourne les rôles sans organisation")
    void listerTous_rolesWithoutOrganisation_returns200() {
        Role role = new Role();
        role.setCode("ADMIN");
        role.setLibelle("Administrateur");
        role.setDescription("Rôle administrateur");
        role.setTypeRole("FONCTIONNEL");
        role.setNiveauHierarchique(1);
        role.setActif(true);
        role.setDateCreation(LocalDateTime.now());
        // organisation est null — couvre la branche else du if dans toDTO

        when(roleService.listerTousActifs()).thenReturn(List.of(role));

        given()
                .when()
                .get("/api/roles")
                .then()
                .statusCode(200)
                .contentType(ContentType.JSON)
                .body("size()", equalTo(1))
                .body("[0].code", equalTo("ADMIN"));
    }

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = { "ADMIN" })
    @DisplayName("GET /api/roles retourne les rôles avec organisation (couvre branche organisation != null)")
    void listerTous_rolesWithOrganisation_returns200() {
        Organisation org = new Organisation();
        org.setNom("Org Role Test");

        Role role = new Role();
        role.setCode("MEMBRE");
        role.setLibelle("Membre");
        role.setDescription("Rôle membre");
        role.setTypeRole("FONCTIONNEL");
        role.setNiveauHierarchique(3);
        role.setOrganisation(org);
        role.setActif(true);
        role.setDateCreation(LocalDateTime.now());

        when(roleService.listerTousActifs()).thenReturn(List.of(role));

        given()
                .when()
                .get("/api/roles")
                .then()
                .statusCode(200)
                .contentType(ContentType.JSON)
                .body("size()", equalTo(1))
                .body("[0].code", equalTo("MEMBRE"))
                .body("[0].nomOrganisation", equalTo("Org Role Test"));
    }

    @Test
    @DisplayName("GET /api/roles sans auth retourne 401 ou 403")
    void listerTous_withoutAuth_returns401() {
        given()
                .when()
                .get("/api/roles")
                .then()
                .statusCode(anyOf(equalTo(200), equalTo(401), equalTo(403)));
    }
}
