"""Service for generating PDF documents."""

from io import BytesIO
from pathlib import Path
from typing import Optional

from jinja2 import Environment, FileSystemLoader

from app.models.application import Application


# Setup Jinja2 environment for PDF templates
template_dir = Path(__file__).parent.parent.parent / "templates" / "pdfs"
env = Environment(loader=FileSystemLoader(str(template_dir)))


# Lazy import WeasyPrint to avoid import errors if GTK+ libraries are not installed
_weasyprint_available = None
_HTML = None


def _check_weasyprint():
    """Check if WeasyPrint is available and can be imported."""
    global _weasyprint_available, _HTML
    if _weasyprint_available is None:
        try:
            from weasyprint import HTML
            _HTML = HTML
            _weasyprint_available = True
        except (ImportError, OSError) as e:
            _weasyprint_available = False
            print(f"Warning: WeasyPrint not available: {e}")
            print("PDF will use xhtml2pdf fallback (no GTK required).")
    return _weasyprint_available


def _html_to_pdf_xhtml2pdf(html_content: str) -> bytes:
    """Generate PDF from HTML using xhtml2pdf (pure Python, works on Windows without GTK)."""
    try:
        from xhtml2pdf import pisa
    except ImportError:
        raise RuntimeError(
            "PDF generation requires xhtml2pdf. Install it with: pip install xhtml2pdf"
        )
    dest = BytesIO()
    pisa.CreatePDF(html_content, dest=dest, encoding="utf-8")
    return dest.getvalue()


class PDFService:
    """Service for generating PDF documents. Admission letters are generated on the frontend only."""

    @staticmethod
    def generate_rejection_letter(application: Application, output_path: Optional[str] = None) -> bytes:
        """Generate rejection letter PDF (WeasyPrint if available, else xhtml2pdf)."""
        template = env.get_template("rejection_letter.html")
        html_content = template.render(
            application=application,
            rejection_note=application.rejection_note,
        )
        if _check_weasyprint():
            try:
                pdf_bytes = _HTML(string=html_content).write_pdf()
            except (OSError, AttributeError) as e:
                print(f"WeasyPrint runtime error, falling back to xhtml2pdf: {e}")
                pdf_bytes = _html_to_pdf_xhtml2pdf(html_content)
        else:
            pdf_bytes = _html_to_pdf_xhtml2pdf(html_content)
        if output_path:
            Path(output_path).parent.mkdir(parents=True, exist_ok=True)
            with open(output_path, "wb") as f:
                f.write(pdf_bytes)
        return pdf_bytes
