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

import cn.novalon.manage.common.exception.ValidationException;
import cn.novalon.manage.common.util.StatusConstants;
import org.junit.jupiter.api.Test;

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

class CreateRoleCommandTest {

    @Test
    void testConstructor() {
        CreateRoleCommand command = new CreateRoleCommand(
                "Admin",
                "admin",
                1,
                1
        );

        assertEquals("Admin", command.roleName());
        assertEquals("admin", command.roleKey());
        assertEquals(1, command.roleSort());
        assertEquals(1, command.status());
    }

    @Test
    void testOf_WithValidStatus() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "Admin",
                "admin",
                1,
                StatusConstants.ENABLED
        );

        assertEquals("Admin", command.roleName());
        assertEquals("admin", command.roleKey());
        assertEquals(1, command.roleSort());
        assertEquals(StatusConstants.ENABLED, command.status());
    }

    @Test
    void testOf_WithDisabledStatus() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "Admin",
                "admin",
                1,
                StatusConstants.DISABLED
        );

        assertEquals("Admin", command.roleName());
        assertEquals("admin", command.roleKey());
        assertEquals(1, command.roleSort());
        assertEquals(StatusConstants.DISABLED, command.status());
    }

    @Test
    void testOf_WithNullStatus() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "Admin",
                "admin",
                1,
                null
        );

        assertEquals("Admin", command.roleName());
        assertEquals("admin", command.roleKey());
        assertEquals(1, command.roleSort());
        assertNull(command.status());
    }

    @Test
    void testOf_WithInvalidStatus() {
        ValidationException exception = assertThrows(
                ValidationException.class,
                () -> CreateRoleCommand.of(
                        "Admin",
                        "admin",
                        1,
                        999
                )
        );

        assertEquals("Invalid status value. Status must be 0 (disabled) or 1 (enabled)", exception.getMessage());
    }

    @Test
    void testOf_WithInvalidStatus_Negative() {
        ValidationException exception = assertThrows(
                ValidationException.class,
                () -> CreateRoleCommand.of(
                        "Admin",
                        "admin",
                        1,
                        -1
                )
        );

        assertEquals("Invalid status value. Status must be 0 (disabled) or 1 (enabled)", exception.getMessage());
    }

    @Test
    void testOf_WithInvalidStatus_Two() {
        ValidationException exception = assertThrows(
                ValidationException.class,
                () -> CreateRoleCommand.of(
                        "Admin",
                        "admin",
                        1,
                        2
                )
        );

        assertEquals("Invalid status value. Status must be 0 (disabled) or 1 (enabled)", exception.getMessage());
    }

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

        assertNull(command.roleName());
        assertNull(command.roleKey());
        assertNull(command.roleSort());
        assertNull(command.status());
    }

    @Test
    void testOf_WithEmptyStrings() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "",
                "",
                null,
                null
        );

        assertEquals("", command.roleName());
        assertEquals("", command.roleKey());
        assertNull(command.roleSort());
        assertNull(command.status());
    }

    @Test
    void testOf_WithBoundaryValues() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "a",
                "a",
                Integer.MAX_VALUE,
                StatusConstants.ENABLED
        );

        assertEquals("a", command.roleName());
        assertEquals("a", command.roleKey());
        assertEquals(Integer.MAX_VALUE, command.roleSort());
        assertEquals(StatusConstants.ENABLED, command.status());
    }

    @Test
    void testOf_WithZeroValues() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "Admin",
                "admin",
                0,
                StatusConstants.ENABLED
        );

        assertEquals(0, command.roleSort());
    }

    @Test
    void testOf_WithNegativeSort() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "Admin",
                "admin",
                -1,
                StatusConstants.ENABLED
        );

        assertEquals(-1, command.roleSort());
    }

    @Test
    void testOf_WithSpecialCharacters() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "Admin@#$%",
                "admin@#$%",
                1,
                StatusConstants.ENABLED
        );

        assertEquals("Admin@#$%", command.roleName());
        assertEquals("admin@#$%", command.roleKey());
    }

    @Test
    void testOf_WithLongStrings() {
        String longRoleName = "a".repeat(1000);
        String longRoleKey = "b".repeat(1000);
        
        CreateRoleCommand command = CreateRoleCommand.of(
                longRoleName,
                longRoleKey,
                1,
                StatusConstants.ENABLED
        );

        assertEquals(longRoleName, command.roleName());
        assertEquals(longRoleKey, command.roleKey());
    }

    @Test
    void testOf_WithUnicodeCharacters() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "管理员_测试",
                "admin_测试",
                1,
                StatusConstants.ENABLED
        );

        assertEquals("管理员_测试", command.roleName());
        assertEquals("admin_测试", command.roleKey());
    }

    @Test
    void testOf_WithWhitespace() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "  Admin  ",
                "  admin  ",
                1,
                StatusConstants.ENABLED
        );

        assertEquals("  Admin  ", command.roleName());
        assertEquals("  admin  ", command.roleKey());
    }

    @Test
    void testOf_WithNumericStrings() {
        CreateRoleCommand command = CreateRoleCommand.of(
                "12345",
                "67890",
                1,
                StatusConstants.ENABLED
        );

        assertEquals("12345", command.roleName());
        assertEquals("67890", command.roleKey());
    }

    @Test
    void testValidateStatus_EdgeCase_MaxInt() {
        ValidationException exception = assertThrows(
                ValidationException.class,
                () -> CreateRoleCommand.of(
                        "Admin",
                        "admin",
                        1,
                        Integer.MAX_VALUE
                )
        );

        assertEquals("Invalid status value. Status must be 0 (disabled) or 1 (enabled)", exception.getMessage());
    }

    @Test
    void testValidateStatus_EdgeCase_MinInt() {
        ValidationException exception = assertThrows(
                ValidationException.class,
                () -> CreateRoleCommand.of(
                        "Admin",
                        "admin",
                        1,
                        Integer.MIN_VALUE
                )
        );

        assertEquals("Invalid status value. Status must be 0 (disabled) or 1 (enabled)", exception.getMessage());
    }
}
