from __future__ import annotations

from pathlib import Path

from PIL import Image, ImageDraw, ImageFont
from pypdf import PdfReader, PdfWriter
from pypdf.generic import ArrayObject, ByteStringObject, DictionaryObject, NameObject, NumberObject
from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.platypus import Image as FlowImage
from reportlab.platypus import PageBreak, Paragraph, SimpleDocTemplate, Spacer


ROOT = Path(__file__).resolve().parents[4]
PACKAGE = Path(__file__).resolve().parents[1]
INPUT = PACKAGE / "samples" / "input"
FIXTURES = PACKAGE / "evidence" / "fixtures"
SCREENSHOTS = PACKAGE / "screenshots"


def ensure_directories() -> None:
    for directory in (INPUT, FIXTURES, SCREENSHOTS):
        directory.mkdir(parents=True, exist_ok=True)


def draw_footer(pdf: canvas.Canvas, page_number: int) -> None:
    pdf.setStrokeColor(colors.HexColor("#d6dae3"))
    pdf.line(22 * mm, 16 * mm, 188 * mm, 16 * mm)
    pdf.setFillColor(colors.HexColor("#596170"))
    pdf.setFont("Helvetica", 8)
    pdf.drawString(22 * mm, 10 * mm, "LocalFlux PDF compression editorial fixture")
    pdf.drawRightString(188 * mm, 10 * mm, f"Page {page_number}")


def create_text_heavy_pdf(path: Path) -> None:
    pdf = canvas.Canvas(str(path), pagesize=A4, pageCompression=0)
    _, height = A4
    headings = [
        "A practical local PDF workflow",
        "Why file structure affects compression",
        "Checking a compressed copy",
        "When a PDF is already optimized",
        "A short review checklist",
    ]
    paragraph = (
        "A PDF is a container for pages, fonts, images, and document structure. "
        "Compression can reorganize repeated objects and recompress compatible streams, "
        "but the useful result depends on how the source was created. Keep the original, "
        "compare the measured size, open every page, and confirm that text and graphics remain readable."
    )
    for page_number, heading in enumerate(headings, start=1):
        pdf.setFillColor(colors.HexColor("#151923"))
        pdf.setFont("Helvetica-Bold", 22)
        pdf.drawString(22 * mm, height - 28 * mm, heading)
        pdf.setFillColor(colors.HexColor("#4b63d2"))
        pdf.roundRect(22 * mm, height - 42 * mm, 166 * mm, 7 * mm, 2 * mm, fill=1, stroke=0)
        text = pdf.beginText(22 * mm, height - 55 * mm)
        text.setFont("Times-Roman", 11)
        text.setLeading(14)
        text.setFillColor(colors.HexColor("#272b35"))
        for section in range(1, 7):
            text.textLine(f"Review point {section}")
            for sentence in (paragraph, paragraph):
                words = sentence.split()
                line = ""
                for word in words:
                    candidate = f"{line} {word}".strip()
                    if pdf.stringWidth(candidate, "Times-Roman", 11) > 160 * mm:
                        text.textLine(line)
                        line = word
                    else:
                        line = candidate
                if line:
                    text.textLine(line)
            text.textLine("")
        pdf.drawText(text)
        draw_footer(pdf, page_number)
        pdf.showPage()
    pdf.save()


def create_image_rich_pdf(path: Path) -> None:
    sources = [
        ROOT / "docs" / "blog_drafts" / "png-to-jpg-windows" / "samples" / "input" / "garden-photo.png",
        ROOT / "docs" / "blog_drafts" / "png-to-jpg-windows" / "samples" / "input" / "localflux-ui-screenshot.png",
        ROOT / "assets" / "brand" / "lf_logo.png",
    ]
    styles = getSampleStyleSheet()
    styles.add(ParagraphStyle(name="CenteredTitle", parent=styles["Title"], alignment=TA_CENTER, textColor=colors.HexColor("#151923")))
    story = [
        Paragraph("LocalFlux image-rich PDF fixture", styles["CenteredTitle"]),
        Spacer(1, 8 * mm),
        Paragraph(
            "This self-authored three-page lookbook uses only repository-controlled LocalFlux imagery. "
            "It deliberately embeds large PNG assets so image optimization has meaningful work to do.",
            styles["BodyText"],
        ),
        PageBreak(),
    ]
    captions = [
        "Photo-like landscape fixture",
        "Privacy-safe LocalFlux interface fixture",
        "LocalFlux brand mark on a neutral background",
    ]
    for index, (source, caption) in enumerate(zip(sources, captions), start=1):
        with Image.open(source) as image:
            width, height = image.size
        max_width, max_height = 245 * mm, 145 * mm
        scale = min(max_width / width, max_height / height)
        story.extend([
            Paragraph(caption, styles["Heading1"]),
            Spacer(1, 5 * mm),
            FlowImage(str(source), width=width * scale, height=height * scale),
            Spacer(1, 5 * mm),
            Paragraph(f"Source dimensions: {width} x {height} pixels.", styles["BodyText"]),
        ])
        if index != len(sources):
            story.append(PageBreak())
    document = SimpleDocTemplate(
        str(path),
        pagesize=landscape(A4),
        rightMargin=18 * mm,
        leftMargin=18 * mm,
        topMargin=16 * mm,
        bottomMargin=16 * mm,
        pageCompression=0,
        title="LocalFlux image-rich PDF fixture",
        author="LocalFlux",
    )
    document.build(story)


