class ColorAdjustment(StrEnum):
    brightness = "brightness"
    exposure = "exposure"
    gamma = "gamma"
    contrast = "contrast"
    saturation = "saturation"
    vibrance = "vibrance"
    warmth = "warmth" class CropAlignment(StrEnum):
    center = "center"  # type: ignore
    top = "top"
    right = "right"
    bottom = "bottom"
    left = "left" class Gif2VideoFormat(StrEnum):
    mp4 = "mp4"
    webm = "webm" class Gif2VideoQuality(StrEnum):
    lightest = "lightest"
    lighter = "lighter"
    normal = "normal"
    better = "better"
    best = "best" class ImageFilter(StrEnum):
    adaris = "adaris"
    briaril = "briaril"
    calarel = "calarel"
    carris = "carris"
    cynarel = "cynarel"
    cyren = "cyren"
    elmet = "elmet"
    elonni = "elonni"
    enzana = "enzana"
    erydark = "erydark"
    fenralan = "fenralan"
    ferand = "ferand"
    galen = "galen"
    gavin = "gavin"
    gethriel = "gethriel"
    iorill = "iorill"
    iothari = "iothari"
    iselva = "iselva"
    jadis = "jadis"
    lavra = "lavra"
    misiara = "misiara"
    namala = "namala"
    nerion = "nerion"
    nethari = "nethari"
    pamaya = "pamaya"
    sarnar = "sarnar"
    sedis = "sedis"
    sewen = "sewen"
    sorahel = "sorahel"
    sorlen = "sorlen"
    tarian = "tarian"
    thellassan = "thellassan"
    varriel = "varriel"
    varven = "varven"
    vevera = "vevera"
    virkas = "virkas"
    yedis = "yedis"
    yllara = "yllara"
    zatvel = "zatvel"
    zevcen = "zevcen" class ImageFormat(StrEnum):
    jpeg = "jpeg"
    png = "png"
    webp = "webp"
    auto = "auto" class ImageQuality(StrEnum):
    normal = "normal"
    better = "better"
    best = "best"
    lighter = "lighter"
    lightest = "lightest"
    smart = "smart"
    smart_retina = "smart_retina" class ImageTransformation(BaseTransformation):
    def preview(
        self,
        width: Optional[int] = None,
        height: Optional[int] = None,
    ) -> "ImageTransformation":
        parameters: List[str] = []

        if width or height:
            parameters.append(f'{width or ""}x{height or ""}')

        self.set("preview", parameters)
        return self

    def resize(
        self,
        width: Optional[int] = None,
        height: Optional[int] = None,
    ) -> "ImageTransformation":
        parameters = [f'{width or ""}x{height or ""}']
        self.set("resize", parameters)
        return self

    def stretch(self, mode: StretchMode) -> "ImageTransformation":
        self.set("stretch", [mode])
        return self

    def smart_resize(self, width: int, height: int) -> "ImageTransformation":
        parameters: List[str] = [f"{width}x{height}"]
        self.set("smart_resize", parameters)
        return self

    def crop(
        self,
        width: int,
        height: int,
        offset_x: Optional[Union[int, str]] = None,
        offset_y: Optional[Union[int, str]] = None,
        alignment: Optional[CropAlignment] = None,
    ) -> "ImageTransformation":
        parameters: List[str] = [f"{width}x{height}"]

        if alignment:
            parameters.append(alignment)
        elif offset_x and offset_y:
            parameters.append(f"{offset_x},{offset_y}")

        self.set("crop", parameters)
        return self

    def scale_crop(
        self,
        width: int,
        height: int,
        offset_x_percent: Optional[int] = None,
        offset_y_percent: Optional[int] = None,
        mode: Optional[ScaleCropMode] = None,
    ) -> "ImageTransformation":
        parameters: List[str] = [f"{width}x{height}"]

        if offset_x_percent and offset_y_percent:
            parameters.append(f"{offset_x_percent}p,{offset_y_percent}p")
        elif mode:
            parameters.append(mode)
        self.set("scale_crop", parameters)
        return self

    def setfill(self, color: str) -> "ImageTransformation":
        self.set("setfill", [color])
        return self

    def format(self, image_format: ImageFormat) -> "ImageTransformation":
        self.set("format", [image_format])
        return self

    def quality(self, image_quality: ImageQuality) -> "ImageTransformation":
        self.set("quality", [image_quality])
        return self

    def progressive(self, is_progressive=True) -> "ImageTransformation":
        self.set("progressive", ["yes" if is_progressive else "no"])
        return self

    def gif2video(self) -> "ImageTransformation":
        self.set("gif2video", [])
        return self

    def gif2video_format(
        self, format: Gif2VideoFormat
    ) -> "ImageTransformation":
        self.set("format", [format])
        return self

    def gif2video_quality(
        self, quality: Gif2VideoQuality
    ) -> "ImageTransformation":
        self.set("quality", [quality])
        return self

    def adjust_color(
        self, adjustment: ColorAdjustment, value: Optional[int] = None
    ) -> "ImageTransformation":
        parameters: List[str] = []
        if value is not None:
            parameters.append(str(value))
        self.set(str(adjustment), parameters)
        return self

    def enhance(self, value: Optional[int] = None) -> "ImageTransformation":
        parameters: List[str] = []
        if value is not None:
            parameters.append(str(value))
        self.set("enhance", parameters)
        return self

    def grayscale(self) -> "ImageTransformation":
        self.set("grayscale", [])
        return self

    def invert(self) -> "ImageTransformation":
        self.set("invert", [])
        return self

    def filter(
        self, image_filter: ImageFilter, value: Optional[int] = None
    ) -> "ImageTransformation":
        parameters: List[str] = [image_filter]
        if value is not None:
            parameters.append(str(value))
        self.set("filter", parameters)
        return self

    def srgb(self, conversion: SRGBConversion) -> "ImageTransformation":
        parameters: List[str] = [conversion]
        self.set("srgb", parameters)
        return self

    def max_icc_size(self, threshold: int) -> "ImageTransformation":
        parameters: List[str] = [str(threshold)]
        self.set("max_icc_size", parameters)
        return self

    def blur(
        self, strength: Optional[int] = None, amount: Optional[int] = None
    ) -> "ImageTransformation":
        parameters: List[str] = []
        if strength:
            parameters.append(str(strength))
            if amount:
                parameters.append(str(amount))
        self.set("blur", parameters)
        return self

    def blur_region(
        self,
        region_width: Union[str, int],
        region_height: Union[str, int],
        offset_x: Union[str, int],
        offset_y: Union[str, int],
        strength: Optional[int] = None,
    ) -> "ImageTransformation":
        parameters: List[str] = [
            f"{region_width}x{region_height}",
            f"{offset_x},{offset_y}",
        ]
        if strength is not None:
            parameters.append(str(strength))
        self.set("blur_region", parameters)
        return self

    def blur_faces(
        self, strength: Optional[int] = None
    ) -> "ImageTransformation":
        parameters: List[str] = ["faces"]
        if strength is not None:
            parameters.append(str(strength))
        self.set("blur_region", parameters)
        return self

    def sharp(self, strength: Optional[int] = None) -> "ImageTransformation":
        parameters: List[str] = []
        if strength is not None:
            parameters.append(str(strength))
        self.set("sharp", parameters)
        return self

    def overlay(
        self,
        uuid: str,
        overlay_width: Union[str, int],
        overlay_height: Union[str, int],
        offset: Optional[OverlayOffset] = None,
        offset_x: Optional[Union[str, int]] = None,
        offset_y: Optional[Union[str, int]] = None,
        strength: Optional[int] = None,
    ) -> "ImageTransformation":
        parameters: List[str] = [
            uuid,
            f"{overlay_width}x{overlay_height}",
        ]

        if offset:
            parameters.append(str(offset))
        else:
            parameters.append(f"{offset_x},{offset_y}")

        if strength is not None:
            parameters.append(f"{strength}p")

        self.set("overlay", parameters)
        return self

    def overlay_self(
        self,
        overlay_width: Union[str, int],
        overlay_height: Union[str, int],
        offset: Optional[OverlayOffset] = None,
        offset_x: Optional[Union[str, int]] = None,
        offset_y: Optional[Union[str, int]] = None,
        strength: Optional[int] = None,
    ) -> "ImageTransformation":
        parameters: List[str] = [
            "self",
            f"{overlay_width}x{overlay_height}",
        ]

        if offset:
            parameters.append(offset)
        else:
            parameters.append(f"{offset_x},{offset_y}")

        if strength is not None:
            parameters.append(f"{strength}p")

        self.set("overlay", parameters)
        return self

    def autorotate(self, enabled=True) -> "ImageTransformation":
        parameters: List[str] = ["yes" if enabled else "no"]
        self.set("autorotate", parameters)
        return self

    def rotate(self, angle: int) -> "ImageTransformation":
        parameters: List[str] = [str(angle)]
        self.set("rotate", parameters)
        return self

    def flip(self) -> "ImageTransformation":
        self.set("flip", [])
        return self

    def mirror(self) -> "ImageTransformation":
        self.set("mirror", [])
        return self

    def path(self, file_id: str) -> str:
        path_ = super().path(file_id)
        path_ = path_.replace("/-/gif2video", "/gif2video")
        return path_ class OverlayOffset(StrEnum):
    left = "left"
    right = "right"
    top = "top"
    bottom = "bottom"
    center = "center"  # type: ignore class ScaleCropMode(StrEnum):
    center = "center"  # type: ignore
    smart = "smart"
    smart_faces_objects = "smart_faces_objects"
    smart_faces_points = "smart_faces_points"
    smart_objects_faces_points = "smart_objects_faces_points"
    smart_objects_faces = "smart_objects_faces"
    smart_objects_points = "smart_objects_points"
    smart_points = "smart_points"
    smart_objects = "smart_objects"
    smart_faces = "smart_faces" class SRGBConversion(StrEnum):
    fast = "fast"
    icc = "icc"
    keep_profile = "keep_profile" class StretchMode(StrEnum):
    on = "on"
    off = "off"
    fill = "fill"
