"""Contract tests for Listings resource against the live API."""

from __future__ import annotations

import pytest

from cardog import Cardog
from cardog.types.listings import (
    Listing,
    ListingCountResponse,
    ListingFacetsResponse,
    ListingSearchResponse,
)


@pytest.mark.contract
class TestListingsContracts:
    """Validate Listings endpoint response shapes match our Pydantic models."""

    def test_search_returns_valid_response(self, client: Cardog):
        result = client.listings.search(limit=5)
        assert isinstance(result, ListingSearchResponse)
        assert isinstance(result.listings, list)
        assert result.pagination is not None
        assert result.pagination.page >= 1
        assert result.pagination.limit >= 1

    def test_search_with_make_filter(self, client: Cardog, test_make: str):
        result = client.listings.search(makes=[test_make], limit=5)
        assert isinstance(result, ListingSearchResponse)
        for listing in result.listings:
            assert listing.make.lower() == test_make.lower()

    def test_search_with_price_range(self, client: Cardog):
        result = client.listings.search(price_min=10000, price_max=20000, limit=5)
        assert isinstance(result, ListingSearchResponse)
        for listing in result.listings:
            assert 10000 <= listing.price <= 20000

    def test_search_with_year_range(self, client: Cardog):
        result = client.listings.search(year_min=2020, year_max=2023, limit=5)
        assert isinstance(result, ListingSearchResponse)
        for listing in result.listings:
            assert 2020 <= listing.year <= 2023

    def test_search_with_sort(self, client: Cardog):
        result = client.listings.search(
            sort_field="price", sort_direction="asc", limit=5
        )
        assert isinstance(result, ListingSearchResponse)
        if len(result.listings) > 1:
            prices = [l.price for l in result.listings]
            assert prices == sorted(prices)

    def test_search_pagination(self, client: Cardog):
        page1 = client.listings.search(page=1, limit=5)
        page2 = client.listings.search(page=2, limit=5)
        assert isinstance(page1, ListingSearchResponse)
        assert isinstance(page2, ListingSearchResponse)
        if page1.listings and page2.listings:
            # Pages should return different listings
            ids_1 = {l.id for l in page1.listings}
            ids_2 = {l.id for l in page2.listings}
            assert ids_1 != ids_2

    def test_listing_has_required_fields(self, client: Cardog):
        result = client.listings.search(limit=1)
        assert len(result.listings) > 0
        listing = result.listings[0]
        assert listing.id
        assert listing.vin
        assert listing.make
        assert listing.model
        assert listing.year > 1900
        assert listing.price > 0

    def test_listing_has_seller(self, client: Cardog):
        result = client.listings.search(limit=1)
        listing = result.listings[0]
        if listing.seller:
            assert listing.seller.id
            assert listing.seller.name

    def test_count_returns_valid_response(self, client: Cardog):
        result = client.listings.count(makes=["Toyota"])
        assert isinstance(result, ListingCountResponse)
        assert result.count >= 0

    def test_facets_returns_valid_response(self, client: Cardog):
        result = client.listings.facets()
        assert isinstance(result, ListingFacetsResponse)
        assert isinstance(result.makes, list)
        assert len(result.makes) > 0
        for facet in result.makes:
            assert facet.value
            assert facet.count >= 0
        assert isinstance(result.body_styles, list)
        assert isinstance(result.fuel_types, list)

    def test_get_by_id(self, client: Cardog):
        # First get a listing ID from search
        search = client.listings.search(limit=1)
        assert len(search.listings) > 0
        listing_id = search.listings[0].id

        result = client.listings.get_by_id(listing_id)
        assert isinstance(result, Listing)
        assert result.id == listing_id

    def test_search_with_multiple_filters(self, client: Cardog):
        result = client.listings.search(
            makes=["Honda"],
            year_min=2019,
            year_max=2023,
            price_max=40000,
            body_styles=["Sedan"],
            limit=5,
        )
        assert isinstance(result, ListingSearchResponse)
        for listing in result.listings:
            assert listing.make.lower() == "honda"
            assert 2019 <= listing.year <= 2023
