"""Centralised font-loading utilities for all image-composition modules."""

import os

from PIL import ImageFont


def get_system_font(
    size: int,
    bold: bool = True,
) -> ImageFont.FreeTypeFont | ImageFont.ImageFont:
    """Return a system font at *size*, preferring bold when *bold* is ``True``.

    Falls back to the PIL default font when no system font is found.
    """
    # Each entry is (path, ttc_index). Index matters for TTC collections:
    # HelveticaNeue.ttc: 0=Regular, 1=Bold  |  Helvetica.ttc: 0=Regular, 1=Bold
    if bold:
        candidates = [
            ("/System/Library/Fonts/HelveticaNeue.ttc", 1),   # macOS: Helvetica Neue Bold
            ("/System/Library/Fonts/Helvetica.ttc", 1),        # macOS: Helvetica Bold
            ("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 0),
            ("/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", 0),
            ("/usr/share/fonts/liberation/LiberationSans-Bold.ttf", 0),
        ]
    else:
        candidates = [
            ("/System/Library/Fonts/HelveticaNeue.ttc", 0),   # macOS: Helvetica Neue Regular
            ("/System/Library/Fonts/Helvetica.ttc", 0),        # macOS: Helvetica Regular
            ("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 0),
            ("/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", 0),
            ("/usr/share/fonts/liberation/LiberationSans-Regular.ttf", 0),
        ]
    for path, index in candidates:
        if os.path.exists(path):
            try:
                return ImageFont.truetype(path, size, index=index)
            except OSError:
                continue
    return ImageFont.load_default()


def load_template_font(
    template: dict,
    size: int,
    bold: bool = False,
) -> ImageFont.FreeTypeFont | ImageFont.ImageFont:
    """Load a font based on *template* configuration.

    Tries the configured font family + suffix, then without suffix, then falls
    back to :func:`get_system_font`.

    Parameters
    ----------
    template:
        The poster template dict (may contain a ``font`` section).
    size:
        Font size in pixels.
    bold:
        When ``True`` use ``bold_suffix``; otherwise use ``regular_suffix``.
    """
    font_cfg = template.get("font", {})
    family = font_cfg.get("family", "Helvetica")

    # Optional explicit path override per weight (e.g. bold_family, regular_family)
    # bold_family_index / regular_family_index select a face inside a TTC collection.
    if bold:
        explicit_path = font_cfg.get("bold_family", "")
        explicit_index = font_cfg.get("bold_family_index", 0)
        suffix = font_cfg.get("bold_suffix", " Bold")
    else:
        explicit_path = font_cfg.get("regular_family", "")
        explicit_index = font_cfg.get("regular_family_index", 0)
        suffix = font_cfg.get("regular_suffix", "")

    if explicit_path:
        try:
            return ImageFont.truetype(explicit_path, size, index=explicit_index)
        except (OSError, IOError):
            pass

    font_name = f"{family}{suffix}"
    try:
        return ImageFont.truetype(font_name, size)
    except (OSError, IOError):
        pass

    # Try without suffix
    if suffix:
        try:
            return ImageFont.truetype(family, size)
        except (OSError, IOError):
            pass

    # Fall back to built-in system-font candidates
    return get_system_font(size, bold=bold)
