from __future__ import annotations

from pathlib import Path
import re

from bs4 import BeautifulSoup
from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.shared import Cm, Pt, RGBColor

ROOT = Path(__file__).resolve().parents[1]
HTML_FILE = ROOT / "html-workspace" / "rujukan" / "bab-02-template-rujukan.html"
PROJECT_TEMPLATE = ROOT / "file-docs" / "PROJECT.docx"
OUTPUT_DIR = ROOT / "final"
OUTPUT_FILE = OUTPUT_DIR / "BAB_2_Template_Rujukan_Project_Template.docx"


def normalize(text: str) -> str:
    return re.sub(r"\s+", " ", text).strip()


def configure_document(document: Document):
    section = document.sections[0]
    section.page_width = Cm(21)
    section.page_height = Cm(29.7)
    section.top_margin = Cm(2.2)
    section.bottom_margin = Cm(2.2)
    section.left_margin = Cm(2.0)
    section.right_margin = Cm(2.0)

    normal = document.styles["Normal"]
    normal.font.name = "Arial"
    normal.font.size = Pt(11)
    normal.paragraph_format.line_spacing = 1.15
    normal.paragraph_format.space_after = Pt(3)


def add_paragraph(document: Document, text: str, style_name: str, align=None, left_indent_cm: float = 0):
    p = document.add_paragraph(style=style_name)
    p.paragraph_format.left_indent = Cm(left_indent_cm)
    p.paragraph_format.space_after = Pt(4)
    if align is not None:
        p.alignment = align
    for idx, line in enumerate(text.split("\n")):
        if idx:
            p.add_run().add_break()
        run = p.add_run(line)
    return p


def clear_document_body(document: Document):
    body = document._body._element
    for child in list(body):
        if child.tag.endswith("}sectPr"):
            continue
        body.remove(child)


def style_run(paragraph, font_size: float | None = None, bold: bool | None = None):
    for run in paragraph.runs:
        run.font.name = "Arial"
        run.font.color.rgb = RGBColor(31, 41, 51)
        if font_size is not None:
            run.font.size = Pt(font_size)
        if bold is not None:
            run.bold = bold


def build_docx():
    soup = BeautifulSoup(HTML_FILE.read_text(encoding="utf-8"), "lxml")
    document = Document(PROJECT_TEMPLATE)
    clear_document_body(document)
    configure_document(document)

    for tag in soup.select("main.page h1, main.page h2, main.page h3, main.page h4, main.page h5"):
        text = normalize(tag.get_text(" "))
        if not text:
            continue
        name = tag.name.lower()
        if name == "h1":
            text = "BAB 2 GAMBARAN UMUM DAN ANALISIS SITUASI EKSTERNAL"
            p = add_paragraph(document, text, "Heading 1", WD_ALIGN_PARAGRAPH.CENTER)
            style_run(p, 14, True)
        elif name == "h2":
            if text.upper().startswith("BAB 2"):
                continue
            p = add_paragraph(document, text, "Heading 2")
            style_run(p, 12, True)
        elif name == "h3":
            p = add_paragraph(document, text, "Heading 3")
            style_run(p, 11, True)
        elif name == "h4":
            p = add_paragraph(document, text, "Normal", left_indent_cm=0.75)
            style_run(p, 11, True)
        elif name == "h5":
            p = add_paragraph(document, text, "Normal", left_indent_cm=1.25)
            style_run(p, 10.5, False)

    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    document.save(OUTPUT_FILE)
    print(OUTPUT_FILE)


if __name__ == "__main__":
    build_docx()
