import asyncio
import httpx
from loguru import logger


class DiscordNotifier:
    """Discord 웹훅으로 거래 알림을 전송하는 노티파이어."""

    def __init__(self, webhook_url: str, testnet: bool = False):
        self.webhook_url = webhook_url
        self._enabled = bool(webhook_url)
        self._testnet = testnet

    def _send(self, content: str) -> None:
        """알림 전송. 이벤트 루프 내에서는 백그라운드 스레드로 실행하여 블로킹 방지."""
        if self._testnet:
            content = f"[TESTNET] {content}"
        if not self._enabled:
            logger.debug("Discord 웹훅 URL 미설정 - 알림 건너뜀")
            return
        try:
            loop = asyncio.get_running_loop()
            fut = loop.run_in_executor(None, self._send_sync, content)
            fut.add_done_callback(
                lambda f: f.exception() and logger.warning(f"Discord 전송 실패: {f.exception()}")
            )
        except RuntimeError:
            self._send_sync(content)

    def _send_sync(self, content: str) -> None:
        try:
            resp = httpx.post(
                self.webhook_url,
                json={"content": content},
                timeout=10,
            )
            resp.raise_for_status()
        except Exception as e:
            logger.warning(f"Discord 알림 전송 실패: {e}")

    def notify_open(
        self,
        symbol: str,
        side: str,
        entry_price: float,
        quantity: float,
        leverage: int,
        stop_loss: float,
        take_profit: float,
        signal_data: dict = None,
    ) -> None:
        rsi = (signal_data or {}).get("rsi", 0)
        macd = (signal_data or {}).get("macd_hist", 0)
        atr = (signal_data or {}).get("atr", 0)
        msg = (
            f"**[{symbol}] {side} 진입**\n"
            f"진입가: `{entry_price:.4f}` | 수량: `{quantity}` | 레버리지: `{leverage}x`\n"
            f"SL: `{stop_loss:.4f}` | TP: `{take_profit:.4f}`\n"
            f"RSI: `{rsi:.2f}` | MACD Hist: `{macd:.6f}` | ATR: `{atr:.6f}`"
        )
        self._send(msg)

    def notify_close(
        self,
        symbol: str,
        side: str,
        close_reason: str,
        exit_price: float,
        estimated_pnl: float,
        net_pnl: float,
        diff: float,
    ) -> None:
        emoji_map = {"TP": "✅", "SL": "❌", "MANUAL": "🔶"}
        emoji = emoji_map.get(close_reason, "🔶")
        msg = (
            f"{emoji} **[{symbol}] {side} {close_reason} 청산**\n"
            f"청산가:               `{exit_price:.4f}`\n"
            f"예상 수익:            `{estimated_pnl:+.4f} USDT`\n"
            f"실제 순수익:          `{net_pnl:+.4f} USDT`\n"
            f"차이(슬리피지+수수료): `{diff:+.4f} USDT`"
        )
        self._send(msg)

    def notify_info(self, message: str) -> None:
        self._send(f"ℹ️ {message}")
