from pathlib import Path

import numpy as np
from PIL import Image


IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".bmp", ".webp"}


def list_images(path: str | Path) -> list[Path]:
    target = Path(path)
    if target.is_file():
        return [target]
    return sorted(p for p in target.rglob("*") if p.suffix.lower() in IMAGE_EXTENSIONS)


def read_rgb(path: str | Path) -> Image.Image:
    return Image.open(path).convert("RGB")


def save_rgb(image: Image.Image, path: str | Path) -> None:
    Path(path).parent.mkdir(parents=True, exist_ok=True)
    image.save(path)


def crop_image(image: Image.Image, bbox: tuple[int, int, int, int]) -> Image.Image:
    return image.crop(bbox)


def mask_to_bbox(mask: np.ndarray) -> tuple[int, int, int, int] | None:
    mask_bool = np.asarray(mask).astype(bool)
    ys, xs = np.where(mask_bool)
    if xs.size == 0 or ys.size == 0:
        return None
    return int(xs.min()), int(ys.min()), int(xs.max()) + 1, int(ys.max()) + 1
