"""日报结构化组装单元测试（_build_report_data，纯逻辑）。"""

from __future__ import annotations

import json
from datetime import date

from scheduler.reporter import _build_report_data


def _fake_event(title: str, importance: int, event_type: str = "其他",
                sentiment: str = "neutral", source_id: str = "cls",
                url: str = "https://x.com/1") -> dict:
    return {
        "title": title,
        "url": url,
        "source_id": source_id,
        "event": {
            "stock_codes": [],
            "company_names": [],
            "industries": [],
            "sentiment": sentiment,
            "importance": importance,
            "event_type": event_type,
            "summary": f"{title}的摘要",
        },
    }


class TestBuildReportData:
    def test_sections_and_ranks(self) -> None:
        news = {
            "total": 2, "hi_threshold": 4,
            "high": [_fake_event("新闻A", 5), _fake_event("新闻B", 4)],
            "sentiments": {"neutral": 2}, "importances": {5: 1, 4: 1},
            "event_types": {"其他": 2},
        }
        cninfo = {
            "total": 1, "hi_threshold": 2,
            "high": [_fake_event("公告C", 3, event_type="公告")],
            "by_day": {"07月10日": 1}, "announcement": 1, "research": 0, "irm": 0,
        }
        pipeline = {"raw_total": 100, "proc": 90}
        xwlb = {"items": [_fake_event("联播D", 4, event_type="新闻联播", source_id="xwlb")],
                "date": "07月10日"}

        r = _build_report_data(news, cninfo, pipeline, "AI摘要", "20260710", xwlb=xwlb)

        assert r.report_date == date(2026, 7, 10)
        assert r.report_type == "finance"
        assert r.file_name == ""
        assert r.ai_summary == "AI摘要"
        assert [(e.section, e.rank) for e in r.events] == [
            ("news", 1), ("news", 2), ("cninfo", 1), ("xwlb", 1),
        ]
        assert r.events[0].source == "cls"
        assert r.events[3].source == "xwlb"

    def test_stats_snapshot(self) -> None:
        news = {"total": 1, "hi_threshold": 4, "high": [], "sentiments": {},
                "importances": {}, "event_types": {}}
        cninfo = {"total": 0, "hi_threshold": 0, "high": [], "by_day": {},
                  "announcement": 0, "research": 0, "irm": 0}
        r = _build_report_data(news, cninfo, {"raw_total": 100}, "s", "20260710")
        # stats 可 JSON 序列化（入库时 json.dumps）
        json.dumps(r.stats, ensure_ascii=False)
        assert r.stats["pipeline"] == {"raw_total": 100}
        assert r.stats["news"]["total"] == 1
        assert "xwlb" not in r.stats

    def test_title_truncated(self) -> None:
        news = {"total": 1, "hi_threshold": 4,
                "high": [_fake_event("长" * 600, 4)], "sentiments": {},
                "importances": {}, "event_types": {}}
        cninfo = {"total": 0, "hi_threshold": 0, "high": [], "by_day": {},
                  "announcement": 0, "research": 0, "irm": 0}
        r = _build_report_data(news, cninfo, {}, "s", "20260710")
        assert len(r.events[0].title) == 512

    def test_empty_events(self) -> None:
        news = {"total": 0, "hi_threshold": 0, "high": [], "sentiments": {},
                "importances": {}, "event_types": {}}
        cninfo = {"total": 0, "hi_threshold": 0, "high": [], "by_day": {},
                  "announcement": 0, "research": 0, "irm": 0}
        r = _build_report_data(news, cninfo, {}, None, "20260710")
        assert r.events == []
        assert r.ai_summary is None
