"""
Email notification system — SMTP-based alerts, trade reports, and reminders.

Supports:
  - Trade execution alerts (opened/closed/modified)
  - Risk alerts (circuit breaker, drawdown, consecutive losses)
  - Daily PnL summary
  - License expiry reminders

Configure via environment variables:
  SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM
  NOTIFY_EMAIL_TO (comma-separated recipients)
"""
from __future__ import annotations

import json
import os
import smtplib
import time
from datetime import datetime, timezone
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from pathlib import Path
from typing import Any

# SMTP config
SMTP_HOST = os.environ.get("SMTP_HOST", "smtp.gmail.com")
SMTP_PORT = int(os.environ.get("SMTP_PORT", "587"))
SMTP_USER = os.environ.get("SMTP_USER", "")
SMTP_PASS = os.environ.get("SMTP_PASS", "")
SMTP_FROM = os.environ.get("SMTP_FROM", SMTP_USER)

# Where to send
DEFAULT_RECIPIENTS = os.environ.get("NOTIFY_EMAIL_TO", "")

# Rate limiting: don't send more than N emails per MINUTE
RATE_LIMIT_PER_MINUTE = int(os.environ.get("NOTIFY_RATE_LIMIT", "10"))
_send_times: list[float] = []

# Queue for offline mode
QUEUE_FILE = Path(__file__).resolve().parent.parent.parent / "data" / "notify" / "email_queue.ndjson"


def _now() -> str:
    return datetime.now(timezone.utc).isoformat()


def _rate_check() -> bool:
    """Rate limit check. Returns True if allowed to send."""
    global _send_times
    now = time.time()
    _send_times = [t for t in _send_times if now - t < 60]
    if len(_send_times) >= RATE_LIMIT_PER_MINUTE:
        return False
    _send_times.append(now)
    return True


def _send_email(to: str, subject: str, body_html: str) -> bool:
    """Send an email via SMTP. Returns True on success."""
    if not SMTP_USER or not SMTP_PASS:
        # Queue for later
        _queue(to, subject, body_html)
        return False

    if not _rate_check():
        _queue(to, subject, body_html)
        return False

    try:
        msg = MIMEMultipart("alternative")
        msg["From"] = SMTP_FROM or SMTP_USER
        msg["To"] = to
        msg["Subject"] = f"[GoldAutoTrade] {subject}"
        msg.attach(MIMEText(body_html, "html", "utf-8"))

        with smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=15) as server:
            server.starttls()
            server.login(SMTP_USER, SMTP_PASS)
            server.send_message(msg)
        return True
    except Exception as e:
        print(f"[EMAIL] Failed to send to {to}: {e}")
        _queue(to, subject, body_html)
        return False


def _queue(to: str, subject: str, body_html: str) -> None:
    """Queue email for later delivery."""
    QUEUE_FILE.parent.mkdir(parents=True, exist_ok=True)
    with open(QUEUE_FILE, "a", encoding="utf-8") as f:
        f.write(json.dumps({
            "to": to, "subject": subject, "body": body_html, "queued_at": _now(),
        }, ensure_ascii=False) + "\n")


def send(to: str = "", subject: str = "", body: str = "") -> bool:
    """Send or queue a single email."""
    recipients = to or DEFAULT_RECIPIENTS
    if not recipients:
        return False
    return _send_email(recipients, subject, body)


# ─── Templated alerts ──────────────────────────────────────────────

def _style() -> str:
    return """
    <style>
      body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 600px; margin: 0 auto; color: #1a1a1a; }
      .header { background: linear-gradient(135deg, #d4a017, #b8860b); color: white; padding: 24px; border-radius: 8px 8px 0 0; }
      .header h1 { margin: 0; font-size: 20px; }
      .body { padding: 20px; background: #fafafa; border: 1px solid #e0e0e0; border-top: none; border-radius: 0 0 8px 8px; }
      .metric { display: inline-block; padding: 12px 16px; margin: 4px; background: white; border-radius: 6px; border: 1px solid #e0e0e0; text-align: center; min-width: 80px; }
      .metric .value { font-size: 24px; font-weight: 700; }
      .metric .label { font-size: 11px; color: #888; text-transform: uppercase; }
      .profit { color: #16a34a; }
      .loss { color: #dc2626; }
      .alert { background: #fef2f2; border-left: 4px solid #dc2626; padding: 12px; margin: 8px 0; border-radius: 4px; }
      .footer { text-align: center; font-size: 11px; color: #999; margin-top: 16px; }
    </style>
    """


