"""輝度均一性評価モジュール."""

import numpy

# Rec.709 グレースケール変換係数
# 参照: ITU-R BT.709 (https://www.itu.int/rec/R-REC-BT.709/en)
REC709_COEFF_R = 0.2126
REC709_COEFF_G = 0.7152
REC709_COEFF_B = 0.0722


def to_grayscale(image: numpy.ndarray) -> numpy.ndarray:
    """RGB 画像を Rec.709 輝度係数でグレースケール（輝度画像）に変換する．

    OpenCV の cvtColor ではなく Rec.709 の係数を明示的に使用する．
    参照: ITU-R BT.709

    Args:
        image: 入力 RGB 画像の NumPy 配列（H x W x 3, uint8）．

    Returns:
        輝度画像の NumPy 配列（H x W, float64）．値域は 0.0〜255.0．
    """
    # float64 に変換してから係数を適用する（整数演算による丸め誤差を防ぐ）
    img_float = image.astype(numpy.float64)
    luminance = (
        REC709_COEFF_R * img_float[:, :, 0]
        + REC709_COEFF_G * img_float[:, :, 1]
        + REC709_COEFF_B * img_float[:, :, 2]
    )
    return luminance


def calc_uniformity(luminance: numpy.ndarray) -> dict:
    """輝度画像から均一性指標を算出する．

    3 つの指標を算出する:
    - CoV（変動係数）: σ / μ — 小さいほど均一（無次元）
    - std（標準偏差）: 輝度のばらつきの絶対値
    - max_min_ratio（最大/最小比）: max / min — 極端なムラの検出

    Args:
        luminance: 輝度画像の NumPy 配列（H x W, float64）．

    Returns:
        均一性指標を格納した辞書．キーは "cov", "std", "max_min_ratio",
        "mean", "max", "min"．

    Raises:
        ValueError: 輝度画像の最小値が 0 の場合（最大/最小比が計算不能）．
    """
    mean = float(numpy.mean(luminance))
    std = float(numpy.std(luminance))
    lmax = float(numpy.max(luminance))
    lmin = float(numpy.min(luminance))

    # CoV: 相対的なばらつきの指標
    cov = std / mean if mean != 0.0 else float("inf")

    # 最大/最小比: 極端なムラを検出する指標
    if lmin == 0.0:
        raise ValueError(
            "輝度の最小値が 0 のため最大/最小比を計算できません．"
            "ROI の設定を確認してください．"
        )
    max_min_ratio = lmax / lmin

    return {
        "cov": cov,
        "std": std,
        "max_min_ratio": max_min_ratio,
        "mean": mean,
        "max": lmax,
        "min": lmin,
    }
