"""Central pint UnitRegistry and formatting helpers.

This module provides a singleton UnitRegistry and convenience functions for
formatting quantities with automatic SI prefix scaling.
"""

from __future__ import annotations

import threading
from typing import Optional, cast

import pint

_lock = threading.Lock()
_registry: Optional[pint.UnitRegistry] = None


def get_registry() -> pint.UnitRegistry:
    """Return a global pint UnitRegistry instance (thread-safe lazy init)."""
    global _registry
    if _registry is None:
        with _lock:
            if _registry is None:
                _registry = pint.UnitRegistry(auto_reduce_dimensions=True)
                # Enable compact formatting preferences if needed later
    return _registry


def format_quantity(
    value: float | int,
    unit: str = "",
    precision: int = 2,
    strategy: str = "auto",
) -> str:
    """Format a numeric value with unit using pint.

    Strategies:
    - raw: do not rescale, just show value with unit
    - auto: use pint's to_compact() for intelligent SI prefix scaling
    """
    reg = get_registry()
    # Treat empty unit as dimensionless
    if unit:
        quantity = cast(pint.Quantity, value * reg(unit))
    else:
        quantity = cast(pint.Quantity, value * reg.dimensionless)

    if strategy == "auto":
        try:
            quantity = cast(pint.Quantity, quantity.to_compact())
        except Exception:
            # Fallback: keep original if conversion fails (e.g. unknown unit)
            pass

    # Separate magnitude and unit for formatting
    magnitude = float(quantity.magnitude)
    # Use compact short notation (e.g., "Mbit/s" instead of "Mbit / s")
    unit_str = f"{quantity.units:~P}" if strategy == "auto" else f"{quantity.units:~}"
    unit_str = unit_str.strip()
    if unit_str:
        return f"{magnitude:.{precision}f} {unit_str}"
    return f"{magnitude:.{precision}f}"


class PintValueFormatter:
    """Formatter wrapping pint for consistent interface with display backend."""

    def __init__(
        self,
        unit: str = "",
        precision: int = 2,
        strategy: str = "raw",
    ) -> None:
        self.unit = unit
        self.precision = precision
        self.strategy = strategy  # 'raw' | 'auto'

    def format(self, value: float | int | None) -> str:
        if value is None:
            return "N/A"
        return format_quantity(value, self.unit, self.precision, self.strategy)

    def format_magnitude_only(self, value: float | int | None) -> str:
        """Format value with scaling applied but without unit string."""
        if value is None:
            return "—"
        reg = get_registry()
        if self.unit:
            quantity = cast(pint.Quantity, value * reg(self.unit))
        else:
            quantity = cast(pint.Quantity, value * reg.dimensionless)

        if self.strategy == "auto":
            try:
                quantity = cast(pint.Quantity, quantity.to_compact())
            except Exception:
                pass

        magnitude = float(quantity.magnitude)
        return f"{magnitude:.{self.precision}f}"
