"""Tests for Pydantic models."""

import pytest

from agentberlin.models import (
    AnalyticsResponse,
    BrandProfileResponse,
    ChannelBreakdown,
    ClusterKeywordResult,
    ClusterKeywordsResponse,
    ClusterListResponse,
    ClusterSummary,
    DataRange,
    KeywordListResponse,
    KeywordResult,
    KeywordSearchResponse,
    PageDetailResponse,
    PageSearchResponse,
    TrafficData,
    VisibilityData,
)


class TestAnalyticsModels:
    """Tests for analytics models."""

    def test_analytics_response_minimal(self):
        """Test AnalyticsResponse with minimal data."""
        data = {
            "domain": "example.com",
            "domain_authority": 50,
            "visibility": {
                "current_percentage": 75.5,
                "ranking_stability": 0.85,
                "share_of_voice": 12.3,
                "history": [],
            },
            "traffic": {
                "total_sessions": 10000,
                "llm_sessions": 500,
                "channel_breakdown": {
                    "direct": 2000,
                    "organic_search": 5000,
                    "referral": 1000,
                    "organic_social": 500,
                    "llm": 500,
                    "other": 1000,
                },
                "daily_trend": [],
            },
            "topics": [],
            "competitors": [],
            "data_range": {"start": "2024-01-01", "end": "2024-01-31"},
            "last_updated": "2024-01-31T12:00:00Z",
        }

        response = AnalyticsResponse.model_validate(data)
        assert response.domain == "example.com"
        assert response.domain_authority == 50
        assert response.visibility.current_percentage == 75.5

    def test_channel_breakdown_defaults(self):
        """Test ChannelBreakdown default values."""
        breakdown = ChannelBreakdown()
        assert breakdown.direct == 0
        assert breakdown.organic_search == 0
        assert breakdown.llm == 0


class TestSearchModels:
    """Tests for search models."""

    def test_page_search_response(self):
        """Test PageSearchResponse parsing."""
        data = {
            "similar_pages": [
                {
                    "target_page_url": "https://example.com/page1",
                    "similarity_score": 0.85,
                    "match_type": "page_to_page",
                },
                {
                    "target_page_url": "https://example.com/page2",
                    "similarity_score": 0.72,
                    "match_type": "chunk_to_page",
                    "chunk_text": "Sample chunk text",
                },
            ],
            "similar_chunks": [],
        }

        response = PageSearchResponse.model_validate(data)
        assert len(response.similar_pages) == 2
        assert response.similar_pages[0].target_page_url == "https://example.com/page1"
        assert response.similar_pages[0].similarity_score == 0.85

    def test_keyword_result_optional_fields(self):
        """Test KeywordResult with optional fields."""
        # With all fields
        full_data = {
            "keyword": "seo tips",
            "volume": 1000,
            "difficulty": 45,
            "cpc": 2.50,
            "intent": "informational",
        }
        result = KeywordResult.model_validate(full_data)
        assert result.keyword == "seo tips"
        assert result.volume == 1000

        # With minimal fields
        minimal_data = {"keyword": "seo tips"}
        result = KeywordResult.model_validate(minimal_data)
        assert result.keyword == "seo tips"
        assert result.volume is None

    def test_cluster_list_response(self):
        """Test ClusterListResponse parsing."""
        data = {
            "clusters": [
                {
                    "cluster_id": 0,
                    "size": 47,
                    "representative_keywords": ["seo tools", "best seo platform", "seo software"],
                },
                {
                    "cluster_id": 1,
                    "size": 32,
                    "representative_keywords": ["content marketing", "blog strategy"],
                },
            ],
            "noise_count": 234,
            "total_keywords": 5000,
            "cluster_count": 15,
        }

        response = ClusterListResponse.model_validate(data)
        assert len(response.clusters) == 2
        assert response.clusters[0].cluster_id == 0
        assert response.clusters[0].size == 47
        assert len(response.clusters[0].representative_keywords) == 3
        assert response.noise_count == 234
        assert response.total_keywords == 5000
        assert response.cluster_count == 15

    def test_cluster_keywords_response(self):
        """Test ClusterKeywordsResponse parsing."""
        data = {
            "keywords": [
                {"keyword": "seo tools", "cluster_id": 0, "volume": 1000, "difficulty": 45},
                {"keyword": "best seo platform", "cluster_id": 0, "volume": 800},
                {"keyword": "seo software", "cluster_id": 0},
            ],
            "total": 47,
            "cluster_id": 0,
            "limit": 50,
            "offset": 0,
        }

        response = ClusterKeywordsResponse.model_validate(data)
        assert len(response.keywords) == 3
        assert response.keywords[0].keyword == "seo tools"
        assert response.keywords[0].volume == 1000
        assert response.keywords[0].difficulty == 45
        assert response.keywords[1].difficulty is None  # Optional field
        assert response.keywords[2].volume is None  # Optional field
        assert response.total == 47
        assert response.cluster_id == 0
        assert response.limit == 50
        assert response.offset == 0

    def test_page_detail_response(self):
        """Test PageDetailResponse with links."""
        data = {
            "url": "https://example.com/page",
            "title": "Test Page",
            "h1": "Welcome",
            "content_length": 5000,
            "links": {
                "inlinks": [
                    {
                        "source_url": "https://example.com/other",
                        "target_url": "https://example.com/page",
                        "domain_type": "internal",
                    }
                ],
                "outlinks": [],
            },
        }

        response = PageDetailResponse.model_validate(data)
        assert response.url == "https://example.com/page"
        assert len(response.links.inlinks) == 1


class TestBrandModels:
    """Tests for brand profile models."""

    def test_brand_profile_response(self):
        """Test BrandProfileResponse parsing."""
        data = {
            "domain": "example.com",
            "name": "Example Inc",
            "context": "A technology company",
            "domain_authority": 60,
            "competitors": ["competitor1.com", "competitor2.com"],
            "industries": ["technology", "saas"],
            "business_models": ["b2b"],
            "company_size": "startup",
            "target_customer_segments": ["enterprise"],
            "geographies": ["us", "eu"],
            "personas": ["cto", "developer"],
            "sitemaps": [],
            "profile_urls": [],
        }

        response = BrandProfileResponse.model_validate(data)
        assert response.domain == "example.com"
        assert len(response.competitors) == 2
