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

import cn.novalon.gym.manage.sys.primitive.Email;
import cn.novalon.gym.manage.sys.primitive.Password;
import cn.novalon.gym.manage.sys.primitive.Username;
import org.junit.jupiter.api.Test;

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

class CreateUserCommandTest {

    @Test
    void testConstructor() {
        Username username = Username.of("testuser");
        Password password = Password.of("Password123!");
        Email email = Email.of("test@example.com");
        
        CreateUserCommand command = new CreateUserCommand(
                username,
                password,
                email,
                "nickname",
                "1234567890",
                1L,
                1
        );

        assertEquals(username, command.username());
        assertEquals(password, command.password());
        assertEquals(email, command.email());
        assertEquals("nickname", command.nickname());
        assertEquals("1234567890", command.phone());
        assertEquals(1L, command.roleId());
        assertEquals(1, command.status());
    }

    @Test
    void testOf() {
        CreateUserCommand command = CreateUserCommand.of(
                "testuser",
                "Password123!",
                "test@example.com",
                "nickname",
                "1234567890",
                1L,
                1
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertEquals("nickname", command.nickname());
        assertEquals("1234567890", command.phone());
        assertEquals(1L, command.roleId());
        assertEquals(1, command.status());
    }

    @Test
    void testOf_WithNullValues() {
        CreateUserCommand command = CreateUserCommand.of(
                "testuser",
                "Password123!",
                "test@example.com",
                null,
                null,
                null,
                null
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertNull(command.nickname());
        assertNull(command.phone());
        assertNull(command.roleId());
        assertNull(command.status());
    }

    @Test
    void testOf_WithEmptyStrings() {
        CreateUserCommand command = CreateUserCommand.of(
                "testuser",
                "Password123!",
                "test@example.com",
                "",
                "",
                null,
                null
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertEquals("", command.nickname());
        assertEquals("", command.phone());
        assertNull(command.roleId());
        assertNull(command.status());
    }

    @Test
    void testOf_WithBoundaryValues() {
        CreateUserCommand command = CreateUserCommand.of(
                "abc",
                "Abc123!@",
                "a@b.co",
                "n",
                "0",
                1L,
                1
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertEquals("n", command.nickname());
        assertEquals("0", command.phone());
        assertEquals(1L, command.roleId());
        assertEquals(1, command.status());
    }

    @Test
    void testOf_WithZeroValues() {
        CreateUserCommand command = CreateUserCommand.of(
                "testuser",
                "Password123!",
                "test@example.com",
                "nickname",
                "1234567890",
                0L,
                0
        );

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

    @Test
    void testOf_WithNegativeValues() {
        CreateUserCommand command = CreateUserCommand.of(
                "testuser",
                "Password123!",
                "test@example.com",
                "nickname",
                "1234567890",
                -1L,
                -1
        );

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

    @Test
    void testOf_WithSpecialCharacters() {
        CreateUserCommand command = CreateUserCommand.of(
                "test_user",
                "Password123!",
                "test@example.com",
                "nick@#$%",
                "123@#$%",
                1L,
                1
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertEquals("nick@#$%", command.nickname());
        assertEquals("123@#$%", command.phone());
    }

    @Test
    void testOf_WithLongStrings() {
        String longNickname = "a".repeat(1000);
        String longPhone = "1".repeat(100);
        
        CreateUserCommand command = CreateUserCommand.of(
                "testuser",
                "Password123!",
                "test@example.com",
                longNickname,
                longPhone,
                1L,
                1
        );

        assertEquals(longNickname, command.nickname());
        assertEquals(longPhone, command.phone());
    }

    @Test
    void testOf_WithUnicodeCharacters() {
        CreateUserCommand command = CreateUserCommand.of(
                "test_user",
                "Password123!",
                "test@example.com",
                "昵称_测试",
                "1234567890",
                1L,
                1
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertEquals("昵称_测试", command.nickname());
    }

    @Test
    void testOf_WithWhitespace() {
        CreateUserCommand command = CreateUserCommand.of(
                "testuser",
                "Password123!",
                "test@example.com",
                "  nickname  ",
                "  1234567890  ",
                1L,
                1
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertEquals("  nickname  ", command.nickname());
        assertEquals("  1234567890  ", command.phone());
    }

    @Test
    void testOf_WithNumericStrings() {
        CreateUserCommand command = CreateUserCommand.of(
                "test123",
                "Password123!",
                "test@example.com",
                "12345",
                "12345",
                1L,
                1
        );

        assertNotNull(command.username());
        assertNotNull(command.password());
        assertNotNull(command.email());
        assertEquals("12345", command.nickname());
        assertEquals("12345", command.phone());
    }
}
