"""Tests for response models."""
import pytest

from botcoin.models import Entity, Listing, Memory, Purchase, SearchResult, Signal, Stats


class TestMemory:
    """Tests for Memory model."""

    def test_from_api_full_data(self):
        """Test parsing full API response."""
        data = {
            "id": "mem-123",
            "content": "Test content",
            "tags": ["tag1", "tag2"],
            "memory_type": "fact",
            "created_at": "2026-01-01T00:00:00Z",
        }
        memory = Memory.from_api(data)

        assert memory.id == "mem-123"
        assert memory.content == "Test content"
        assert memory.tags == ["tag1", "tag2"]
        assert memory.memory_type == "fact"

    def test_from_api_with_summary_fallback(self):
        """Test that summary is used if content is missing."""
        data = {"id": "mem-456", "summary": "Summary text", "tags": []}
        memory = Memory.from_api(data)

        assert memory.content == "Summary text"

    def test_from_api_handles_missing_fields(self):
        """Test graceful handling of missing fields."""
        memory = Memory.from_api({})

        assert memory.id == ""
        assert memory.content == ""
        assert memory.tags == []
        assert memory.memory_type == ""


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

    def test_from_api_with_relevance(self):
        """Test parsing with relevance score."""
        data = {
            "id": "sr-123",
            "content": "Result content",
            "relevance": 0.95,
            "tags": ["a"],
        }
        result = SearchResult.from_api(data)

        assert result.memory_id == "sr-123"
        assert result.relevance == 0.95

    def test_from_api_with_score_fallback(self):
        """Test that score is used if relevance is missing."""
        data = {"memory_id": "sr-456", "score": 0.8, "summary": "Summary"}
        result = SearchResult.from_api(data)

        assert result.memory_id == "sr-456"
        assert result.relevance == 0.8
        assert result.content == "Summary"


class TestListing:
    """Tests for Listing model."""

    def test_from_api_full_data(self):
        """Test parsing marketplace listing."""
        data = {
            "id": "sig-123",
            "title": "Knowledge Title",
            "description": "Description",
            "price": 5.0,
            "seller_name": "agent-xyz",
        }
        listing = Listing.from_api(data)

        assert listing.id == "sig-123"
        assert listing.title == "Knowledge Title"
        assert listing.price == 5.0
        assert listing.seller == "agent-xyz"

    def test_from_api_signal_id_fallback(self):
        """Test signal_id fallback for id."""
        data = {"signal_id": "sig-789", "title": "Title", "price": 3.0}
        listing = Listing.from_api(data)

        assert listing.id == "sig-789"

    def test_from_api_content_scrubbed_fallback(self):
        """Test content_scrubbed fallback for description."""
        data = {"id": "x", "content_scrubbed": "Scrubbed content"}
        listing = Listing.from_api(data)

        assert listing.description == "Scrubbed content"


class TestPurchase:
    """Tests for Purchase model."""

    def test_from_api_full_data(self):
        """Test parsing purchase response."""
        data = {
            "content_unlocked": "Full content here",
            "amount": 5.0,
            "transaction_id": "tx-123",
            "seller_share": 4.45,
            "evaluators_share": 0.25,
            "treasury_share": 0.25,
            "burn_amount": 0.05,
        }
        purchase = Purchase.from_api(data)

        assert purchase.content == "Full content here"
        assert purchase.price == 5.0
        assert purchase.transaction_id == "tx-123"
        assert purchase.covenant["seller_share"] == 4.45
        assert purchase.covenant["burn_amount"] == 0.05


class TestSignal:
    """Tests for Signal model."""

    def test_from_api_with_nested_signal(self):
        """Test parsing nested signal response."""
        data = {
            "signal": {
                "id": "sig-new",
                "title": "New Signal",
                "price": 10.0,
            }
        }
        signal = Signal.from_api(data)

        assert signal.id == "sig-new"
        assert signal.title == "New Signal"
        assert signal.price == 10.0
        assert "sig-new" in signal.url

    def test_from_api_flat_data(self):
        """Test parsing flat signal data."""
        data = {"signal_id": "sig-flat", "title": "Flat", "price": 2.0}
        signal = Signal.from_api(data)

        assert signal.id == "sig-flat"


class TestStats:
    """Tests for Stats model."""

    def test_from_api_full_data(self):
        """Test parsing dashboard stats."""
        data = {
            "total_agents": 68,
            "total_memories": 112,
            "total_transactions": 13,
            "total_volume_botc": 96.0,
        }
        stats = Stats.from_api(data)

        assert stats.agents == 68
        assert stats.memories == 112
        assert stats.transactions == 13
        assert stats.volume == 96.0

    def test_from_api_alternate_keys(self):
        """Test alternate key names."""
        data = {"agents": 50, "memories": 100, "transactions": 10, "volume": 50.0}
        stats = Stats.from_api(data)

        assert stats.agents == 50
        assert stats.volume == 50.0


class TestEntity:
    """Tests for Entity model."""

    def test_from_api_with_nested_entity(self):
        """Test parsing nested entity response."""
        data = {
            "entity": {
                "name": "Neo4j",
                "entity_type": "tool",
                "properties": {"category": "database"},
            }
        }
        entity = Entity.from_api(data)

        assert entity.name == "Neo4j"
        assert entity.entity_type == "tool"
        assert entity.properties["category"] == "database"

    def test_from_api_flat_data(self):
        """Test parsing flat entity data."""
        data = {"name": "BPC-157", "type": "compound", "properties": {}}
        entity = Entity.from_api(data)

        assert entity.name == "BPC-157"
        assert entity.entity_type == "compound"
