from __future__ import annotations

from html import escape

from investly.domain import Observation, Recommendation, SimAction

CSS = """
body{margin:0;background:#f2efe8;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif;color:#161616}
.wrap{max-width:760px;margin:auto;background:#fff;box-shadow:0 8px 30px rgba(0,0,0,.06)}
.hero{background:#0d0d0d;color:#fff;padding:38px 36px}.eyebrow{font-size:12px;letter-spacing:2px;text-transform:uppercase}
.gold{color:#c9a45e}.section{padding:26px 36px;border-bottom:1px solid #ece8df}
.card{border:1px solid #e6dfd2;border-radius:16px;padding:18px;margin:14px 0;background:#fff}
.muted{color:#727272}.pill{display:inline-block;border:1px solid #d4bd91;border-radius:99px;padding:5px 10px;margin:0 6px 6px 0;font-size:12px}
.num{font-size:23px;font-weight:750}.action{font-size:16px;font-weight:700}.risk{background:#faf7f0;border-radius:10px;padding:10px 12px}
.footer{padding:24px 36px;background:#faf9f6;color:#777;font-size:12px}.method{font-size:12px;color:#777}
@media(max-width:520px){.hero,.section,.footer{padding-left:20px;padding-right:20px}.num{font-size:20px}}
"""


def _money(value: float | None) -> str:
    return "—" if value is None else f"{value:,.2f}"


def _rec_card(rec: Recommendation) -> str:
    upside = ((rec.target / rec.reference_price - 1) * 100) if rec.target else None
    reasons = escape("; ".join(rec.reasons_for[:3]) or "No positive evidence recorded.")
    risks = escape("; ".join(rec.reasons_against[:3]) or "No major baseline contradiction.")
    potential = "Target pending" if upside is None else f"Potential {upside:+.1f}%"
    final_line = (
        f"{rec.action.value} | Next target {_money(rec.target)} | "
        f"Exit/invalidation {_money(rec.stop)} or thesis breaks | Horizon: {escape(rec.horizon)}"
    )
    return f'''<div class="card"><div><span class="pill">{escape(rec.strategy.value.title())}</span><span class="pill">{escape(rec.action.value)}</span></div><h3>{escape(rec.name)} <span class="muted">{escape(rec.symbol)}</span></h3><div class="num">{rec.reference_price:.2f} → {_money(rec.target)}</div><p class="gold">{potential} · Score {rec.score:.1f}/10 · Confidence {rec.confidence:.0%}</p><p>{reasons}</p><div class="risk"><b>What could go wrong</b><br><span class="muted">{risks}</span></div><p class="action">{final_line}</p><p class="method">Target: {escape(rec.target_method)}<br>Invalidation: {escape(rec.invalidation_method)}</p></div>'''


def preopen_email(
    market: str,
    recs: list[Recommendation],
    actions: list[SimAction],
    portfolios: dict[str, tuple[float, float]],
) -> tuple[str, str]:
    cards = "".join(_rec_card(rec) for rec in sorted(recs, key=lambda item: item.score, reverse=True))
    actions_html = "".join(
        f"<li><b>{escape(action.portfolio_id)}</b> · {escape(action.action)} {action.quantity} {escape(action.symbol)} — {escape(action.reason)}</li>"
        for action in actions
    )
    if not actions_html:
        actions_html = (
            "<li>Recommendations are frozen now. Paper fills are reconstructed at the "
            "verified session open after close data is available; no pre-open price is used as a fill.</li>"
        )
    portfolio_html = "".join(
        f"<div class='card'><b>{escape(name)}</b><br>Starting capital {_money(start)} · Cash {_money(cash)}</div>"
        for name, (start, cash) in portfolios.items()
    )
    html = f'''<!doctype html><html><head><meta name="viewport" content="width=device-width,initial-scale=1"><style>{CSS}</style></head><body><div class="wrap"><div class="hero"><div class="eyebrow gold">INVESTLY · PRE-MARKET</div><h1>{escape(market)} Executive Intelligence</h1><p>What the engine believes before the market opens. The record is immutable after issuance.</p></div><div class="section"><h2>Top opportunities</h2>{cards or '<p>No qualifying opportunities today.</p>'}</div><div class="section"><h2>Virtual portfolios</h2>{portfolio_html}<h3>Simulation execution policy</h3><ul>{actions_html}</ul></div><div class="footer">Internal research only · Each strategy uses an independent clone of the same user budget. Recommendations are engine-only; user inputs cannot alter ranking, confidence, target, stop or action.</div></div></body></html>'''
    text_lines = [f"INVESTLY {market} PRE-MARKET"]
    for rec in recs:
        text_lines.append(
            f"{rec.symbol} {rec.strategy.value} {rec.action.value} target {_money(rec.target)} "
            f"invalidation {_money(rec.stop)} | {rec.target_method}"
        )
    text_lines.append("Paper fills use verified session open after close data is available.")
    return html, "\n".join(text_lines)


def postclose_email(
    market: str,
    recs: list[Recommendation],
    observations: list[Observation],
) -> tuple[str, str]:
    by_id = {observation.recommendation_id: observation for observation in observations}
    cards: list[str] = []
    for rec in recs:
        observation = by_id.get(rec.recommendation_id)
        if not observation:
            continue
        rules = escape(", ".join(f"{citation.rule_id} v{citation.version}" for citation in rec.rules))
        cards.append(
            f'''<div class="card"><div class="eyebrow gold">{escape(rec.strategy.value)} · {escape(observation.verdict.value)}</div><h3>{escape(rec.name)} <span class="muted">{escape(rec.symbol)}</span></h3><div class="num">{observation.return_pct:+.2f}%</div><p>{escape(observation.reason)}</p><p class="muted">Morning action {rec.action.value}; target {_money(rec.target)}; invalidation {_money(rec.stop)}; rules {rules}</p><p class="method">Morning target method: {escape(rec.target_method)}</p></div>'''
        )
    html = f'''<!doctype html><html><head><meta name="viewport" content="width=device-width,initial-scale=1"><style>{CSS}</style></head><body><div class="wrap"><div class="hero"><div class="eyebrow gold">INVESTLY · ACCOUNTABILITY</div><h1>{escape(market)} After the Close</h1><p>What was right, wrong, still open — and why.</p></div><div class="section">{''.join(cards) or '<p>No completed observations.</p>'}</div><div class="footer">The morning record is immutable. This report evaluates it without hindsight edits.</div></div></body></html>'''
    text = f"INVESTLY {market} POST-CLOSE\n" + "\n".join(
        f"{observation.symbol} {observation.verdict.value} {observation.return_pct:+.2f}%: {observation.reason}"
        for observation in observations
    )
    return html, text
