from .ImageManipulation import ImageManipulation
from ImageContainer import ImageContainer
from typing import Any, List
from PIL import Image


class CropImage(ImageManipulation):
    """Concrete implementation for cropping images."""

    def __init__(self):
        # You can initialize any instance variables here
        self.manipulation_name = "Crop"

    def manipulateImage(self, image: ImageContainer, parameters: Any) -> None:
        """
        Manipulate the given image using the provided parameters.

        Args:
            image: The image to manipulate
            parameters: Parameters for the manipulation (e.g., crop coordinates)
        """

        pil_image = image.getImage()

        # If parameters provided as dict with width/height, do centered crop
        if isinstance(parameters, dict) and "width" in parameters and "height" in parameters:
            target_width = int(parameters["width"]) if parameters["width"] is not None else None
            target_height = int(parameters["height"]) if parameters["height"] is not None else None
            if target_width is None or target_height is None:
                return
            img_width, img_height = pil_image.size
            crop_width = min(target_width, img_width)
            crop_height = min(target_height, img_height)
            left = (img_width - crop_width) // 2
            top = (img_height - crop_height) // 2
            right = left + crop_width
            bottom = top + crop_height
        else:
            img_width, img_height = pil_image.size
            left = 80
            top = 80
            right = max(0, img_width - 130)
            bottom = max(0, img_height - 130)
            if right <= left or bottom <= top:
                return

        cropped = pil_image.crop((left, top, right, bottom))
        image._imageData = cropped

    def getParameters(self) -> List[str]:
        """
        Get the list of parameters required for cropping.

        Returns:
            List of parameter names
        """
        return ["width", "height"]

    def getManipulationName(self) -> str:
        """
        Get the name of this manipulation operation.

        Returns:
            The name of the manipulation
        """
        return "Crop Image"