"""
Test font utilities for ensuring consistent font usage across tests.

This module provides utilities to guarantee that all tests use the same bundled font,
preventing inconsistencies that can arise from different system fonts.
"""

import os
from typing import Optional
from PIL import ImageFont

from pyWebLayout.style.fonts import Font, FontWeight, FontStyle, TextDecoration


def get_bundled_font_path() -> Optional[str]:
    """
    Get the path to the bundled DejaVuSans.ttf font.

    This function works from test directories by finding the font relative to the
    test file locations.

    Returns:
        str: Path to the bundled font file, or None if not found
    """
    # Get the directory containing this test utility file
    current_dir = os.path.dirname(os.path.abspath(__file__))

    # Navigate up to the project root (tests/utils -> tests -> root)
    project_root = os.path.dirname(os.path.dirname(current_dir))

    # Path to the bundled font
    bundled_font_path = os.path.join(
        project_root,
        'pyWebLayout',
        'assets',
        'fonts',
        'DejaVuSans.ttf')

    if os.path.exists(bundled_font_path):
        return bundled_font_path

    # Alternative: try to find it relative to the pyWebLayout module
    try:
        import pyWebLayout
        module_dir = os.path.dirname(pyWebLayout.__file__)
        alt_font_path = os.path.join(module_dir, 'assets', 'fonts', 'DejaVuSans.ttf')
        if os.path.exists(alt_font_path):
            return alt_font_path
    except ImportError:
        pass

    return None


def verify_bundled_font_available() -> bool:
    """
    Verify that the bundled font is available and can be loaded.

    Returns:
        bool: True if the bundled font is available and loadable
    """
    font_path = get_bundled_font_path()
    if not font_path:
        return False

    try:
        # Try to load the font with PIL to verify it's valid
        ImageFont.truetype(font_path, 16)
        return True
    except Exception:
        return False


def create_test_font(font_size: int = 16,
                     colour: tuple = (0, 0, 0),
                     weight: FontWeight = FontWeight.NORMAL,
                     style: FontStyle = FontStyle.NORMAL,
                     decoration: TextDecoration = TextDecoration.NONE,
                     background: Optional[tuple] = None,
                     language: str = "en_EN",
                     min_hyphenation_width: Optional[int] = None) -> Font:
    """
    Create a Font object that uses the bundled font for consistent testing.

    This function ensures all tests use the same font file, preventing
    cross-system inconsistencies in text measurements and layout.

    Args:
        font_size: Size of the font in points
        colour: RGB color tuple for the text
        weight: Font weight (normal or bold)
        style: Font style (normal or italic)
        decoration: Text decoration (none, underline, or strikethrough)
        background: RGBA background color for the text
        language: Language code for hyphenation and text processing
        min_hyphenation_width: Minimum width in pixels for hyphenation

    Returns:
        Font: A Font object guaranteed to use the bundled font

    Raises:
        RuntimeError: If the bundled font cannot be found or loaded
    """
    font_path = get_bundled_font_path()
    if not font_path:
        raise RuntimeError(
            "Bundled font (DejaVuSans.ttf) not found. "
            "Ensure the font exists in pyWebLayout/assets/fonts/"
        )

    if not verify_bundled_font_available():
        raise RuntimeError(
            f"Bundled font at {font_path} cannot be loaded. "
            "Font file may be corrupted or invalid."
        )

    return Font(
        font_path=font_path,
        font_size=font_size,
        colour=colour,
        weight=weight,
        style=style,
        decoration=decoration,
        background=background,
        language=language,
        min_hyphenation_width=min_hyphenation_width
    )


def create_default_test_font() -> Font:
    """
    Create a default Font object for testing with the bundled font.

    This is equivalent to Font() but guarantees the bundled font is used.

    Returns:
        Font: A default Font object using the bundled font
    """
    return create_test_font()


def ensure_consistent_font_in_tests():
    """
    Ensure that tests are using consistent fonts by checking availability.

    This function can be called in test setup to verify the font environment
    is properly configured.

    Raises:
        RuntimeError: If the bundled font is not available
    """
    if not verify_bundled_font_available():
        font_path = get_bundled_font_path()
        if font_path:
            raise RuntimeError(
                f"Bundled font found at {font_path} but cannot be loaded. "
                "Font file may be corrupted."
            )
        else:
            raise RuntimeError(
                "Bundled font (DejaVuSans.ttf) not found. "
                "Ensure the font exists in pyWebLayout/assets/fonts/"
            )


# Convenience aliases
get_test_font = create_default_test_font
font_factory = create_test_font
