"""Генератор письма с саммари встречи: plaintext + HTML.

HTML-версия — по мотивам макета `design/mockups/email-summary.html`
(упрощённая структура: шапка/участники/тело саммари/футер, цвета и типографика
светлой темы `design/DESIGN_SYSTEM.md`; почтовые клиенты игнорируют внешние
`<style>`, поэтому все стили — инлайн). Тело саммари приходит от LLM
(`conference_sessions.summary_data`) в фиксированном markdown-подобном
формате промпта `workers/summarizer/prompts/summary_reduce_ru.txt` (заголовки
`## ...`, пункты `- ...`) — при рендере разбирается построчно и оборачивается
в HTML-разметку; заголовок конференции, имена участников и сам текст саммари
экранируются `html.escape`.
Plaintext-альтернатива — обязательный минимум для клиентов без HTML.
"""

from __future__ import annotations

import html
from collections.abc import Sequence
from dataclasses import dataclass


@dataclass(frozen=True)
class SummaryEmailContext:
    """Данные для рендера письма — без привязки к ORM (проще тестировать)."""

    conference_title: str
    date_label: str
    """Дата встречи в `display_timezone`, формат `ДД.ММ.ГГГГ`."""
    time_label: str
    """Время встречи в `display_timezone`, формат `ЧЧ:ММ–ЧЧ:ММ`."""
    duration_minutes: int
    participant_names: Sequence[str]
    summary_text: str


def build_summary_email(context: SummaryEmailContext) -> tuple[str, str]:
    """Собрать (plaintext, html) тело письма с саммари встречи."""
    return _build_plaintext(context), _build_html(context)


def _build_plaintext(context: SummaryEmailContext) -> str:
    """Простой текстовый вариант — без экранирования (не HTML)."""
    participants = ", ".join(context.participant_names) or "участники не определены"
    lines = [
        f"Саммари встречи «{context.conference_title}»",
        f"{context.date_label}, {context.time_label} ({context.duration_minutes} мин)",
        "",
        f"Участники: {participants}",
        "",
        context.summary_text.strip(),
        "",
        "—",
        "Письмо сформировано автоматически по итогам конференции в VidConf.",
    ]
    return "\n".join(lines)


def _build_html(context: SummaryEmailContext) -> str:
    """HTML-вариант письма — все пользовательские подстановки экранированы."""
    title = html.escape(context.conference_title)
    date_label = html.escape(context.date_label)
    time_label = html.escape(context.time_label)
    participants = html.escape(", ".join(context.participant_names) or "не определены")
    body_html = _render_summary_body(context.summary_text)

    return f"""\
<!doctype html>
<html lang="ru">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body style="margin:0; padding:0; background-color:#F1F1F1; font-family:Helvetica, Arial, sans-serif;">
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:#F1F1F1;">
<tr><td align="center" style="padding: 32px 16px;">
  <table role="presentation" width="600" cellpadding="0" cellspacing="0" border="0" style="width:600px; max-width:600px; background-color:#FFFFFF; border-radius:24px; overflow:hidden; border:1px solid #E1E3E9;">
    <tr>
      <td style="padding: 32px 32px 24px 32px; background-color:#F7F7F8;">
        <p style="margin: 0 0 6px; font-family:Helvetica, Arial, sans-serif; font-size:12px; font-weight:bold; letter-spacing:.06em; text-transform:uppercase; color:#6976AC;">
          Саммари встречи
        </p>
        <h1 style="margin:0 0 12px; font-family:Helvetica, Arial, sans-serif; font-size:24px; line-height:1.25; font-weight:bold; color:#2E3454;">
          {title}
        </h1>
        <p style="margin:0; font-family:Helvetica, Arial, sans-serif; font-size:14px; color:#535F94;">
          {date_label}, {time_label} &middot; {context.duration_minutes} мин
        </p>
      </td>
    </tr>
    <tr>
      <td style="padding: 24px 32px 8px 32px;">
        <p style="margin:0 0 6px; font-family:Helvetica, Arial, sans-serif; font-size:12px; font-weight:bold; letter-spacing:.06em; text-transform:uppercase; color:#A6AECB;">
          Участники
        </p>
        <p style="margin:0; font-family:Helvetica, Arial, sans-serif; font-size:14px; color:#2E3454;">
          {participants}
        </p>
      </td>
    </tr>
    <tr><td style="padding: 16px 32px;"><hr style="border:none; border-top:1px solid #E1E3E9; margin:0;"></td></tr>
    <tr>
      <td style="padding: 8px 32px 24px 32px;">
        {body_html}
      </td>
    </tr>
    <tr>
      <td style="padding: 20px 32px 32px 32px; background-color:#F7F7F8; border-top:1px solid #E1E3E9;">
        <p style="margin:0; font-family:Helvetica, Arial, sans-serif; font-size:12px; line-height:1.6; color:#A6AECB;">
          Письмо сформировано автоматически по итогам конференции в VidConf (self-hosted).
        </p>
      </td>
    </tr>
  </table>
</td></tr>
</table>
</body>
</html>
"""


def _render_summary_body(summary_text: str) -> str:
    """Разобрать markdown-подобный текст саммари (`## заголовок`, `- пункт`) в HTML.

    Формат фиксирован промптом суммаризации; при
    отклонении LLM от формата непонятые строки рендерятся как обычные
    абзацы — разбор не должен падать на неожиданном вводе. Всё содержимое
    экранируется `html.escape` (текст саммари — от LLM, потенциальная
    инъекция в HTML-письмо).
    """
    parts: list[str] = []
    in_list = False
    for raw_line in summary_text.strip("\n").splitlines():
        line = raw_line.strip()
        if not line:
            continue
        if line.startswith("## "):
            if in_list:
                parts.append("</ul>")
                in_list = False
            heading = html.escape(line[3:].strip())
            parts.append(
                '<p style="margin:16px 0 8px; font-family:Helvetica, Arial, sans-serif; '
                'font-size:15px; font-weight:bold; color:#2E3454;">' + heading + "</p>"
            )
        elif line.startswith("- "):
            if not in_list:
                parts.append('<ul style="margin:0 0 8px; padding-left:20px;">')
                in_list = True
            item = html.escape(line[2:].strip())
            parts.append(
                '<li style="font-family:Helvetica, Arial, sans-serif; font-size:14px; '
                'line-height:1.6; color:#2E3454; padding:2px 0;">' + item + "</li>"
            )
        else:
            if in_list:
                parts.append("</ul>")
                in_list = False
            parts.append(
                '<p style="margin:0 0 8px; font-family:Helvetica, Arial, sans-serif; '
                'font-size:14px; line-height:1.6; color:#2E3454;">' + html.escape(line) + "</p>"
            )
    if in_list:
        parts.append("</ul>")
    return "\n        ".join(parts)
