"""每日数据找人推送 — 路线图R2 (2026-08-30)

北极星③：主动推送扩大 —— 异常 + 机会两类。
- 异常类：待处理预警（kpi_alerts pending）
- 机会类：KPI向好 / 预算余量 / 预测上行（opportunity_detector）
复用企微通道 8800/send（公司群中继服务）。

用法: /root/cma-management/backend/venv/bin/python3 scripts/daily_push.py [--dry-run]
cron: 15 9 * * *  (alert_generator 9:00 之后)
"""
import sys
import os
import json
import logging
import argparse
from datetime import datetime

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

from app.database import get_session_local
from app.models import KPIDefinition, KPIAlert
from scripts.opportunity_detector import detect_all, flatten

logger = logging.getLogger("cma.daily_push")

RELAY_URL = "http://127.0.0.1:8800/send"
SOURCE = "管理会计OS"


def collect_exceptions(db, limit: int = 10) -> list:
    """异常类：待处理预警（red/yellow）"""
    out = []
    alerts = db.query(KPIAlert).filter(
        KPIAlert.status == "pending",
        KPIAlert.alert_level.in_(["red", "yellow"]),
    ).order_by(KPIAlert.created_at.desc()).limit(limit).all()
    for a in alerts:
        k = db.query(KPIDefinition).filter(KPIDefinition.id == a.kpi_id).first()
        kpi_name = k.kpi_name if k else f"KPI#{a.kpi_id}"
        icon = "🔴" if a.alert_level == "red" else "🟡"
        out.append({
            "type": "exception",
            "title": f"{icon} {kpi_name} 预警",
            "detail": f"({a.alert_level}) {a.alert_message}",
            "kpi_id": a.kpi_id,
            "kpi_name": kpi_name,
            "period": "",
        })
    return out


def build_message(exceptions: list, opportunities: list) -> str:
    """组装 markdown 推送内容"""
    now = datetime.now().strftime("%Y-%m-%d %H:%M")
    lines = [f"## 📊 管理会计OS · 每日经营播报", f"**{now}**", ""]

    lines.append("### ⚠️ 异常关注")
    if exceptions:
        for e in exceptions:
            lines.append(f"- {e['title']}")
            lines.append(f"  {e['detail']}")
    else:
        lines.append("- 今日无待处理预警 ✅")

    lines.append("")
    lines.append("### 🎯 机会发现")
    if opportunities:
        for o in opportunities:
            lines.append(f"- {o['title']}")
            lines.append(f"  {o['detail']}")
    else:
        lines.append("- 今日暂无显著机会")

    lines.append("")
    lines.append("---")
    lines.append("💡 数据找人：异常要处理，机会要把握。详情见 CMA 系统。")
    return "\n".join(lines)


def push_wecom(msg: str) -> dict:
    """通过8800中继推送企微"""
    import urllib.request
    import urllib.parse
    data = urllib.parse.urlencode({
        "msg": msg,
        "source": SOURCE,
        "msgtype": "markdown",
    }).encode("utf-8")
    req = urllib.request.Request(RELAY_URL, data=data,
                                 headers={"Content-Type": "application/x-www-form-urlencoded"})
    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            return result
    except Exception as e:
        return {"ok": False, "error": f"推送异常: {e}"}


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--dry-run", action="store_true", help="只打印不推送")
    parser.add_argument("--entity-id", type=int, default=1)
    args = parser.parse_args()

    db = get_session_local()()
    try:
        exceptions = collect_exceptions(db)
        opportunities = flatten(detect_all(db, args.entity_id))
        msg = build_message(exceptions, opportunities)

        if args.dry_run:
            print(msg)
            print(f"\n[DRY-RUN] 异常{len(exceptions)}条 / 机会{len(opportunities)}条")
            return

        result = push_wecom(msg)
        print(f"推送结果: {json.dumps(result, ensure_ascii=False)}")
        print(f"统计: 异常{len(exceptions)}条 / 机会{len(opportunities)}条")
    finally:
        db.close()


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    main()
