"""Render compliance markdown documents to branded PDF via WeasyPrint.

WeasyPrint is an optional dependency — this module gracefully handles
its absence with a clear error message.
"""

from datetime import date
from pathlib import Path
from typing import Any

import yaml

try:
    import markdown  # type: ignore[import-untyped]
    import weasyprint
    from jinja2 import Template

    HAS_RENDERER_DEPS = True
except ImportError:
    HAS_RENDERER_DEPS = False


PACKAGE_DIR = Path(__file__).parent
CSS_PATH = PACKAGE_DIR / "css" / "compliance.css"
TEMPLATE_PATH = PACKAGE_DIR / "templates" / "document.html"

# Minimal brandspec for projects without one
DEFAULT_BRANDSPEC: dict[str, Any] = {
    "brand": {
        "identity": {"name": "Untitled Project", "legal_name": "Untitled Project"},
        "colours": {
            "primary": "#1a365d",
            "secondary": "#2b6cb0",
            "accent": "#38a169",
            "text": "#1a202c",
            "muted": "#718096",
        },
        "compliance": {
            "document_control": {
                "author": "Generated by Dazzle Compliance Pipeline",
                "classification": "Confidential",
            }
        },
    }
}


def load_brandspec(path: Path | None = None, project_path: Path | None = None) -> dict[str, Any]:
    """Load brandspec.yaml from explicit path or project root.

    Falls back to DEFAULT_BRANDSPEC if not found.
    """
    if path and path.exists():
        result: dict[str, Any] = yaml.safe_load(path.read_text())
        return result

    if project_path:
        candidate = project_path / ".dazzle" / "compliance" / "brandspec.yaml"
        if candidate.exists():
            result = yaml.safe_load(candidate.read_text())
            return result

    return DEFAULT_BRANDSPEC


def render_document(
    markdown_path: Path,
    output_path: Path,
    brandspec: dict[str, Any],
    document_title: str,
    document_id: str,
    version: str = "1.0",
    reviewer: str = "",
    approver: str = "",
) -> Path:
    """Render a markdown document to a branded PDF.

    Requires weasyprint, jinja2, and markdown packages.
    Install with: pip install weasyprint jinja2 markdown
    """
    if not HAS_RENDERER_DEPS:
        raise RuntimeError(
            "PDF rendering requires optional dependencies. "
            "Install with: pip install weasyprint jinja2 markdown"
        )

    brand = brandspec["brand"]
    identity = brand["identity"]
    colours = brand["colours"]
    compliance = brand.get("compliance", {})
    doc_control = compliance.get("document_control", {})

    md_text = markdown_path.read_text()
    content_html = markdown.markdown(
        md_text,
        extensions=["tables", "toc", "fenced_code"],
    )

    if not TEMPLATE_PATH.exists():
        raise FileNotFoundError(f"Template not found: {TEMPLATE_PATH}")
    if not CSS_PATH.exists():
        raise FileNotFoundError(f"CSS not found: {CSS_PATH}")

    template = Template(TEMPLATE_PATH.read_text())
    html_str = template.render(
        content=content_html,
        document_title=document_title,
        document_id=document_id,
        version=version,
        date=date.today().isoformat(),
        organisation_name=identity["name"],
        legal_name=identity.get("legal_name", identity["name"]),
        classification=doc_control.get("classification", "Confidential"),
        author=doc_control.get("author", "Compliance Pipeline"),
        reviewer=reviewer or doc_control.get("reviewer", ""),
        approver=approver or doc_control.get("approver", ""),
        colours=colours,
        css_path=str(CSS_PATH),
    )

    output_path.parent.mkdir(parents=True, exist_ok=True)
    weasyprint.HTML(string=html_str, base_url=str(PACKAGE_DIR)).write_pdf(str(output_path))

    return output_path
