#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Panel label utilities for multi-panel figures."""

import string
from typing import TYPE_CHECKING, Any, List, Optional, Tuple

if TYPE_CHECKING:
    from ._axes import RecordingAxes


def add_panel_labels(
    all_axes: List["RecordingAxes"],
    labels: Optional[List[str]],
    loc: str,
    offset: Tuple[float, float],
    fontsize: float,
    fontweight: str,
    text_color: str,
    record_callback: Any,
    **kwargs,
) -> List[Any]:
    """Add panel labels (A, B, C, D, etc.) to axes.

    Parameters
    ----------
    all_axes : list of RecordingAxes
        Flattened list of all axes.
    labels : list of str or None
        Custom labels. If None, uses uppercase letters.
    loc : str
        Location hint: 'upper left', 'upper right', 'lower left', 'lower right'.
    offset : tuple of float
        (x, y) offset in axes coordinates.
    fontsize : float
        Font size in points.
    fontweight : str
        Font weight.
    text_color : str
        Text color.
    record_callback : callable
        Callback to record panel labels info.
    **kwargs
        Additional arguments passed to ax.text().

    Returns
    -------
    list of Text
        The matplotlib Text objects created.
    """
    n_axes = len(all_axes)

    # Generate default labels if not provided
    if labels is None:
        labels = list(string.ascii_uppercase[:n_axes])
    elif len(labels) < n_axes:
        # Extend with letters if not enough labels provided
        labels = list(labels) + list(string.ascii_uppercase[len(labels) : n_axes])

    # Calculate position based on loc
    x, y, ha, va = _calculate_position(loc, offset)

    # Record panel labels
    record_callback(
        {
            "labels": labels[:n_axes],
            "loc": loc,
            "offset": offset,
            "fontsize": fontsize,
            "fontweight": fontweight,
            "color": text_color,
            "kwargs": kwargs,
        }
    )

    # Add labels to each axes
    text_objects = []
    for ax, label in zip(all_axes, labels[:n_axes]):
        text = ax.ax.text(
            x,
            y,
            label,
            transform=ax.ax.transAxes,
            fontsize=fontsize,
            fontweight=fontweight,
            color=text_color,
            ha=ha,
            va=va,
            **kwargs,
        )
        text_objects.append(text)

    return text_objects


def _calculate_position(
    loc: str, offset: Tuple[float, float]
) -> Tuple[float, float, str, str]:
    """Calculate text position and alignment based on location.

    Returns
    -------
    tuple
        (x, y, ha, va) where ha/va are horizontal/vertical alignment.
    """
    if loc == "upper left":
        x, y = offset
        ha, va = "right", "bottom"
    elif loc == "upper right":
        x, y = offset
        ha, va = "left", "bottom"
    elif loc == "lower left":
        x, y = offset[0], -offset[1] + 1.0
        ha, va = "right", "top"
    elif loc == "lower right":
        x, y = offset
        ha, va = "left", "top"
    else:
        x, y = offset
        ha, va = "right", "bottom"

    return x, y, ha, va


__all__ = ["add_panel_labels"]

# EOF
