"""Tests for point-in-time signal context snapshots."""

from __future__ import annotations

import json
from datetime import date, datetime, timezone

import pytest

from app.models.fundamental import FundamentalData
from app.models.score import CompositeScore, DimensionScore
from app.models.sentiment import SentimentScore
from app.models.signal_context_snapshot import SignalContextSnapshot
from app.models.ticker import Ticker
from app.models.trade_setup import TradeSetup
from app.services import rr_scanner_service as rr
from tests.conftest import _test_session_factory  # type: ignore


@pytest.fixture
async def session():
    async with _test_session_factory() as s:
        yield s


async def test_create_signal_context_snapshot_captures_latest_context(session):
    now = datetime(2026, 7, 2, 12, tzinfo=timezone.utc)
    ticker = Ticker(symbol="CTX")
    session.add(ticker)
    await session.flush()

    session.add_all([
        DimensionScore(
            ticker_id=ticker.id,
            dimension="technical",
            score=71.0,
            is_stale=False,
            computed_at=now,
        ),
        DimensionScore(
            ticker_id=ticker.id,
            dimension="momentum",
            score=82.0,
            is_stale=False,
            computed_at=now,
        ),
        CompositeScore(
            ticker_id=ticker.id,
            score=76.5,
            is_stale=False,
            weights_json='{"technical": 0.25}',
            computed_at=now,
        ),
        SentimentScore(
            ticker_id=ticker.id,
            classification="BULLISH",
            confidence=78,
            source="test",
            timestamp=now,
            reasoning="",
            citations_json="[]",
            recommendation="BUY",
        ),
        FundamentalData(
            ticker_id=ticker.id,
            pe_ratio=25.0,
            revenue_growth=0.18,
            earnings_surprise=0.05,
            market_cap=1_000_000_000.0,
            next_earnings_date=date(2026, 8, 1),
            fetched_at=now,
            unavailable_fields_json="{}",
        ),
    ])
    setup = TradeSetup(
        ticker_id=ticker.id,
        direction="long",
        entry_price=100.0,
        stop_loss=95.0,
        target=120.0,
        rr_ratio=4.0,
        composite_score=76.5,
        detected_at=now,
        confidence_score=64.0,
        momentum_percentile=88.0,
        recommended_action="LONG_HIGH",
        risk_level="Low",
    )
    session.add(setup)
    await session.flush()

    await rr._create_signal_context_snapshots(session, [setup])
    await session.commit()

    row = (await session.get(SignalContextSnapshot, 1))
    assert row is not None
    assert row.trade_setup_id == setup.id
    assert row.strategy_version == rr.STRATEGY_VERSION
    assert row.momentum_percentile == 88.0

    score = json.loads(row.score_context_json)
    sentiment = json.loads(row.sentiment_context_json)
    fundamental = json.loads(row.fundamental_context_json)

    assert score["composite_score"] == 76.5
    assert score["dimensions"]["technical"]["score"] == 71.0
    assert sentiment["classification"] == "BULLISH"
    assert sentiment["confidence"] == 78
    assert fundamental["pe_ratio"] == 25.0
    assert fundamental["next_earnings_date"] == "2026-08-01"
