"""策略计划(趋势回调 / 滚仓)开始与结束 — 企业微信推送(三所共用)."""
from __future__ import annotations

from typing import Any, Optional

from lib.common.wechat_notify_lib import wechat_direction_label


def _send(cfg: dict[str, Any], content: str) -> None:
    fn = cfg.get("send_wechat")
    if callable(fn):
        try:
            fn(content)
            return
        except Exception:
            pass
    m = cfg.get("app_module")
    if m is not None:
        sw = getattr(m, "send_wechat_msg", None)
        if callable(sw):
            try:
                sw(content)
            except Exception:
                pass


def _account(cfg: dict[str, Any]) -> str:
    fn = cfg.get("wechat_account_label")
    if callable(fn):
        try:
            return str(fn()).strip() or _exchange(cfg)
        except Exception:
            pass
    return _exchange(cfg)


def _exchange(cfg: dict[str, Any]) -> str:
    return str(cfg.get("exchange_display") or "").strip() or "交易账户"


def _dir_text(cfg: dict[str, Any], direction: str) -> str:
    fn = cfg.get("wechat_direction_text")
    if callable(fn):
        try:
            return str(fn(direction))
        except Exception:
            pass
    return wechat_direction_label(direction)


def _fmt_price(cfg: dict[str, Any], symbol: str, price: Any) -> str:
    if price is None or price == "":
        return "—"
    fn = cfg.get("format_price") or cfg.get("price_fmt")
    if callable(fn):
        try:
            return str(fn(symbol, price))
        except Exception:
            pass
    m = cfg.get("app_module")
    pf = getattr(m, "format_price_for_symbol", None) if m else None
    if callable(pf):
        try:
            return str(pf(symbol, price))
        except Exception:
            pass
    try:
        return str(round(float(price), 8))
    except (TypeError, ValueError):
        return str(price)


def _fmt_pnl(pnl: Any) -> str:
    if pnl is None:
        return "—"
    try:
        v = float(pnl)
        return f"{'+' if v > 0 else ''}{round(v, 2)} U"
    except (TypeError, ValueError):
        return str(pnl)


def notify_trend_plan_started(
    cfg: dict[str, Any],
    *,
    plan_id: int,
    symbol: str,
    direction: str,
    leverage: int,
    stop_loss: float,
    take_profit: float,
    add_upper: float,
    risk_percent: float,
    dca_legs: int,
    first_order_amount: float,
    avg_entry: Optional[float] = None,
    snapshot_usdt: Optional[float] = None,
) -> None:
    sym = symbol or "—"
    lines = [
        f"# 🚀 {sym} 趋势回调计划已开始",
        f"**账户:{_account(cfg)}**",
        f"- 计划 ID:**{plan_id}**",
        f"- 方向:{_dir_text(cfg, direction)}｜杠杆 **{int(leverage or 1)}x**",
        f"- 止损:{_fmt_price(cfg, sym, stop_loss)}｜止盈:{_fmt_price(cfg, sym, take_profit)}",
        f"- 补仓区:{_fmt_price(cfg, sym, add_upper)}｜补仓档 **{int(dca_legs or 0)}** 档",
        f"- 风险:**{risk_percent}%**｜首仓张数:**{first_order_amount}**",
    ]
    if avg_entry is not None:
        lines.append(f"- 首仓成交价:{_fmt_price(cfg, sym, avg_entry)}")
    if snapshot_usdt is not None:
        try:
            lines.append(f"- 启动时合约可用:**{round(float(snapshot_usdt), 2)} U**")
        except (TypeError, ValueError):
            pass
    lines.append("- 说明:交易所已挂止损;止盈由程序监控;结束/保本将另行推送")
    _send(cfg, "\n".join(lines))


def notify_trend_plan_ended(
    cfg: dict[str, Any],
    *,
    plan_id: int,
    symbol: str,
    direction: str,
    end_type: str,
    result_label: Optional[str] = None,
    exit_price: Optional[float] = None,
    pnl_amount: Optional[float] = None,
    extra: Optional[str] = None,
) -> None:
    sym = symbol or "—"
    res = (result_label or end_type or "—").strip()
    lines = [
        f"# 🏁 {sym} 趋势回调计划已结束",
        f"**账户:{_account(cfg)}**",
        f"- 计划 ID:**{plan_id}**",
        f"- 方向:{_dir_text(cfg, direction)}",
        f"- 结束方式:**{end_type}**",
        f"- 结果:**{res}**",
    ]
    if exit_price is not None:
        lines.append(f"- 离场参考价:{_fmt_price(cfg, sym, exit_price)}")
    if pnl_amount is not None:
        lines.append(f"- 本单盈亏:**{_fmt_pnl(pnl_amount)}**")
    if extra:
        lines.append(f"- {extra}")
    _send(cfg, "\n".join(lines))


def notify_roll_group_started(
    cfg: dict[str, Any],
    *,
    group_id: int,
    symbol: str,
    direction: str,
    order_monitor_id: int,
    initial_take_profit: Optional[float] = None,
    initial_stop_loss: Optional[float] = None,
) -> None:
    sym = symbol or "—"
    lines = [
        f"# 🚀 {sym} 滚仓计划已开始",
        f"**账户:{_account(cfg)}**",
        f"- 滚仓组 ID:**{group_id}**｜绑定下单监控 **#{order_monitor_id}**",
        f"- 方向:{_dir_text(cfg, direction)}",
        f"- 首仓止盈(锁定):{_fmt_price(cfg, sym, initial_take_profit)}",
        f"- 当前止损:{_fmt_price(cfg, sym, initial_stop_loss)}",
        "- 说明:顺势加仓为人工触发;组结束(无持仓/监控结案)将另行推送",
    ]
    _send(cfg, "\n".join(lines))


def notify_roll_group_ended(
    cfg: dict[str, Any],
    *,
    group_id: int,
    symbol: str,
    direction: str,
    reason: str,
    leg_count: int = 0,
) -> None:
    sym = symbol or "—"
    lines = [
        f"# 🏁 {sym} 滚仓计划已结束",
        f"**账户:{_account(cfg)}**",
        f"- 滚仓组 ID:**{group_id}**",
        f"- 方向:{_dir_text(cfg, direction)}",
        f"- 结束原因:**{reason}**",
        f"- 已完成滚仓腿数:**{int(leg_count or 0)}**",
    ]
    _send(cfg, "\n".join(lines))