def create_signed_fixture(source: Path, path: Path) -> None:
    reader = PdfReader(str(source))
    writer = PdfWriter()
    writer.clone_document_from_reader(reader)
    signature = DictionaryObject({
        NameObject("/Type"): NameObject("/Sig"),
        NameObject("/Filter"): NameObject("/Adobe.PPKLite"),
        NameObject("/SubFilter"): NameObject("/adbe.pkcs7.detached"),
        NameObject("/ByteRange"): ArrayObject([NumberObject(0), NumberObject(1), NumberObject(2), NumberObject(3)]),
        NameObject("/Contents"): ByteStringObject(b"LocalFlux editorial signature fixture"),
        NameObject("/Reason"): ByteStringObject(b"Exercises the signed-PDF safety boundary"),
    })
    writer.root_object[NameObject("/LocalFluxSignatureFixture")] = writer._add_object(signature)
    with path.open("wb") as stream:
        writer.write(stream)


def create_input_contact_sheet(paths: list[Path], output: Path) -> None:
    import pymupdf

    page_previews = []
    for path in paths:
        document = pymupdf.open(path)
        pixmap = document[0].get_pixmap(matrix=pymupdf.Matrix(1.1, 1.1), alpha=False)
        preview = Image.frombytes("RGB", (pixmap.width, pixmap.height), pixmap.samples)
        preview.thumbnail((410, 500), Image.Resampling.LANCZOS)
        page_previews.append((path, preview.copy(), len(document)))
        document.close()

    canvas_image = Image.new("RGB", (1400, 720), "#f4f6fb")
    draw = ImageDraw.Draw(canvas_image)
    title_font = ImageFont.truetype("C:/Windows/Fonts/segoeuib.ttf", 34)
    label_font = ImageFont.truetype("C:/Windows/Fonts/segoeui.ttf", 22)
    detail_font = ImageFont.truetype("C:/Windows/Fonts/segoeui.ttf", 18)
    draw.text((44, 28), "Three privacy-safe PDF inputs", font=title_font, fill="#151923")
    for index, (path, preview, pages) in enumerate(page_previews):
        x = 44 + index * 450
        y = 96
        draw.rounded_rectangle((x, y, x + 410, y + 500), radius=18, fill="white", outline="#d8dce6", width=2)
        paste_x = x + (410 - preview.width) // 2
        paste_y = y + (500 - preview.height) // 2
        canvas_image.paste(preview, (paste_x, paste_y))
        draw.text((x, 620), path.name, font=label_font, fill="#202532")
        draw.text((x, 658), f"{pages} pages - publication-safe fixture", font=detail_font, fill="#596170")
    canvas_image.save(output, optimize=True)


def main() -> None:
    ensure_directories()
    text_path = INPUT / "text-heavy-handout.pdf"
    image_path = INPUT / "image-rich-lookbook.pdf"
    create_text_heavy_pdf(text_path)
    create_image_rich_pdf(image_path)
    create_signed_fixture(text_path, FIXTURES / "signed-sample.pdf")
    already_optimized = INPUT / "already-optimized-handout.pdf"
    if already_optimized.exists():
        create_input_contact_sheet(
            [text_path, image_path, already_optimized],
            SCREENSHOTS / "05-test-inputs.png",
        )


if __name__ == "__main__":
    main()
