package cn.novalon.gym.manage.sys.core.command;

import org.junit.jupiter.api.Test;

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

class UpdateUserCommandTest {

    @Test
    void testConstructor() {
        UpdateUserCommand command = new UpdateUserCommand(
                1L,
                "testuser",
                "password123",
                "test@example.com",
                2L,
                1,
                false
        );

        assertEquals(1L, command.id());
        assertEquals("testuser", command.username());
        assertEquals("password123", command.password());
        assertEquals("test@example.com", command.email());
        assertEquals(2L, command.roleId());
        assertEquals(1, command.status());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithoutClearRole() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "testuser",
                "password123",
                "test@example.com",
                2L,
                1
        );

        assertEquals(1L, command.id());
        assertEquals("testuser", command.username());
        assertEquals("password123", command.password());
        assertEquals("test@example.com", command.email());
        assertEquals(2L, command.roleId());
        assertEquals(1, command.status());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithClearRoleFalse() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "testuser",
                "password123",
                "test@example.com",
                2L,
                1,
                false
        );

        assertEquals(1L, command.id());
        assertEquals("testuser", command.username());
        assertEquals("password123", command.password());
        assertEquals("test@example.com", command.email());
        assertEquals(2L, command.roleId());
        assertEquals(1, command.status());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithClearRoleTrue() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "testuser",
                "password123",
                "test@example.com",
                2L,
                1,
                true
        );

        assertEquals(1L, command.id());
        assertEquals("testuser", command.username());
        assertEquals("password123", command.password());
        assertEquals("test@example.com", command.email());
        assertEquals(2L, command.roleId());
        assertEquals(1, command.status());
        assertTrue(command.clearRole());
    }

    @Test
    void testOf_WithNullValues() {
        UpdateUserCommand command = UpdateUserCommand.of(
                null,
                null,
                null,
                null,
                null,
                null
        );

        assertNull(command.id());
        assertNull(command.username());
        assertNull(command.password());
        assertNull(command.email());
        assertNull(command.roleId());
        assertNull(command.status());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithEmptyStrings() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "",
                "",
                "",
                null,
                null
        );

        assertEquals(1L, command.id());
        assertEquals("", command.username());
        assertEquals("", command.password());
        assertEquals("", command.email());
        assertNull(command.roleId());
        assertNull(command.status());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithBoundaryValues() {
        UpdateUserCommand command = UpdateUserCommand.of(
                Long.MAX_VALUE,
                "a",
                "1",
                "a@b.c",
                Long.MAX_VALUE,
                Integer.MAX_VALUE,
                true
        );

        assertEquals(Long.MAX_VALUE, command.id());
        assertEquals("a", command.username());
        assertEquals("1", command.password());
        assertEquals("a@b.c", command.email());
        assertEquals(Long.MAX_VALUE, command.roleId());
        assertEquals(Integer.MAX_VALUE, command.status());
        assertTrue(command.clearRole());
    }

    @Test
    void testOf_WithZeroValues() {
        UpdateUserCommand command = UpdateUserCommand.of(
                0L,
                "testuser",
                "password123",
                "test@example.com",
                0L,
                0,
                false
        );

        assertEquals(0L, command.id());
        assertEquals(0L, command.roleId());
        assertEquals(0, command.status());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithNegativeValues() {
        UpdateUserCommand command = UpdateUserCommand.of(
                -1L,
                "testuser",
                "password123",
                "test@example.com",
                -1L,
                -1,
                true
        );

        assertEquals(-1L, command.id());
        assertEquals(-1L, command.roleId());
        assertEquals(-1, command.status());
        assertTrue(command.clearRole());
    }

    @Test
    void testOf_WithSpecialCharacters() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "user@#$%",
                "pass@#$%",
                "test@#$%.com",
                1L,
                1,
                false
        );

        assertEquals("user@#$%", command.username());
        assertEquals("pass@#$%", command.password());
        assertEquals("test@#$%.com", command.email());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithLongStrings() {
        String longUsername = "a".repeat(1000);
        String longPassword = "b".repeat(1000);
        String longEmail = "c".repeat(1000) + "@example.com";
        
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                longUsername,
                longPassword,
                longEmail,
                1L,
                1,
                false
        );

        assertEquals(longUsername, command.username());
        assertEquals(longPassword, command.password());
        assertEquals(longEmail, command.email());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithUnicodeCharacters() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "用户_测试",
                "密码_测试",
                "测试@example.com",
                1L,
                1,
                false
        );

        assertEquals("用户_测试", command.username());
        assertEquals("密码_测试", command.password());
        assertEquals("测试@example.com", command.email());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithWhitespace() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "  testuser  ",
                "  password123  ",
                "  test@example.com  ",
                1L,
                1,
                false
        );

        assertEquals("  testuser  ", command.username());
        assertEquals("  password123  ", command.password());
        assertEquals("  test@example.com  ", command.email());
        assertFalse(command.clearRole());
    }

    @Test
    void testOf_WithNumericStrings() {
        UpdateUserCommand command = UpdateUserCommand.of(
                1L,
                "12345",
                "12345",
                "12345@example.com",
                1L,
                1,
                false
        );

        assertEquals("12345", command.username());
        assertEquals("12345", command.password());
        assertEquals("12345@example.com", command.email());
        assertFalse(command.clearRole());
    }

    @Test
    void testClearRoleFlag_True() {
        UpdateUserCommand command = new UpdateUserCommand(
                1L,
                "testuser",
                "password123",
                "test@example.com",
                2L,
                1,
                true
        );

        assertTrue(command.clearRole());
    }

    @Test
    void testClearRoleFlag_False() {
        UpdateUserCommand command = new UpdateUserCommand(
                1L,
                "testuser",
                "password123",
                "test@example.com",
                2L,
                1,
                false
        );

        assertFalse(command.clearRole());
    }
}
