"""ROI（関心領域）抽出モジュール．

SPEC_02 の evaluation.roi 仕様に基づき，輝度画像または RGB 画像から
矩形 ROI を切り出す．現在は image_pixel 型のみ対応．
"""

from __future__ import annotations

import numpy

from sm_tias_lightsim.scene.schema import RoiConfig


def extract_roi(image: numpy.ndarray, roi: RoiConfig) -> numpy.ndarray:
    """画像から ROI（関心領域）を矩形クロップで抽出する．

    image_pixel 型の ROI 設定に従い，`roi.x`, `roi.y`, `roi.width`, `roi.height` で
    矩形領域を切り出す．2D（輝度）・3D（RGB）どちらの配列も受け付ける．

    Args:
        image: 輝度画像（H x W, float64）または RGB 画像（H x W x 3）．
            先頭 2 軸が H, W であること．
        roi: ROI 設定（RoiConfig）．type は "image_pixel" のみ対応．

    Returns:
        ROI でクロップされた配列．入力と同じ次元数を持つ．

    Raises:
        NotImplementedError: roi.type が "image_pixel" 以外の場合．
        ValueError: ROI が画像の範囲外にはみ出す場合．
    """
    # scene_face 等の将来型は NotImplementedError で明示的に未対応を伝える（SPEC_02 参照）
    if roi.type != "image_pixel":
        msg = f"ROI type '{roi.type}' は未対応です．現在は 'image_pixel' のみサポートしています．"
        raise NotImplementedError(msg)

    img_height, img_width = image.shape[:2]

    x_end = roi.x + roi.width
    y_end = roi.y + roi.height

    if roi.x < 0 or roi.y < 0:
        msg = (
            f"ROI の開始座標 (x={roi.x}, y={roi.y}) が負の値です．"
            "ROI 設定を確認してください．"
        )
        raise ValueError(msg)

    if x_end > img_width or y_end > img_height:
        msg = (
            f"ROI (x={roi.x}, y={roi.y}, width={roi.width}, height={roi.height}) が "
            f"画像サイズ (width={img_width}, height={img_height}) を超えています．"
            "ROI 設定を確認してください．"
        )
        raise ValueError(msg)

    return image[roi.y : y_end, roi.x : x_end]
