"""Domain ports (ABCs) for prediction operations."""

from abc import ABC, abstractmethod

from numpy import ndarray
from PIL.Image import Image

from samgis_core.utilities.type_hints import ListDict


class PredictorPort(ABC):
    """Segments objects in an image given point/box prompts.

    Usage:
        predictor.set_image(image)   # preprocess + encode (caches internally)
        masks, ious = predictor.predict(prompt)

    Args for set_image:
        image: RGB image as HWC uint8 ndarray or PIL Image.

    Args for predict:
        prompt: ListDict of point/rectangle prompts, e.g.
            [{"type": "point", "data": [x, y], "label": 1},
             {"type": "rectangle", "data": [x1, y1, x2, y2], "label": 0}]

    Returns from predict:
        masks: (N, H, W) uint8 ndarray, values {0, 255}.
        ious: (N,) float32 ndarray of IoU confidence scores.
    """

    @abstractmethod
    def set_image(self, image: ndarray | Image) -> None:
        """Preprocess image and compute encoder embeddings."""
        ...

    @abstractmethod
    def predict(self, prompt: ListDict) -> tuple[ndarray, ndarray]:
        """Predict segmentation masks for the given prompts.

        Raises:
            RuntimeError: If set_image() has not been called.
            ValueError: If prompt is empty or contains multiple rectangles.
        """
        ...
