from __future__ import annotations

from datetime import datetime, timezone

from investly.domain import Action, Observation, Recommendation, Verdict


def evaluate(rec: Recommendation, *, close: float, high: float, low: float) -> Observation:
    return_pct = (close / rec.reference_price - 1) * 100
    if rec.action in {Action.BUY, Action.HOLD}:
        if rec.target is not None and high >= rec.target:
            verdict = Verdict.RIGHT
            reason = "target reached"
        elif rec.stop is not None and low <= rec.stop:
            verdict = Verdict.WRONG
            reason = "stop/invalidation reached"
        else:
            verdict = Verdict.OPEN
            reason = "position thesis remains unresolved at this close"
    elif rec.action == Action.SELL:
        if close <= rec.reference_price:
            verdict = Verdict.RIGHT
            reason = "exit avoided same-session downside versus recommendation reference"
        else:
            verdict = Verdict.OPEN
            reason = "exit requires more horizon before judging opportunity cost"
    elif rec.action in {Action.AVOID, Action.WATCH}:
        verdict = Verdict.RIGHT if close <= rec.reference_price else Verdict.OPEN
        reason = (
            "non-buy did not materially miss upside"
            if verdict == Verdict.RIGHT
            else "requires more horizon before judgment"
        )
    else:
        verdict = Verdict.OPEN
        reason = "recommendation lifecycle still open"
    return Observation(
        rec.recommendation_id,
        rec.symbol,
        datetime.now(timezone.utc),
        rec.reference_price,
        close,
        high,
        low,
        rec.target,
        rec.stop,
        verdict,
        round(return_pct, 3),
        reason,
    )
