"""
Tests filtres avances et exports API.
"""

from datetime import datetime, timedelta
import json

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from pricewatch.app.api.main import (
    export_logs,
    export_prices,
    export_products,
    list_logs,
    list_prices,
    list_products,
)
from pricewatch.app.db.models import Base, PriceHistory, Product, ScrapingLog


def _make_session():
    engine = create_engine("sqlite:///:memory:")
    Base.metadata.create_all(engine)
    session = sessionmaker(bind=engine)()
    return engine, session


def test_list_products_filters_latest_price_and_stock():
    engine, session = _make_session()
    try:
        product_a = Product(
            source="amazon",
            reference="REF-A",
            url="https://example.com/a",
            title="A",
            category="Test",
            currency="EUR",
            first_seen_at=datetime(2026, 1, 14, 10, 0, 0),
            last_updated_at=datetime(2026, 1, 15, 9, 0, 0),
        )
        product_b = Product(
            source="amazon",
            reference="REF-B",
            url="https://example.com/b",
            title="B",
            category="Test",
            currency="EUR",
            first_seen_at=datetime(2026, 1, 14, 10, 0, 0),
            last_updated_at=datetime(2026, 1, 15, 9, 5, 0),
        )
        session.add_all([product_a, product_b])
        session.commit()

        history = [
            PriceHistory(
                product_id=product_a.id,
                price=80,
                shipping_cost=0,
                stock_status="out_of_stock",
                fetch_method="http",
                fetch_status="success",
                fetched_at=datetime(2026, 1, 15, 8, 0, 0),
            ),
            PriceHistory(
                product_id=product_a.id,
                price=100,
                shipping_cost=0,
                stock_status="in_stock",
                fetch_method="http",
                fetch_status="success",
                fetched_at=datetime(2026, 1, 15, 9, 0, 0),
            ),
            PriceHistory(
                product_id=product_b.id,
                price=200,
                shipping_cost=10,
                stock_status="in_stock",
                fetch_method="http",
                fetch_status="success",
                fetched_at=datetime(2026, 1, 15, 9, 5, 0),
            ),
        ]
        session.add_all(history)
        session.commit()

        filtered = list_products(price_min=150, session=session)
        assert len(filtered) == 1
        assert filtered[0].reference == "REF-B"

        filtered_stock = list_products(stock_status="in_stock", session=session)
        assert {item.reference for item in filtered_stock} == {"REF-A", "REF-B"}
    finally:
        session.close()
        engine.dispose()


def test_list_prices_filters():
    engine, session = _make_session()
    try:
        product = Product(
            source="amazon",
            reference="REF-1",
            url="https://example.com/1",
            title="Produit",
            category="Test",
            currency="EUR",
            first_seen_at=datetime(2026, 1, 14, 10, 0, 0),
            last_updated_at=datetime(2026, 1, 14, 11, 0, 0),
        )
        session.add(product)
        session.commit()

        history = [
            PriceHistory(
                product_id=product.id,
                price=50,
                shipping_cost=0,
                stock_status="in_stock",
                fetch_method="http",
                fetch_status="success",
                fetched_at=datetime(2026, 1, 14, 12, 0, 0),
            ),
            PriceHistory(
                product_id=product.id,
                price=120,
                shipping_cost=0,
                stock_status="in_stock",
                fetch_method="http",
                fetch_status="failed",
                fetched_at=datetime(2026, 1, 15, 12, 0, 0),
            ),
        ]
        session.add_all(history)
        session.commit()

        results = list_prices(
            product_id=product.id,
            price_min=100,
            fetch_status="failed",
            session=session,
        )
        assert len(results) == 1
        assert results[0].price == 120
    finally:
        session.close()
        engine.dispose()


def test_list_logs_filters():
    engine, session = _make_session()
    try:
        now = datetime(2026, 1, 15, 10, 0, 0)
        logs = [
            ScrapingLog(
                product_id=None,
                url="https://example.com/a",
                source="amazon",
                reference="REF-A",
                fetch_method="http",
                fetch_status="success",
                fetched_at=now,
            ),
            ScrapingLog(
                product_id=None,
                url="https://example.com/b",
                source="amazon",
                reference="REF-B",
                fetch_method="http",
                fetch_status="failed",
                fetched_at=now - timedelta(hours=2),
            ),
        ]
        session.add_all(logs)
        session.commit()

        filtered = list_logs(
            fetch_status="success",
            fetched_after=now - timedelta(hours=1),
            session=session,
        )
        assert len(filtered) == 1
        assert filtered[0].reference == "REF-A"
    finally:
        session.close()
        engine.dispose()


def test_exports_csv_and_json():
    engine, session = _make_session()
    try:
        product = Product(
            source="amazon",
            reference="REF-EXPORT",
            url="https://example.com/export",
            title="Export",
            category="Test",
            currency="EUR",
            first_seen_at=datetime(2026, 1, 14, 10, 0, 0),
            last_updated_at=datetime(2026, 1, 14, 11, 0, 0),
        )
        session.add(product)
        session.commit()

        session.add(
            PriceHistory(
                product_id=product.id,
                price=99,
                shipping_cost=0,
                stock_status="in_stock",
                fetch_method="http",
                fetch_status="success",
                fetched_at=datetime(2026, 1, 14, 12, 0, 0),
            )
        )
        session.add(
            ScrapingLog(
                product_id=product.id,
                url=product.url,
                source=product.source,
                reference=product.reference,
                fetch_method="http",
                fetch_status="success",
                fetched_at=datetime(2026, 1, 14, 12, 0, 0),
            )
        )
        session.commit()

        csv_response = export_products(format="csv", session=session)
        assert csv_response.media_type == "text/csv"
        assert "products.csv" in csv_response.headers.get("Content-Disposition", "")
        assert "REF-EXPORT" in csv_response.body.decode("utf-8")

        json_response = export_logs(format="json", session=session)
        payload = json.loads(json_response.body.decode("utf-8"))
        assert payload[0]["reference"] == "REF-EXPORT"
    finally:
        session.close()
        engine.dispose()
