from __future__ import annotations

import io

from pptx import Presentation
from pptx.util import Inches

from .deck_models import DeckSpec, DesignSpec
from .models import PptxImageAsset
from .rendering_slides import RENDERERS
from .rendering_styles import (
    _is_compact_four_card_column,
    _is_compact_kpi_metric,
    _resolve_theme,
)


def render_deck_to_bytes(spec: DeckSpec, image_assets: dict[str, PptxImageAsset] | None = None) -> bytes:
    """Render one validated deck spec into an editable `.pptx` binary.

    `image_assets` is the already-resolved deck-local registry keyed by `asset_id`. Text-only slide types ignore
    it; image-bearing slide types consume it directly instead of trying to resolve artifacts during rendering.
    """
    prs = Presentation()
    if spec.deck.size == "wide_16_9":
        prs.slide_width = Inches(13.333)
        prs.slide_height = Inches(7.5)
    else:
        prs.slide_width = Inches(10)
        prs.slide_height = Inches(7.5)

    blank_layout = prs.slide_layouts[6]
    for index, slide_spec in enumerate(spec.slides):
        slide = prs.slides.add_slide(blank_layout)
        effective_design = slide_spec.design
        if index == 0 and slide_spec.type == "title" and slide_spec.design.background == "light":
            effective_design = DesignSpec(
                variant=slide_spec.design.variant,
                density=slide_spec.design.density,
                tone=slide_spec.design.tone,
                background="dark",
            )

        theme = _resolve_theme(spec, effective_design)
        renderer = RENDERERS[slide_spec.type]
        if slide_spec.type in {"image_text", "image"}:
            renderer(prs, slide, slide_spec, theme, effective_design, image_assets or {})
        else:
            renderer(prs, slide, slide_spec, theme, effective_design)

    output = io.BytesIO()
    prs.save(output)
    return output.getvalue()
