package cn.novalon.gym.manage.sys.audit.domain;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

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

/**
 * AuditLog 单元测试
 * 
 * @author 张翔
 * @date 2026-04-14
 */
class AuditLogTest {

    @Test
    @DisplayName("创建默认审计日志")
    void createDefaultAuditLog_shouldHaveNullFields() {
        AuditLog auditLog = new AuditLog();
        
        assertNull(auditLog.getId());
        assertNull(auditLog.getEntityType());
        assertNull(auditLog.getEntityId());
        assertNull(auditLog.getOperator());
        assertNull(auditLog.getOperationType());
        assertNotNull(auditLog.getOperationTime());
        assertNull(auditLog.getDescription());
        assertNull(auditLog.getIpAddress());
        assertNull(auditLog.getUserAgent());
        assertNull(auditLog.getDeletedAt());
    }

    @Test
    @DisplayName("设置和获取ID")
    void setAndGetId_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setId(1L);
        
        assertEquals(1L, auditLog.getId());
    }

    @Test
    @DisplayName("设置和获取实体类型")
    void setAndGetEntityType_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setEntityType("User");
        
        assertEquals("User", auditLog.getEntityType());
    }

    @Test
    @DisplayName("设置和获取实体ID")
    void setAndGetEntityId_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setEntityId(100L);
        
        assertEquals(100L, auditLog.getEntityId());
    }

    @Test
    @DisplayName("设置和获取操作人")
    void setAndGetOperator_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setOperator("admin");
        
        assertEquals("admin", auditLog.getOperator());
    }

    @Test
    @DisplayName("设置和获取操作类型")
    void setAndGetOperationType_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setOperationType("CREATE");
        
        assertEquals("CREATE", auditLog.getOperationType());
    }

    @Test
    @DisplayName("设置和获取操作时间")
    void setAndGetOperationTime_shouldWorkCorrectly() {
        LocalDateTime operationTime = LocalDateTime.now();
        AuditLog auditLog = new AuditLog();
        auditLog.setOperationTime(operationTime);
        
        assertEquals(operationTime, auditLog.getOperationTime());
    }

    @Test
    @DisplayName("设置和获取描述")
    void setAndGetDescription_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setDescription("创建用户");
        
        assertEquals("创建用户", auditLog.getDescription());
    }

    @Test
    @DisplayName("设置和获取IP地址")
    void setAndGetIpAddress_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setIpAddress("192.168.1.1");
        
        assertEquals("192.168.1.1", auditLog.getIpAddress());
    }

    @Test
    @DisplayName("设置和获取用户代理")
    void setAndGetUserAgent_shouldWorkCorrectly() {
        AuditLog auditLog = new AuditLog();
        auditLog.setUserAgent("Mozilla/5.0");
        
        assertEquals("Mozilla/5.0", auditLog.getUserAgent());
    }

    @Test
    @DisplayName("设置和获取删除时间")
    void setAndGetDeletedAt_shouldWorkCorrectly() {
        LocalDateTime deletedAt = LocalDateTime.now();
        AuditLog auditLog = new AuditLog();
        auditLog.setDeletedAt(deletedAt);
        
        assertEquals(deletedAt, auditLog.getDeletedAt());
    }

    @Test
    @DisplayName("toString方法应包含所有字段")
    void toString_shouldContainAllFields() {
        LocalDateTime operationTime = LocalDateTime.now();
        
        AuditLog auditLog = new AuditLog();
        auditLog.setId(1L);
        auditLog.setEntityType("User");
        auditLog.setEntityId(100L);
        auditLog.setOperator("admin");
        auditLog.setOperationType("CREATE");
        auditLog.setOperationTime(operationTime);
        auditLog.setDescription("创建用户");
        auditLog.setIpAddress("192.168.1.1");
        auditLog.setUserAgent("Mozilla/5.0");
        
        String toString = auditLog.toString();
        
        assertTrue(toString.contains("1"));
        assertTrue(toString.contains("User"));
        assertTrue(toString.contains("100"));
        assertTrue(toString.contains("admin"));
        assertTrue(toString.contains("CREATE"));
        assertTrue(toString.contains("创建用户"));
        assertTrue(toString.contains("192.168.1.1"));
        assertTrue(toString.contains("Mozilla/5.0"));
    }

    @Test
    @DisplayName("equals和hashCode方法应基于字段值")
    void equalsAndHashCode_shouldBeBasedOnFieldValues() {
        LocalDateTime operationTime = LocalDateTime.now();
        
        AuditLog auditLog1 = new AuditLog();
        auditLog1.setId(1L);
        auditLog1.setEntityType("User");
        auditLog1.setEntityId(100L);
        auditLog1.setOperator("admin");
        auditLog1.setOperationType("CREATE");
        auditLog1.setOperationTime(operationTime);
        auditLog1.setDescription("创建用户");
        auditLog1.setIpAddress("192.168.1.1");
        auditLog1.setUserAgent("Mozilla/5.0");
        
        AuditLog auditLog2 = new AuditLog();
        auditLog2.setId(1L);
        auditLog2.setEntityType("User");
        auditLog2.setEntityId(100L);
        auditLog2.setOperator("admin");
        auditLog2.setOperationType("CREATE");
        auditLog2.setOperationTime(operationTime);
        auditLog2.setDescription("创建用户");
        auditLog2.setIpAddress("192.168.1.1");
        auditLog2.setUserAgent("Mozilla/5.0");
        
        assertEquals(auditLog1, auditLog2);
        assertEquals(auditLog1.hashCode(), auditLog2.hashCode());
    }

    @Test
    @DisplayName("不同ID的对象应不相等")
    void differentIds_shouldNotBeEqual() {
        AuditLog auditLog1 = new AuditLog();
        auditLog1.setId(1L);
        
        AuditLog auditLog2 = new AuditLog();
        auditLog2.setId(2L);
        
        assertNotEquals(auditLog1, auditLog2);
    }

    @Test
    @DisplayName("null对象应不相等")
    void nullObject_shouldNotBeEqual() {
        AuditLog auditLog = new AuditLog();
        auditLog.setId(1L);
        
        assertNotEquals(auditLog, null);
    }

    @Test
    @DisplayName("不同类型对象应不相等")
    void differentTypeObject_shouldNotBeEqual() {
        AuditLog auditLog = new AuditLog();
        auditLog.setId(1L);
        
        assertNotEquals(auditLog, "not an audit log");
    }

    @Test
    @DisplayName("相同对象引用应相等")
    void sameObjectReference_shouldBeEqual() {
        AuditLog auditLog = new AuditLog();
        auditLog.setId(1L);
        
        assertEquals(auditLog, auditLog);
    }
}