import datetime as dt
import pandas as pd
import pytest
from app.screener.nodes.ai_news import AiNewsSentiment


class FakeCtx:
    def __init__(self, df=None):
        self.news_sentiment = df
        self.asof = dt.date(2026, 5, 13)


def test_compute_empty_context():
    out = AiNewsSentiment().compute(FakeCtx(None), {"min_news_count": 1})
    assert out.empty


def test_compute_with_data_percentile_ranks():
    df = pd.DataFrame([
        {"ticker": "A", "score_raw": -5.0, "news_count": 3},
        {"ticker": "B", "score_raw":  0.0, "news_count": 3},
        {"ticker": "C", "score_raw":  8.0, "news_count": 3},
    ])
    out = AiNewsSentiment().compute(FakeCtx(df), {"min_news_count": 1})
    assert len(out) == 3
    # percentile rank: A (lowest) < B < C (highest)
    assert out.loc["A"] < out.loc["B"] < out.loc["C"]
    # all within [0, 100]
    assert (out >= 0).all() and (out <= 100).all()


def test_compute_filters_by_min_news_count():
    df = pd.DataFrame([
        {"ticker": "A", "score_raw": -5.0, "news_count": 0},  # 필터됨
        {"ticker": "B", "score_raw":  0.0, "news_count": 2},
        {"ticker": "C", "score_raw":  8.0, "news_count": 5},
    ])
    out = AiNewsSentiment().compute(FakeCtx(df), {"min_news_count": 1})
    assert "A" not in out.index
    assert "B" in out.index
    assert "C" in out.index


def test_compute_all_filtered_returns_empty():
    df = pd.DataFrame([
        {"ticker": "A", "score_raw": 5.0, "news_count": 0},
    ])
    out = AiNewsSentiment().compute(FakeCtx(df), {"min_news_count": 1})
    assert out.empty


def test_metadata():
    n = AiNewsSentiment()
    assert n.name == "ai_news"
    assert "AI" in n.label or "뉴스" in n.label
    assert n.default_params == {"min_news_count": 1}
    assert "min_news_count" in n.param_schema["properties"]
