"""complyform-newsletter-draft — bi-weekly newsletter Markdown draft assembly.

Trigger: Bi-weekly Cloud Scheduler (1st + 15th of month).

Reads curated news items from ``newsletter_content/{date}`` documents,
groups by category, assembles Markdown draft, writes to
``newsletter_drafts/{YYYY-MM-DD}``, and sends preview to founder email.

Contract: skips if no content in last 14 days. Always returns 200.
"""

from __future__ import annotations

import logging
from datetime import UTC, datetime, timedelta
from typing import Any

from backend.billing.email_sender import send_template_email
from backend.ops._shared import cloud_function_wrapper, log_action
from backend.shared.firestore import get_db

_log = logging.getLogger(__name__)

_FOUNDER_EMAIL = "alerts@complyform.dev"

_CATEGORY_HEADINGS: dict[str, str] = {
    "regulation_updates": "Regulation Updates",
    "tool_releases": "Tool Releases",
    "breach_news": "Industry News",
    "best_practices": "Best Practices",
}

_CATEGORY_ORDER = (
    "regulation_updates",
    "tool_releases",
    "breach_news",
    "best_practices",
)


def _assemble_markdown(items_by_category: dict[str, list[dict[str, Any]]]) -> str:
    """Build newsletter Markdown from categorized items."""
    sections: list[str] = []

    for category in _CATEGORY_ORDER:
        items = items_by_category.get(category, [])
        if not items:
            continue
        heading = _CATEGORY_HEADINGS.get(category, category.replace("_", " ").title())
        lines = [f"## {heading}", ""]
        for item in items:
            title = item.get("title", "Untitled")
            url = item.get("url", "")
            summary = item.get("summary", "")
            if url:
                lines.append(f"- [{title}]({url}) — {summary}")
            else:
                lines.append(f"- **{title}** — {summary}")
        lines.append("")
        sections.append("\n".join(lines))

    footer = (
        "---\n\n"
        "*This newsletter is a draft. Review before publishing via Buttondown.*\n"
    )
    return "\n".join(sections) + footer


@cloud_function_wrapper("complyform-newsletter-draft")
async def newsletter_draft(request: Any) -> dict[str, Any]:
    """Assemble curated compliance news into Markdown draft.

    Reads recent ``newsletter_content`` documents, groups by category,
    generates Markdown, writes to ``newsletter_drafts/{date}``, and sends
    preview to founder email.
    """
    db = get_db()
    now = datetime.now(UTC)
    cutoff = now - timedelta(days=14)
    today_str = now.strftime("%Y-%m-%d")

    # Collect items from the last 14 days
    all_items: list[dict[str, Any]] = []
    content_ref = db.collection("newsletter_content")

    async for doc in content_ref.stream():
        data = doc.to_dict() or {}
        published_at_str = data.get("published_at", "")
        if not published_at_str:
            continue
        published_at = datetime.fromisoformat(published_at_str)
        if published_at.tzinfo is None:
            published_at = published_at.replace(tzinfo=UTC)
        if published_at >= cutoff:
            all_items.append(data)

    if not all_items:
        _log.info("No newsletter content in last 14 days — skipping draft")
        return {"skipped": True, "reason": "no_content"}

    # Group by category
    items_by_category: dict[str, list[dict[str, Any]]] = {}
    for item in all_items:
        cat = item.get("category", "best_practices")
        items_by_category.setdefault(cat, []).append(item)

    markdown_body = _assemble_markdown(items_by_category)

    # Write to Firestore
    draft_ref = db.collection("newsletter_drafts").document(today_str)
    await draft_ref.set(
        {
            "markdown_body": markdown_body,
            "item_count": len(all_items),
            "generated_at": now.isoformat(),
            "sent": False,
        }
    )

    # Send preview to founder
    ok = await send_template_email(
        to=_FOUNDER_EMAIL,
        template_alias="newsletter-preview",
        template_model={
            "markdown_body": markdown_body,
            "item_count": len(all_items),
            "date": today_str,
        },
    )

    log_action(
        customer_id=None,
        action="newsletter_draft_assembled",
        item_count=len(all_items),
        preview_sent=ok,
    )

    return {"item_count": len(all_items), "preview_sent": ok}


entry_point = newsletter_draft
