"""
Tests pour pricewatch.app.stores.cdiscount.store avec fixtures HTML réels.

Teste le parsing de vraies pages HTML capturées depuis Cdiscount.com.
"""

import pytest
from pathlib import Path

from pricewatch.app.stores.cdiscount.store import CdiscountStore
from pricewatch.app.core.schema import DebugStatus, StockStatus


class TestCdiscountRealFixtures:
    """Tests avec fixtures HTML réels capturés depuis Cdiscount."""

    @pytest.fixture
    def store(self) -> CdiscountStore:
        """Fixture: CdiscountStore instance."""
        return CdiscountStore()

    @pytest.fixture
    def fixture_tuf608umrv004(self) -> str:
        """Fixture: HTML Cdiscount tuf608umrv004 (PC Portable Gamer ASUS)."""
        fixture_path = Path(__file__).parent.parent.parent / \
            "pricewatch/app/stores/cdiscount/fixtures/cdiscount_tuf608umrv004_pw.html"
        with open(fixture_path, "r", encoding="utf-8") as f:
            return f.read()

    @pytest.fixture
    def fixture_a128902(self) -> str:
        """Fixture: HTML Cdiscount a128902 (Canapé d'angle NIRVANA)."""
        fixture_path = Path(__file__).parent.parent.parent / \
            "pricewatch/app/stores/cdiscount/fixtures/cdiscount_a128902_pw.html"
        with open(fixture_path, "r", encoding="utf-8") as f:
            return f.read()

    def test_parse_tuf608umrv004_complete(self, store, fixture_tuf608umrv004):
        """Parse fixture tuf608umrv004 - doit extraire toutes les données essentielles."""
        url = "https://www.cdiscount.com/informatique/ordinateurs-pc-portables/pc-portable-gamer-asus-tuf-gaming-a16-sans-windo/f-10709-tuf608umrv004.html"
        snapshot = store.parse(fixture_tuf608umrv004, url)

        # Métadonnées
        assert snapshot.source == "cdiscount"
        assert snapshot.url == url
        assert snapshot.reference == "10709-tuf608umrv004"
        assert snapshot.fetched_at is not None

        # Titre (doit contenir "ASUS" ou "TUF")
        assert snapshot.title is not None
        assert len(snapshot.title) > 0
        assert "ASUS" in snapshot.title or "TUF" in snapshot.title

        # Prix
        assert snapshot.price is not None
        assert snapshot.price > 0
        assert snapshot.currency == "EUR"

        # Status
        assert snapshot.debug.status in [DebugStatus.SUCCESS, DebugStatus.PARTIAL]

    def test_parse_a128902_complete(self, store, fixture_a128902):
        """Parse fixture a128902 - doit extraire toutes les données essentielles."""
        url = "https://www.cdiscount.com/maison/canape-canapes/canape-d-angle-convertible-reversible-nirvana-4-5/f-11701-a128902.html"
        snapshot = store.parse(fixture_a128902, url)

        # Métadonnées
        assert snapshot.source == "cdiscount"
        assert snapshot.url == url
        assert snapshot.reference == "11701-a128902"

        # Titre
        assert snapshot.title is not None
        assert "Canapé" in snapshot.title or "NIRVANA" in snapshot.title.upper()

        # Prix
        assert snapshot.price is not None
        assert snapshot.price > 0
        assert snapshot.currency == "EUR"

        # Status
        assert snapshot.debug.status in [DebugStatus.SUCCESS, DebugStatus.PARTIAL]

    def test_parse_tuf608umrv004_images(self, store, fixture_tuf608umrv004):
        """Parse fixture tuf608umrv004 - doit extraire au moins une image."""
        url = "https://www.cdiscount.com/informatique/.../f-10709-tuf608umrv004.html"
        snapshot = store.parse(fixture_tuf608umrv004, url)

        # Doit avoir au moins une image
        assert len(snapshot.images) > 0
        # Les images doivent être des URLs valides
        for img_url in snapshot.images:
            assert img_url.startswith("http")
            assert "cdiscount.com" in img_url.lower() or "cdscdn.com" in img_url.lower()

    def test_parse_a128902_images(self, store, fixture_a128902):
        """Parse fixture a128902 - doit extraire au moins une image."""
        url = "https://www.cdiscount.com/maison/.../f-11701-a128902.html"
        snapshot = store.parse(fixture_a128902, url)

        # Doit avoir au moins une image
        assert len(snapshot.images) > 0
        # Les images doivent être des URLs valides
        for img_url in snapshot.images:
            assert img_url.startswith("http")

    def test_parse_tuf608umrv004_completeness(self, store, fixture_tuf608umrv004):
        """Parse fixture tuf608umrv004 - vérifier is_complete()."""
        url = "https://www.cdiscount.com/informatique/.../f-10709-tuf608umrv004.html"
        snapshot = store.parse(fixture_tuf608umrv004, url)

        # Si titre ET prix sont présents, is_complete() doit être True
        if snapshot.title and snapshot.price:
            assert snapshot.is_complete() is True
        else:
            assert snapshot.is_complete() is False

    def test_parse_a128902_completeness(self, store, fixture_a128902):
        """Parse fixture a128902 - vérifier is_complete()."""
        url = "https://www.cdiscount.com/maison/.../f-11701-a128902.html"
        snapshot = store.parse(fixture_a128902, url)

        # Si titre ET prix sont présents, is_complete() doit être True
        if snapshot.title and snapshot.price:
            assert snapshot.is_complete() is True
        else:
            assert snapshot.is_complete() is False

    def test_parse_tuf608umrv004_json_serialization(self, store, fixture_tuf608umrv004):
        """Parse fixture tuf608umrv004 - vérifier sérialisation JSON."""
        url = "https://www.cdiscount.com/informatique/.../f-10709-tuf608umrv004.html"
        snapshot = store.parse(fixture_tuf608umrv004, url)

        # Doit pouvoir sérialiser en JSON sans erreur
        json_str = snapshot.to_json()
        assert json_str is not None
        assert len(json_str) > 0
        assert 'cdiscount' in json_str
        assert 'tuf608umrv004' in json_str.lower()

    def test_parse_a128902_json_serialization(self, store, fixture_a128902):
        """Parse fixture a128902 - vérifier sérialisation JSON."""
        url = "https://www.cdiscount.com/maison/.../f-11701-a128902.html"
        snapshot = store.parse(fixture_a128902, url)

        # Doit pouvoir sérialiser en JSON sans erreur
        json_str = snapshot.to_json()
        assert json_str is not None
        assert len(json_str) > 0
        assert 'cdiscount' in json_str
        assert 'a128902' in json_str

    def test_parse_fixtures_preserve_sku(self, store, fixture_tuf608umrv004, fixture_a128902):
        """Parse fixtures - le SKU dans l'URL doit être préservé dans reference."""
        # Test tuf608umrv004
        url1 = "https://www.cdiscount.com/informatique/.../f-10709-tuf608umrv004.html"
        snapshot1 = store.parse(fixture_tuf608umrv004, url1)
        assert snapshot1.reference == "10709-tuf608umrv004"

        # Test a128902
        url2 = "https://www.cdiscount.com/maison/.../f-11701-a128902.html"
        snapshot2 = store.parse(fixture_a128902, url2)
        assert snapshot2.reference == "11701-a128902"

    def test_parse_tuf608umrv004_price_format(self, store, fixture_tuf608umrv004):
        """Parse fixture tuf608umrv004 - le prix doit être un float valide."""
        url = "https://www.cdiscount.com/informatique/.../f-10709-tuf608umrv004.html"
        snapshot = store.parse(fixture_tuf608umrv004, url)

        if snapshot.price:
            assert isinstance(snapshot.price, float)
            assert snapshot.price > 0
            # Le prix doit avoir maximum 2 décimales
            assert snapshot.price == round(snapshot.price, 2)

    def test_parse_a128902_price_format(self, store, fixture_a128902):
        """Parse fixture a128902 - le prix doit être un float valide."""
        url = "https://www.cdiscount.com/maison/.../f-11701-a128902.html"
        snapshot = store.parse(fixture_a128902, url)

        if snapshot.price:
            assert isinstance(snapshot.price, float)
            assert snapshot.price > 0
            # Le prix doit avoir maximum 2 décimales
            assert snapshot.price == round(snapshot.price, 2)

    def test_parse_different_categories(self, store, fixture_tuf608umrv004, fixture_a128902):
        """Parse fixtures de catégories différentes - les deux doivent fonctionner."""
        # PC Portable (informatique)
        url1 = "https://www.cdiscount.com/informatique/.../f-10709-tuf608umrv004.html"
        snapshot1 = store.parse(fixture_tuf608umrv004, url1)
        assert snapshot1.is_complete()

        # Canapé (maison)
        url2 = "https://www.cdiscount.com/maison/.../f-11701-a128902.html"
        snapshot2 = store.parse(fixture_a128902, url2)
        assert snapshot2.is_complete()

        # Les deux doivent être valides
        assert snapshot1.price != snapshot2.price  # Produits différents
        assert snapshot1.title != snapshot2.title  # Produits différents
