from pathlib import Path

from PIL import Image


def expand_bbox(
    bbox: tuple[int, int, int, int],
    image_size: tuple[int, int],
    expand_ratio: float = 0.08,
) -> tuple[int, int, int, int]:
    x1, y1, x2, y2 = bbox
    width, height = image_size
    box_w = max(1, x2 - x1)
    box_h = max(1, y2 - y1)
    pad_x = int(round(box_w * expand_ratio))
    pad_y = int(round(box_h * expand_ratio))
    return (
        max(0, x1 - pad_x),
        max(0, y1 - pad_y),
        min(width, x2 + pad_x),
        min(height, y2 + pad_y),
    )


def center_fallback_bbox(image_size: tuple[int, int], ratio: float = 0.8) -> tuple[int, int, int, int]:
    width, height = image_size
    crop_w = max(1, int(width * ratio))
    crop_h = max(1, int(height * ratio))
    x1 = max(0, (width - crop_w) // 2)
    y1 = max(0, (height - crop_h) // 2)
    return x1, y1, x1 + crop_w, y1 + crop_h


def save_fallback_crop(image: Image.Image, output_path: str | Path) -> tuple[int, int, int, int]:
    bbox = center_fallback_bbox(image.size)
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)
    image.crop(bbox).save(output_path)
    return bbox
