"""Figures DOCX builder — TürkPatent resim sayfası kuralları.

reference-scripts/build_turkpatent_figures_docx.py'den adapte edildi.

TPMK resim sayfası farkları (tarifname/istem/özet'ten):
- Kenarlar: Üst 25 mm / Sol 25 mm / Sağ 15 mm / Alt 10 mm (farklı set)
- Satır numarası YOK
- Sayfa numarası `N/toplam` formatında (Word PAGE field + literal "/<total>")
- Her şekil ayrı sayfada, sayfada "Şekil N" etiketli
"""

from __future__ import annotations

import io
from typing import TypedDict

from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Mm, Pt
from PIL import Image


class FigureInput(TypedDict):
    png_bytes: bytes
    title: str | None  # opsiyonel şekil başlığı (Şekil N etiketinden ayrı)


def _set_figure_page_margins(section) -> None:
    section.page_height = Mm(297)
    section.page_width = Mm(210)
    section.top_margin = Mm(25)
    section.left_margin = Mm(25)
    section.right_margin = Mm(15)
    section.bottom_margin = Mm(10)
    section.header_distance = Mm(10)
    section.footer_distance = Mm(5)


def _add_page_number_n_of_total(footer, total_pages: int) -> None:
    """Alt ortalanmış 'PAGE/N' — PAGE dinamik field, N literal sabit."""
    p = footer.paragraphs[0]
    p.alignment = WD_ALIGN_PARAGRAPH.CENTER

    run = p.add_run()
    run.font.name = "Times New Roman"
    run.font.size = Pt(11)

    # PAGE field
    begin = OxmlElement("w:fldChar")
    begin.set(qn("w:fldCharType"), "begin")
    instr = OxmlElement("w:instrText")
    instr.set(qn("xml:space"), "preserve")
    instr.text = "PAGE"
    end = OxmlElement("w:fldChar")
    end.set(qn("w:fldCharType"), "end")
    run._r.append(begin)
    run._r.append(instr)
    run._r.append(end)

    # "/{total}" literal
    run2 = p.add_run(f"/{total_pages}")
    run2.font.name = "Times New Roman"
    run2.font.size = Pt(11)


def _compute_image_size_mm(
    png_bytes: bytes,
    max_width_mm: float,
    max_height_mm: float,
) -> tuple[float, float]:
    """En-boy oranını koruyarak sayfaya sığan en büyük boyutu hesapla."""
    with Image.open(io.BytesIO(png_bytes)) as im:
        px_w, px_h = im.size
    if px_w <= 0 or px_h <= 0:
        return max_width_mm, max_height_mm
    ratio = px_w / px_h
    w_mm = max_width_mm
    h_mm = w_mm / ratio
    if h_mm > max_height_mm:
        h_mm = max_height_mm
        w_mm = h_mm * ratio
    return w_mm, h_mm


def build_figures_docx(title: str, figures: list[FigureInput]) -> bytes:
    """Resimler.docx — her şekil ayrı sayfada, 'Şekil N' etiketli.

    Args:
        title: Patent başlığı (ilk sayfada merkezli gösterilebilir ama
            TPMK formatı gerekmez; boş bırakılabilir).
        figures: [{"png_bytes": b"...", "title": "Sistem mimarisi"}, ...]

    Returns:
        DOCX bytes.
    """
    if not figures:
        raise ValueError("Figures list cannot be empty.")

    doc = Document()

    # Default style
    style = doc.styles["Normal"]
    style.font.name = "Times New Roman"
    style.font.size = Pt(12)

    # Tek section — tüm şekiller tek section'da, aralarda page_break
    section = doc.sections[0]
    _set_figure_page_margins(section)
    # Satır numarası EKLENMİYOR (TPMK: resim sayfalarında line numbering yok)
    _add_page_number_n_of_total(section.footer, len(figures))

    # Yerleşim alanı: A4 − kenar marjları − başlık için alt boşluk
    max_w_mm = 210 - 25 - 15  # 170 mm
    max_h_mm = 297 - 25 - 10 - 25  # 237 mm (~25mm caption için)

    for i, fig in enumerate(figures, start=1):
        if i > 1:
            doc.add_page_break()

        w_mm, _ = _compute_image_size_mm(fig["png_bytes"], max_w_mm, max_h_mm)

        # Ortalanmış resim
        p = doc.add_paragraph()
        p.alignment = WD_ALIGN_PARAGRAPH.CENTER
        run = p.add_run()
        run.add_picture(io.BytesIO(fig["png_bytes"]), width=Mm(w_mm))

        # "Şekil N" etiketi (opsiyonel başlık varsa onu da ekle)
        caption = doc.add_paragraph()
        caption.alignment = WD_ALIGN_PARAGRAPH.CENTER
        cr = caption.add_run(f"Şekil {i}")
        cr.bold = True
        cr.font.name = "Times New Roman"
        cr.font.size = Pt(12)
        caption.paragraph_format.space_before = Pt(6)

        fig_title = (fig.get("title") or "").strip()
        if fig_title:
            sub = doc.add_paragraph()
            sub.alignment = WD_ALIGN_PARAGRAPH.CENTER
            sr = sub.add_run(fig_title)
            sr.font.name = "Times New Roman"
            sr.font.size = Pt(11)

    _ = title  # Şu an kullanılmıyor; ileride kapak sayfası için rezerve
    buffer = io.BytesIO()
    doc.save(buffer)
    return buffer.getvalue()
