package dev.lions.user.manager.dto.base;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

import static org.junit.jupiter.api.Assertions.*;

class BaseDTOTest {

    // Concrete implementation for testing abstract class
    static class TestDTO extends BaseDTO {
        private static final long serialVersionUID = 1L;
    }

    @Test
    void testSettersAndGetters() {
        TestDTO dto = new TestDTO();
        LocalDateTime now = LocalDateTime.now();

        dto.setId("uuid-123");
        dto.setDateCreation(now);
        dto.setDateModification(now);
        dto.setCreeParUsername("admin");
        dto.setModifieParUsername("superadmin");
        dto.setVersion(1L);

        assertEquals("uuid-123", dto.getId());
        assertEquals(now, dto.getDateCreation());
        assertEquals(now, dto.getDateModification());
        assertEquals("admin", dto.getCreeParUsername());
        assertEquals("superadmin", dto.getModifieParUsername());
        assertEquals(1L, dto.getVersion());
    }

    @Test
    void testEqualsAndHashCode() {
        TestDTO dto1 = new TestDTO();
        dto1.setId("uuid-123");
        dto1.setVersion(1L);

        TestDTO dto2 = new TestDTO();
        dto2.setId("uuid-123");
        dto2.setVersion(1L);

        TestDTO dto3 = new TestDTO();
        dto3.setId("uuid-456");
        dto3.setVersion(2L);

        assertEquals(dto1, dto2);
        assertEquals(dto1.hashCode(), dto2.hashCode());
        assertNotEquals(dto1, dto3);
    }

    @Test
    void testToString() {
        TestDTO dto = new TestDTO();
        dto.setId("uuid-123");
        dto.setCreeParUsername("admin");

        String str = dto.toString();
        assertNotNull(str);
        assertTrue(str.contains("uuid-123"));
        assertTrue(str.contains("admin"));
    }

    @Test
    void testNoArgsConstructor() {
        TestDTO dto = new TestDTO();
        assertNull(dto.getId());
        assertNull(dto.getDateCreation());
        assertNull(dto.getDateModification());
        assertNull(dto.getCreeParUsername());
        assertNull(dto.getModifieParUsername());
        assertNull(dto.getVersion());
    }

    @Test
    void testAllFields() {
        LocalDateTime creationTime = LocalDateTime.of(2025, 1, 15, 10, 30);
        LocalDateTime modificationTime = LocalDateTime.of(2025, 1, 15, 14, 20);

        TestDTO dto = new TestDTO();
        dto.setId("f47ac10b-58cc-4372-a567-0e02b2c3d479");
        dto.setDateCreation(creationTime);
        dto.setDateModification(modificationTime);
        dto.setCreeParUsername("admin@lions.dev");
        dto.setModifieParUsername("superadmin@lions.dev");
        dto.setVersion(5L);

        assertEquals("f47ac10b-58cc-4372-a567-0e02b2c3d479", dto.getId());
        assertEquals(creationTime, dto.getDateCreation());
        assertEquals(modificationTime, dto.getDateModification());
        assertEquals("admin@lions.dev", dto.getCreeParUsername());
        assertEquals("superadmin@lions.dev", dto.getModifieParUsername());
        assertEquals(5L, dto.getVersion());
    }

    @Test
    void testEqualsWithNull() {
        TestDTO dto = new TestDTO();
        dto.setId("uuid-123");

        assertNotEquals(null, dto);
    }

    @Test
    void testEqualsWithDifferentClass() {
        TestDTO dto = new TestDTO();
        dto.setId("uuid-123");

        assertNotEquals("string", dto);
    }

    @Test
    void testEqualsSameObject() {
        TestDTO dto = new TestDTO();
        dto.setId("uuid-123");

        assertEquals(dto, dto);
    }

    @Test
    void testHashCodeConsistency() {
        TestDTO dto = new TestDTO();
        dto.setId("uuid-123");
        dto.setVersion(1L);

        int hash1 = dto.hashCode();
        int hash2 = dto.hashCode();

        assertEquals(hash1, hash2);
    }
}
