package net.siegeln.cameleer.saas.audit;

import net.siegeln.cameleer.saas.TestcontainersConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Map;
import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@DataJpaTest
@Import(TestcontainersConfig.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("test")
class AuditRepositoryTest {

    @Autowired
    private AuditRepository auditRepository;

    @Test
    void save_persistsAuditEntry() {
        var entry = new AuditEntity();
        entry.setActorId(UUID.randomUUID());
        entry.setActorEmail("test@example.com");
        entry.setAction("AUTH_LOGIN");
        entry.setResult("SUCCESS");

        var saved = auditRepository.save(entry);

        assertNotNull(saved.getId());
        assertNotNull(saved.getCreatedAt());
        assertEquals("AUTH_LOGIN", saved.getAction());
    }

    @Test
    void findByTenantId_returnsFilteredResults() {
        UUID tenantA = UUID.randomUUID();
        UUID tenantB = UUID.randomUUID();

        var entryA = new AuditEntity();
        entryA.setTenantId(tenantA);
        entryA.setAction("AUTH_LOGIN");
        entryA.setResult("SUCCESS");
        auditRepository.save(entryA);

        var entryB = new AuditEntity();
        entryB.setTenantId(tenantB);
        entryB.setAction("AUTH_LOGIN");
        entryB.setResult("SUCCESS");
        auditRepository.save(entryB);

        Instant from = Instant.now().minus(1, ChronoUnit.HOURS);
        Instant to = Instant.now().plus(1, ChronoUnit.HOURS);

        var results = auditRepository.findByTenantIdAndCreatedAtBetween(tenantA, from, to);

        assertEquals(1, results.size());
        assertEquals(tenantA, results.get(0).getTenantId());
    }

    @Test
    void save_persistsJsonMetadata() {
        var entry = new AuditEntity();
        entry.setAction("CONFIG_UPDATE");
        entry.setResult("SUCCESS");
        entry.setMetadata(Map.of("setting", "timeout", "oldValue", "30", "newValue", "60"));

        var saved = auditRepository.save(entry);

        var found = auditRepository.findById(saved.getId()).orElseThrow();
        assertNotNull(found.getMetadata());
        assertFalse(found.getMetadata().isEmpty());
        assertEquals("timeout", found.getMetadata().get("setting"));
    }
}