def send_trade_alert(action: str, symbol: str, volume: float, price: float,
                     sl: float, tp: float, pnl: float = 0, signal_id: str = "") -> bool:
    """Send a trade execution alert."""
    pnl_class = "profit" if pnl >= 0 else "loss"
    pnl_sign = "+" if pnl >= 0 else ""
    body = f"""<!DOCTYPE html><html><head>{_style()}</head><body>
    <div class="header"><h1>Trade Alert: {action}</h1></div>
    <div class="body">
      <div class="metric"><div class="value">{symbol}</div><div class="label">Symbol</div></div>
      <div class="metric"><div class="value">{volume}</div><div class="label">Volume</div></div>
      <div class="metric"><div class="value">{price:.2f}</div><div class="label">Price</div></div>
      <div class="metric"><div class="value {pnl_class}">{pnl_sign}{pnl:.2f}</div><div class="label">P&L</div></div>
      <p style="margin-top:16px;color:#888;font-size:12px;">SL: {sl:.2f} | TP: {tp:.2f} | Signal: {signal_id}</p>
    </div>
    <div class="footer">Gold AutoTrade — {_now()[:19]}</div>
    </body></html>"""
    return send(subject=f"{action} {symbol} @ {price:.2f} {'+' if pnl>=0 else ''}{pnl:.2f}", body=body)


def send_risk_alert(alert_type: str, details: dict[str, Any]) -> bool:
    """Send a risk alert (circuit breaker, drawdown, etc.)."""
    items = "".join(
        f'<div class="alert"><strong>{k}</strong>: {v}</div>'
        for k, v in details.items()
    )
    body = f"""<!DOCTYPE html><html><head>{_style()}</head><body>
    <div class="header"><h1>RISK ALERT: {alert_type}</h1></div>
    <div class="body">{items}</div>
    <div class="footer">Gold AutoTrade Risk Monitor — {_now()[:19]}</div>
    </body></html>"""
    return send(subject=f"RISK: {alert_type}", body=body)


def send_daily_summary(date_str: str, stats: dict[str, Any]) -> bool:
    """Send daily P&L summary."""
    pnl = stats.get("net_pnl", 0)
    pnl_class = "profit" if pnl >= 0 else "loss"
    pnl_sign = "+" if pnl >= 0 else ""

    body = f"""<!DOCTYPE html><html><head>{_style()}</head><body>
    <div class="header"><h1>Daily Summary — {date_str}</h1></div>
    <div class="body">
      <div class="metric"><div class="value {pnl_class}">{pnl_sign}{pnl:.2f}</div><div class="label">Net P&L</div></div>
      <div class="metric"><div class="value">{stats.get('total_trades', 0)}</div><div class="label">Trades</div></div>
      <div class="metric"><div class="value">{stats.get('win_rate', 0):.0%}</div><div class="label">Win Rate</div></div>
      <div class="metric"><div class="value">{stats.get('drawdown_pct', 0):.1f}%</div><div class="label">Max DD</div></div>
    </div>
    <div class="footer">Gold AutoTrade — {_now()[:19]}</div>
    </body></html>"""
    return send(subject=f"Daily Summary {date_str} | P&L: {pnl_sign}{pnl:.2f}", body=body)


def send_license_expiry_reminder(email: str, days_left: int) -> bool:
    """Send license expiry reminder."""
    body = f"""<!DOCTYPE html><html><head>{_style()}</head><body>
    <div class="header"><h1>License Expiring Soon</h1></div>
    <div class="body">
      <p>Your Gold AutoTrade license will expire in <strong>{days_left} days</strong>.</p>
      <p>Renew now to ensure uninterrupted trading:</p>
      <p><a href="https://huipin199.com/renew" style="display:inline-block;padding:12px 24px;background:#d4a017;color:white;text-decoration:none;border-radius:6px;">Renew License</a></p>
    </div>
    <div class="footer">Gold AutoTrade Licensing — {_now()[:19]}</div>
    </body></html>"""
    return _send_email(email, f"License expires in {days_left} days", body)
