"""
Sprint 5 验证脚本 — 情绪因子快速验证。

用法:
    python cli/demo_sentiment.py
    python cli/demo_sentiment.py --ts_code 600519.SH
    python cli/demo_sentiment.py --ts_code 000001.SZ --no-qwen
"""

import sys, os, argparse
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import pandas as pd
from data.data_manager import DataManager
from factors.sentiment.news_source import NewsSource, align_news_to_trading_days
from factors.sentiment.qwen_client import QwenClient
from factors.sentiment.sentiment_engine import SentimentEngine


def main():
    p = argparse.ArgumentParser(description="Sprint 5 — 情绪因子快速验证")
    p.add_argument("--ts_code", default="000001.SZ", help="测试股票代码")
    p.add_argument("--no-qwen", action="store_true", help="跳过 Qwen 情绪分析")
    args = p.parse_args()

    print("=" * 60)
    print("Sprint 5 — Qwen 情绪因子验证")
    print("=" * 60)

    dm = DataManager(); dm.init_db()

    print("\n[1/5] 新闻数据源测试...")
    news_src = NewsSource(use_mcp=False)
    news_df = news_src.fetch(args.ts_code, max_news=10)
    if not news_df.empty:
        print("  获取 {} 条新闻".format(len(news_df)))
        for _, row in news_df.head(3).iterrows():
            print("  [{}] {}... (source={})".format(row["date"], str(row["title"])[:80], row["source"]))
    else:
        print("  (无新闻数据)")
    print("[OK]")

    print("\n[2/5] 日期对齐测试...")
    from data.data_manager import DataManager as DM
    price = dm.get_daily(args.ts_code) if dm.get_daily(args.ts_code) is not None else dm.get_daily("000001.SZ")
    if price is not None and not price.empty:
        price = price.set_index("trade_date").sort_index()
        daily_idx = pd.to_datetime(price.index, format="%Y%m%d", errors="coerce")
        test_news = pd.DataFrame({"date": ["20240601", "20240602", "20240603"],
                                  "title": ["周六新闻", "周日新闻", "周一新闻"],
                                  "content": [""] * 3, "source": ["test"] * 3, "url": [""] * 3})
        aligned = align_news_to_trading_days(test_news, daily_idx)
        for _, row in aligned.iterrows():
            print("  {}: {}".format(row["title"], row["date"]))
    print("[OK]")

    print("\n[3/5] Qwen 客户端状态...")
    client = QwenClient()
    has_api = bool(client.api_key) or bool(client.local_base_url)
    if has_api and not args.no_qwen:
        mode = "本地Ollama/{}".format(client.local_model) if client.local_base_url else "DashScope/{}".format(client.model)
        print("  模式: {}".format(mode))
    else:
        print("  模式: 未配置或跳过")
    print("[OK]")

    print("\n[4/5] SentimentEngine 全链路 (max_news=10)...")
    try:
        sent_engine = SentimentEngine(dm, qwen_client=client, news_source=news_src)
        sent_df = sent_engine.compute(args.ts_code, max_news=10)
        if sent_df is not None and not sent_df.empty:
            valid = sent_df.dropna(how="all")
            print("  情绪因子: {}".format(list(sent_df.columns)))
            print("  有效行: {}/{}".format(len(valid), len(sent_df)))
            if not valid.empty:
                print(valid.tail(5).round(4).to_string())
    except Exception as e:
        print("  [WARN] {}".format(e))
    print("[OK]")

    print("\n[5/5] 分析范围解析...")
    scope = sent_engine.get_scope_stocks()
    print("  成分股数量: {}".format(len(scope)))
    if scope:
        print("  示例: {}".format(", ".join(scope[:5])))
    print("[OK]")

    try:
        from reports.storage import save_report
        save_report("## 情绪因子验证 — {}\n\n- 新闻源: OK\n- 日期对齐: OK\n- Qwen: {}".format(
            args.ts_code, "就绪" if has_api else "未配置"),
            "情绪因子验证", subject_type="stock", subject_code=args.ts_code)
        print("  报告已存入 DB")
    except Exception:
        pass

    print("\n" + "=" * 60)
    print("Sprint 5 验证完成")
    print("=" * 60)


if __name__ == "__main__":
    main()
