from __future__ import annotations

import argparse
from datetime import datetime, timezone
import json
from pathlib import Path
from typing import Any

from alerting import AlertPlan, build_risk_alert, build_trade_alert
from telegram_alerts import TelegramAlertConfig, send_telegram_alert


def _journal(payload: dict[str, Any]) -> Path:
    path = Path("runtime/reports") / f"telegram_alert_smoke_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}.json"
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(payload, indent=2, default=str, sort_keys=True), encoding="utf-8")
    return path


def _plans() -> list[tuple[str, AlertPlan]]:
    return [
        ("info", AlertPlan("Crypto Bot INFO [TEST] Telegram alert smoke: info alert; no secrets.")),
        ("trade_proposal", AlertPlan("Crypto Bot PROPOSAL [TEST] BTC long notional=15 risk<=0.50; no order sent by alert smoke.")),
        ("entry", build_trade_alert(event_type="entry", coin="BTC", side="buy", price=65000, size=0.00023, dry_run=False, paper_trading=True, reason="telegram_alert_smoke")),
        ("stop_placed", AlertPlan("Crypto Bot STOP PLACED [TEST] BTC reduceOnly stop confirmed; no secrets.")),
        ("exit", build_trade_alert(event_type="exit", coin="BTC", side="sell", price=65100, size=0.00023, dry_run=False, paper_trading=True, reason="telegram_alert_smoke", realized_pnl_usd=0.02)),
        ("critical_reconcile", AlertPlan("Crypto Bot CRITICAL RECONCILE [TEST] position_without_stop simulation; this is a smoke alert only.")),
        ("kill_switch", build_risk_alert(reason="kill_switch smoke test", dry_run=False, paper_trading=True)),
        ("daily_report_test", AlertPlan("Crypto Bot DAILY REPORT [TEST] Equity/PnL/Reconcile/WLD summary delivery smoke; no secrets.")),
    ]


def run_alert_smoke(*, dry_run: bool = False, only: tuple[str, ...] = ()) -> dict[str, Any]:
    config = TelegramAlertConfig.from_env()
    allowed = set(only)
    plans = [(name, plan) for name, plan in _plans() if not allowed or name in allowed]
    payload: dict[str, Any] = {
        "tool": "telegram_alert_smoke",
        "status": "ok",
        "dry_run": dry_run,
        "config": {"enabled": config.enabled, "chat_id_present": bool(config.chat_id), "thread_id_present": config.thread_id is not None, "bot_token_present": bool(config.bot_token)},
        "alerts": [],
        "secrets_sent": False,
    }
    for name, plan in plans:
        if dry_run:
            payload["alerts"].append({"name": name, "planned": True, "sent": False, "reason": "dry_run", "text_preview": plan.text})
            continue
        result = send_telegram_alert(plan, config)
        payload["alerts"].append({"name": name, "planned": True, "sent": result.sent, "reason": result.reason, "message_id": result.message_id})
    if not dry_run and not all(item["sent"] for item in payload["alerts"]):
        payload["status"] = "skipped" if not config.enabled else "partial"
    if not payload["alerts"]:
        payload["status"] = "skipped"
        payload["reason"] = "no_matching_alerts"
    return payload


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Telegram alert smoke for CryptoTradingBot. Sends no secrets.")
    parser.add_argument("--json", action="store_true")
    parser.add_argument("--dry-run", action="store_true")
    parser.add_argument("--only", action="append", default=[], help="Send only named alert(s), e.g. --only critical_reconcile. Repeatable.")
    args = parser.parse_args(argv)
    payload = run_alert_smoke(dry_run=args.dry_run, only=tuple(args.only))
    path = _journal(payload)
    payload["journal"] = str(path)
    print(json.dumps(payload, indent=2, default=str, sort_keys=True) if args.json else payload)
    return 0 if payload.get("status") == "ok" else 1


if __name__ == "__main__":
    raise SystemExit(main())
