from PIL import Image
from pathlib import Path
from typing import Optional
import io


def resize_image(
    image_path: Path,
    max_size: int,
    quality: int,
    remove_exif: bool = True
) -> Optional[bytes]:
    try:
        with Image.open(image_path) as img:
            img = apply_exif_rotation(img)
            
            if img.width > max_size or img.height > max_size:
                img = resize_proportional(img, max_size)
            
            output_bytes = save_as_webp(img, quality)
            return output_bytes
            
    except Exception:
        return None


def apply_exif_rotation(img: Image.Image) -> Image.Image:
    try:
        from PIL import ExifTags
        
        exif = img._getexif()
        if exif is None:
            return img
        
        orientation_key = None
        for key, value in ExifTags.TAGS.items():
            if value == 'Orientation':
                orientation_key = key
                break
        
        if orientation_key is None or orientation_key not in exif:
            return img
        
        orientation = exif[orientation_key]
        rotations = {
            3: lambda i: i.rotate(180, expand=True),
            6: lambda i: i.rotate(270, expand=True),
            8: lambda i: i.rotate(90, expand=True)
        }
        
        if orientation in rotations:
            return rotations[orientation](img)
        
        return img
    except Exception:
        return img


def resize_proportional(img: Image.Image, max_size: int) -> Image.Image:
    width, height = img.size
    
    if width >= height:
        new_width = min(width, max_size)
        new_height = int(height * (new_width / width))
    else:
        new_height = min(height, max_size)
        new_width = int(width * (new_height / height))
    
    return img.resize((new_width, new_height), Image.Resampling.LANCZOS)


def save_as_webp(img: Image.Image, quality: int) -> bytes:
    buffer = io.BytesIO()
    
    if img.mode not in ('RGB', 'RGBA'):
        img = img.convert('RGB')
    
    save_kwargs = {'quality': quality}
    
    if img.mode == 'RGBA':
        save_kwargs['lossless'] = True
        save_kwargs['method'] = 6
    
    img.save(buffer, format='WEBP', **save_kwargs)
    
    return buffer.getvalue()