from pyuploadcare.transformations.image import (
    ColorAdjustment,
    CropAlignment,
    Gif2VideoFormat,
    Gif2VideoQuality,
    ImageFilter,
    ImageFormat,
    ImageQuality,
    ImageTransformation,
    OverlayOffset,
    ScaleCropMode,
    SRGBConversion,
    StretchMode,
)


def test_image_transformation_path():
    transformation = (
        ImageTransformation()
        .quality(ImageQuality.best)
        .preview(160, 160)
        .setfill("8d8578")
        .stretch(StretchMode.fill)
        .resize(220)
    )
    assert str(transformation) == (
        "quality/best/-/preview/160x160/"
        "-/setfill/8d8578/-/stretch/fill/-/resize/220x/"
    )
    assert transformation.path("52da3bfc-7cd8-4861-8b05-126fef7a6994") == (
        "52da3bfc-7cd8-4861-8b05-126fef7a6994/"
        "-/quality/best/-/preview/160x160/"
        "-/setfill/8d8578/-/stretch/fill/-/resize/220x/"
    )


def test_image_smart_resize():
    transformation = (
        ImageTransformation()
        .smart_resize(440, 600)
        .quality(ImageQuality.smart)
    )

    assert str(transformation) == ("smart_resize/440x600/-/quality/smart/")


def test_image_crop():
    transformation = ImageTransformation().crop(
        2000, 1325, alignment=CropAlignment.center
    )

    assert str(transformation) == "crop/2000x1325/center/"


def test_image_crop_offset():
    transformation = ImageTransformation().crop(
        640, 424, offset_x=2560, offset_y=830
    )

    assert str(transformation) == "crop/640x424/2560,830/"


def test_image_scale_crop():
    transformation = ImageTransformation().scale_crop(
        1024, 1024, mode=ScaleCropMode.center
    )

    assert str(transformation) == "scale_crop/1024x1024/center/"


def test_setfill():
    transformation = (
        ImageTransformation().setfill("ece3d2").format(ImageFormat.jpeg)
    )

    assert str(transformation) == "setfill/ece3d2/-/format/jpeg/"


def test_image_progressive():
    transformation = (
        ImageTransformation()
        .preview()

        .quality(ImageQuality.best)