"""Tests for FuturesService against mocked httpx responses."""

import httpx
import respx


def test_historical_bars(mock_api, client):
    mock_api.get("/futures/bars/historical").mock(
        return_value=httpx.Response(
            200,
            json={
                "symbols": "ZC*1",
                "exchange": "CME",
                "start_date": "2025-01-01",
                "end_date": "2025-01-03",
                "data_points": 2,
                "data": [
                    {"ts_event": "2025-01-01", "open": 450.0, "high": 455.0, "low": 448.0, "close": 453.0, "volume": 1000, "symbol": "ZC*1"},
                    {"ts_event": "2025-01-02", "open": 453.0, "high": 460.0, "low": 451.0, "close": 458.0, "volume": 1200, "symbol": "ZC*1"},
                ],
            },
        )
    )

    df = client.history("ZC*1", start="2025-01-01")
    assert len(df) == 2
    assert "date" in df.columns
    assert "symbol" in df.columns
    assert df.iloc[0]["symbol"] == "ZC*1"


def test_historical_bars_multi_symbol(mock_api, client):
    mock_api.get("/futures/bars/historical").mock(
        return_value=httpx.Response(
            200,
            json={
                "symbols": "ZC*1,ZS*1",
                "exchange": "CME",
                "start_date": "2025-01-01",
                "end_date": "2025-01-02",
                "data_points": 2,
                "data": [
                    {"ts_event": "2025-01-01", "open": 450.0, "high": 455.0, "low": 448.0, "close": 453.0, "volume": 1000, "symbol": "ZC*1"},
                    {"ts_event": "2025-01-01", "open": 1000.0, "high": 1010.0, "low": 995.0, "close": 1005.0, "volume": 800, "symbol": "ZS*1"},
                ],
            },
        )
    )

    df = client.history(["ZC*1", "ZS*1"], start="2025-01-01")
    assert len(df) == 2
    assert set(df["symbol"].unique()) == {"ZC*1", "ZS*1"}


def test_latest_quotes(mock_api, client):
    mock_api.get("/futures/quotes/latest").mock(
        return_value=httpx.Response(
            200,
            json={
                "symbols": ["ZC*1"],
                "exchange": "CME",
                "start_ts": "2025-01-01T00:00:00Z",
                "end_ts": "2025-01-02T00:00:00Z",
                "data_points": 1,
                "data": [
                    {"symbol": "ZC*1", "last_price": 455.0, "session_high": 460.0, "session_low": 450.0, "volume": 5000},
                ],
            },
        )
    )

    df = client.quote("ZC*1")
    assert len(df) == 1
    assert df.iloc[0]["last_price"] == 455.0


def test_search_symbols(mock_api, client):
    mock_api.get("/futures/symbols/search").mock(
        return_value=httpx.Response(
            200,
            json={
                "query": "corn",
                "results": [
                    {"product_id": "CBOT:ZC:FUT", "exchange": "CBOT", "root": "ZC", "name": "Corn", "continuous_symbol": "ZC*1", "score": 1.0},
                ],
                "total": 1,
            },
        )
    )

    df = client.search("corn")
    assert len(df) == 1
    assert df.iloc[0]["name"] == "Corn"


def test_option_eod(mock_api, client):
    mock_api.get("/futures/options/eod").mock(
        return_value=httpx.Response(
            200,
            json={
                "symbol": "ZCZ26|500C",
                "max_records": 30,
                "order": "desc",
                "volume": "contract",
                "data_points": 1,
                "data": [
                    {"symbol": "ZCZ26|500C", "date": "2025-06-01", "open": 10.0, "high": 12.0, "low": 9.5, "close": 11.0, "volume": 100, "open_interest": 500},
                ],
            },
        )
    )

    df = client.futures.option_eod("ZCZ26|500C")
    assert len(df) == 1


def test_empty_response(mock_api, client):
    mock_api.get("/futures/bars/historical").mock(
        return_value=httpx.Response(
            200,
            json={
                "symbols": "FAKE*1",
                "exchange": "CME",
                "start_date": "2025-01-01",
                "end_date": "2025-01-02",
                "data_points": 0,
                "data": [],
            },
        )
    )

    df = client.history("FAKE*1", start="2025-01-01")
    assert len(df) == 0


def test_401_raises_auth_error(mock_api, client):
    mock_api.get("/futures/bars/historical").mock(
        return_value=httpx.Response(401, json={"detail": "Invalid API key"})
    )

    import pytest
    from edge.exceptions import AuthenticationError

    with pytest.raises(AuthenticationError):
        client.history("ZC*1", start="2025-01-01")


def test_503_raises_service_unavailable(mock_api, client):
    mock_api.get("/futures/bars/historical").mock(
        return_value=httpx.Response(503, json={"detail": "Service unavailable"})
    )

    import pytest
    from edge.exceptions import ServiceUnavailableError

    with pytest.raises(ServiceUnavailableError):
        client.history("ZC*1", start="2025-01-01")
