"""Unit tests for Pydantic models"""

import pytest
from dss.models import Project, Component, Theme, DesignToken, TokenCategory


@pytest.mark.unit
class TestDesignToken:
    """Test DesignToken model"""

    def test_create_color_token(self):
        """Test creating a color token"""
        token = DesignToken(
            name="primary",
            value="oklch(0.65 0.18 250)",
            type="color",
            category=TokenCategory.COLOR,
            description="Primary brand color"
        )
        assert token.name == "primary"
        assert token.category == TokenCategory.COLOR
        assert "oklch" in token.value

    def test_create_spacing_token(self):
        """Test creating a spacing token"""
        token = DesignToken(
            name="space-md",
            value="16px",
            type="dimension",
            category=TokenCategory.SPACING
        )
        assert token.name == "space-md"
        assert token.value == "16px"
        assert token.category == TokenCategory.SPACING


@pytest.mark.unit
class TestTheme:
    """Test Theme model"""

    def test_create_empty_theme(self):
        """Test creating an empty theme"""
        theme = Theme(name="Test Theme")
        assert theme.name == "Test Theme"
        assert theme.version == "1.0.0"
        assert len(theme.tokens) == 0

    def test_create_theme_with_tokens(self):
        """Test creating a theme with tokens"""
        tokens = {
            "primary": DesignToken(
                name="primary",
                value="oklch(0.65 0.18 250)",
                type="color",
                category=TokenCategory.COLOR
            ),
            "space-md": DesignToken(
                name="space-md",
                value="16px",
                type="dimension",
                category=TokenCategory.SPACING
            )
        }
        theme = Theme(name="Test Theme", tokens=tokens)
        assert len(theme.tokens) == 2
        assert "primary" in theme.tokens

    def test_get_tokens_by_category(self):
        """Test filtering tokens by category"""
        tokens = {
            "primary": DesignToken(
                name="primary",
                value="oklch(0.65 0.18 250)",
                type="color",
                category=TokenCategory.COLOR
            ),
            "space-md": DesignToken(
                name="space-md",
                value="16px",
                type="dimension",
                category=TokenCategory.SPACING
            )
        }
        theme = Theme(name="Test Theme", tokens=tokens)

        color_tokens = theme.get_tokens_by_category(TokenCategory.COLOR)
        assert len(color_tokens) == 1
        assert "primary" in color_tokens

        spacing_tokens = theme.get_tokens_by_category(TokenCategory.SPACING)
        assert len(spacing_tokens) == 1
        assert "space-md" in spacing_tokens


@pytest.mark.unit
class TestComponent:
    """Test Component model"""

    def test_create_basic_component(self):
        """Test creating a basic component"""
        component = Component(
            name="Button",
            source="shadcn",
            description="Primary action button"
        )
        assert component.name == "Button"
        assert component.source == "shadcn"
        assert len(component.variants) == 0
        assert len(component.dependencies) == 0

    def test_create_component_with_variants(self):
        """Test creating a component with variants"""
        component = Component(
            name="Button",
            source="shadcn",
            variants=["default", "outline", "ghost"]
        )
        assert len(component.variants) == 3
        assert "outline" in component.variants


@pytest.mark.unit
class TestProject:
    """Test Project model"""

    def test_create_minimal_project(self):
        """Test creating a minimal project"""
        theme = Theme(name="Test Theme")
        project = Project(
            id="test-project",
            name="Test Project",
            theme=theme
        )
        assert project.id == "test-project"
        assert project.name == "Test Project"
        assert project.version == "1.0.0"
        assert len(project.components) == 0

    def test_create_project_with_components(self):
        """Test creating a project with components"""
        theme = Theme(name="Test Theme")
        components = [
            Component(name="Button", source="shadcn"),
            Component(name="Card", source="shadcn")
        ]
        project = Project(
            id="test-project",
            name="Test Project",
            theme=theme,
            components=components
        )
        assert len(project.components) == 2

    def test_get_component_by_name(self):
        """Test retrieving a component by name"""
        theme = Theme(name="Test Theme")
        components = [
            Component(name="Button", source="shadcn"),
            Component(name="Card", source="shadcn")
        ]
        project = Project(
            id="test-project",
            name="Test Project",
            theme=theme,
            components=components
        )

        button = project.get_component("Button")
        assert button is not None
        assert button.name == "Button"

        nonexistent = project.get_component("NonExistent")
        assert nonexistent is None

    def test_project_from_fixture(self, valid_project_data):
        """Test creating project from fixture data"""
        project = Project(**valid_project_data)
        assert project.id == "heroui-ds-test"
        assert project.name == "HeroUI Design System"
        assert len(project.components) == 2
        assert len(project.theme.tokens) == 6
