"""
Tests for Pydantic models.
"""

import pytest

from skillbroker_langchain import (
    Skill,
    SkillQuery,
    SkillResponse,
    SearchResult,
    SkillCapability,
    SkillPricing,
    SkillStats,
    SkillQuality,
)


class TestSkillCapability:
    """Tests for SkillCapability model."""

    def test_create(self):
        """Test creating a capability."""
        cap = SkillCapability(
            name="Tax Filing",
            description="Help with tax returns",
            keywords=["tax", "filing", "returns"]
        )
        assert cap.name == "Tax Filing"
        assert len(cap.keywords) == 3

    def test_default_keywords(self):
        """Test keywords defaults to empty list."""
        cap = SkillCapability(name="Test", description="Test")
        assert cap.keywords == []


class TestSkillPricing:
    """Tests for SkillPricing model."""

    def test_default_free(self):
        """Test pricing defaults to free."""
        pricing = SkillPricing()
        assert pricing.model == "free"

    def test_paid_pricing(self):
        """Test paid pricing model."""
        pricing = SkillPricing(
            model="paid",
            price_per_query=0.01,
            currency="USD"
        )
        assert pricing.model == "paid"
        assert pricing.price_per_query == 0.01


class TestSkillStats:
    """Tests for SkillStats model."""

    def test_defaults(self):
        """Test stats default to zero."""
        stats = SkillStats()
        assert stats.total_queries == 0
        assert stats.average_rating == 0.0

    def test_with_values(self):
        """Test stats with values."""
        stats = SkillStats(total_queries=100, average_rating=4.5)
        assert stats.total_queries == 100


class TestSkillQuality:
    """Tests for SkillQuality model."""

    def test_defaults(self):
        """Test quality defaults."""
        quality = SkillQuality()
        assert quality.quality_score == 0.0
        assert quality.tier == "unrated"

    def test_with_score(self):
        """Test quality with score."""
        quality = SkillQuality(
            quality_score=4.2,
            feedback_count=50,
            tier="gold"
        )
        assert quality.quality_score == 4.2
        assert quality.tier == "gold"


class TestSkill:
    """Tests for Skill model."""

    def test_create_minimal(self):
        """Test creating skill with minimal fields."""
        skill = Skill(
            id="test-skill",
            name="Test Skill",
            description="A test skill",
            author="test@example.com",
            category="Test"
        )
        assert skill.id == "test-skill"
        assert skill.version == "1.0.0"  # default

    def test_create_full(self):
        """Test creating skill with all fields."""
        skill = Skill(
            id="full-skill",
            name="Full Skill",
            description="Complete skill",
            version="2.0.0",
            author="expert@example.com",
            category="Finance",
            tags=["tax", "finance"],
            capabilities=[
                SkillCapability(name="Tax", description="Tax help")
            ],
            pricing=SkillPricing(model="paid", price_per_query=0.05),
            stats=SkillStats(total_queries=1000),
            quality=SkillQuality(quality_score=4.8, tier="platinum")
        )
        assert skill.version == "2.0.0"
        assert len(skill.tags) == 2
        assert len(skill.capabilities) == 1
        assert skill.quality.tier == "platinum"

    def test_extra_fields_allowed(self):
        """Test that extra fields are allowed."""
        skill = Skill(
            id="test",
            name="Test",
            description="Test",
            author="test@example.com",
            category="Test",
            custom_field="custom_value"
        )
        assert skill.custom_field == "custom_value"


class TestSkillQuery:
    """Tests for SkillQuery model."""

    def test_create_simple(self):
        """Test simple query."""
        query = SkillQuery(query="How do I file taxes?")
        assert query.query == "How do I file taxes?"
        assert query.context is None

    def test_create_with_context(self):
        """Test query with context."""
        query = SkillQuery(
            query="How do I file taxes?",
            context={"user_type": "freelancer", "state": "CA"},
            max_tokens=500
        )
        assert query.context["user_type"] == "freelancer"
        assert query.max_tokens == 500


class TestSkillResponse:
    """Tests for SkillResponse model."""

    def test_create_success(self):
        """Test successful response."""
        response = SkillResponse(
            success=True,
            response="Here is your answer...",
            skill_id="tax-advisor",
            skill_name="Tax Advisor",
            tokens_used=150,
            cost=0.001
        )
        assert response.success is True
        assert response.tokens_used == 150

    def test_create_minimal(self):
        """Test response with minimal fields."""
        response = SkillResponse(
            success=False,
            response="Error occurred",
            skill_id="test",
            skill_name="Test"
        )
        assert response.success is False
        assert response.tokens_used is None


class TestSearchResult:
    """Tests for SearchResult model."""

    def test_empty_results(self):
        """Test empty search results."""
        result = SearchResult(skills=[], total_count=0)
        assert len(result.skills) == 0
        assert result.query is None

    def test_with_skills(self):
        """Test search results with skills."""
        skills = [
            Skill(
                id=f"skill-{i}",
                name=f"Skill {i}",
                description=f"Description {i}",
                author="test@example.com",
                category="Test"
            )
            for i in range(3)
        ]
        result = SearchResult(
            skills=skills,
            total_count=3,
            query="test",
            category="Test"
        )
        assert len(result.skills) == 3
        assert result.query == "test"
        assert result.category == "Test"
