"""Resize operation for scaling images."""

from typing import Any, ClassVar

import cv2
import numpy as np
from numpy.typing import NDArray

from axm.operations import OperationProtocol, OperationResult


class ResizeOperation(OperationProtocol):
    """Resize an image to specified dimensions or scale.

    Config:
        width: Target width (optional).
        height: Target height (optional).
        scale: Scale factor (optional, alternative to width/height).
        interpolation: Interpolation method (default: "bilinear").
    """

    INTERPOLATION_MAP: ClassVar[dict[str, int]] = {
        "nearest": cv2.INTER_NEAREST,
        "bilinear": cv2.INTER_LINEAR,
        "bicubic": cv2.INTER_CUBIC,
        "lanczos": cv2.INTER_LANCZOS4,
    }

    @property
    def name(self) -> str:
        """Operation name."""
        return "image.resize"

    def execute(
        self,
        data: NDArray[np.uint8] | None,
        context: dict[str, Any],
        config: dict[str, Any],
    ) -> OperationResult:
        """Resize image to target dimensions.

        Args:
            data: Input image array.
            context: Unused.
            config: width/height or scale, plus interpolation.

        Returns:
            OperationResult with resized image.
        """
        if data is None:
            return OperationResult(
                data=None,
                success=False,
                error="No input image provided",
            )

        img_height, img_width = data.shape[:2]

        # Get target size
        width = config.get("width")
        height = config.get("height")
        scale = config.get("scale")

        if scale is not None:
            new_width = int(img_width * scale)
            new_height = int(img_height * scale)
        elif width is not None and height is not None:
            new_width = width
            new_height = height
        elif width is not None:
            new_width = width
            new_height = int(img_height * (width / img_width))
        elif height is not None:
            new_height = height
            new_width = int(img_width * (height / img_height))
        else:
            return OperationResult(
                data=None,
                success=False,
                error="Must specify width, height, or scale",
            )

        # Get interpolation method
        interp_name = config.get("interpolation", "bilinear")
        interpolation = self.INTERPOLATION_MAP.get(interp_name, cv2.INTER_LINEAR)

        resized: NDArray[Any] = cv2.resize(
            data, (new_width, new_height), interpolation=interpolation
        )

        return OperationResult(
            data=resized,
            success=True,
            metadata={"width": new_width, "height": new_height},
        )
