import pandas as pd
import pytest

from psx_signal.data.comparison import compare_sources
from psx_signal.labels import add_forward_labels


def test_comparison_distinguishes_exact_small_and_material() -> None:
    reference = pd.DataFrame([
        {"symbol": "A", "date": "2026-08-18", "open": 10, "high": 11, "low": 9, "close": 10, "volume": 100},
        {"symbol": "B", "date": "2026-08-18", "open": 10, "high": 11, "low": 9, "close": 10, "volume": 100},
        {"symbol": "C", "date": "2026-08-18", "open": 10, "high": 11, "low": 9, "close": 10, "volume": 100},
    ])
    candidate = reference.astype({column: "float64" for column in ["open", "high", "low", "close", "volume"]})
    candidate.loc[1, "close"] = 10.02
    candidate.loc[2, "close"] = 12
    compared = compare_sources(reference, candidate)
    assert compared["comparison"].tolist() == [
        "EXACT_MATCH", "SMALL_DIFFERENCE", "MATERIAL_DIFFERENCE"
    ]


def test_labels_use_adjusted_returns_but_preserve_raw_execution_prices() -> None:
    frame = pd.DataFrame({
        "symbol": ["SYS"] * 3,
        "date": pd.to_datetime(["2026-08-16", "2026-08-17", "2026-08-18"]),
        "open": [100.0, 50.0, 52.0], "close": [102.0, 51.0, 53.0],
        "adjusted_open": [50.0, 50.0, 52.0], "adjusted_close": [51.0, 51.0, 53.0],
    })
    labelled = add_forward_labels(frame, horizons=(1,), buy_threshold=0.01, sell_threshold=-0.01)
    assert labelled.loc[0, "forward_return_1d"] == pytest.approx(0.02)
    assert labelled.loc[0, "entry_open_1d"] == 50.0
    assert labelled.loc[0, "exit_close_1d"] == 51.0
