# 阿里云OSS服务
import os
import uuid
import datetime
from typing import Optional
import oss2
from PIL import Image
import io

# OSS配置
OSS_CONFIG = {
    "access_key_id": os.getenv("OSS_ACCESS_KEY_ID", "LTAI5t6HUnpFBLEK9194kPVG"),
    "access_key_secret": os.getenv("OSS_ACCESS_KEY_SECRET", "LEr4Q8yRxb8D5b24cKfCwlt4MMoke1"),
    "bucket_name": "jiachenlong-oss",
    "endpoint": "oss-cn-hangzhou.aliyuncs.com",
    "public_url": "https://jiachenlong-oss.oss-cn-hangzhou.aliyuncs.com"
}

# 图片压缩配置
IMAGE_CONFIG = {
    "max_size": 1024 * 1024,  # 1MB
    "max_width": 2048,
    "max_height": 2048,
    "quality": 85,
    "format": "JPEG"
}

# 初始化OSS
auth = oss2.Auth(OSS_CONFIG["access_key_id"], OSS_CONFIG["access_key_secret"])
bucket = oss2.Bucket(auth, OSS_CONFIG["endpoint"], OSS_CONFIG["bucket_name"])


def get_oss_path(prefix: str, user_id: str = None, filename: str = None) -> str:
    """生成OSS存储路径"""
    now = datetime.datetime.now()
    year = now.strftime("%Y")
    month = now.strftime("%m")
    day = now.strftime("%d")
    
    if filename:
        ext = filename.split('.')[-1] if '.' in filename else 'jpg'
        unique_name = f"{uuid.uuid4().hex}.{ext}"
    else:
        unique_name = f"{uuid.uuid4().hex}.jpg"
    
    if user_id:
        path = f"{prefix}/{user_id}/{year}/{month}/{unique_name}"
    else:
        path = f"{prefix}/{year}/{month}/{day}/{unique_name}"
    
    return path, unique_name


def upload_to_oss(file_data: bytes, oss_key: str, compress: bool = True) -> str:
    """上传文件到OSS，返回公网URL"""
    try:
        # 如果是图片，进行压缩
        if compress and any(oss_key.lower().endswith(ext) for ext in ['.jpg', '.jpeg', '.png', '.webp']):
            file_data = compress_image(file_data)
        
        # 上传文件
        result = bucket.put_object(oss_key, file_data)
        
        if result.status == 200:
            # 返回公网URL
            return f"{OSS_CONFIG['public_url']}/{oss_key}"
        else:
            raise Exception(f"OSS上传失败: {result.status}")
            
    except Exception as e:
        raise Exception(f"OSS上传失败: {str(e)}")


def delete_from_oss(oss_key: str) -> bool:
    """从OSS删除文件"""
    try:
        result = bucket.delete_object(oss_key)
        return result.status == 204
    except Exception as e:
        print(f"OSS删除失败: {str(e)}")
        return False


def get_public_url(oss_key: str) -> str:
    """获取公网URL"""
    return f"{OSS_CONFIG['public_url']}/{oss_key}"


def compress_image(image_data: bytes, max_size: int = None) -> bytes:
    """压缩图片到指定大小以内"""
    if max_size is None:
        max_size = IMAGE_CONFIG["max_size"]
    
    # 如果已经小于限制，直接返回
    if len(image_data) <= max_size:
        return image_data
    
    # 打开图片
    img = Image.open(io.BytesIO(image_data))
    
    # 如果是PNG且有透明通道，转换为RGB
    if img.mode in ('RGBA', 'P'):
        img = img.convert('RGB')
    
    # 逐步降低质量直到达到目标大小
    quality = 95
    compressed_data = image_data
    
    while quality > 30 and len(compressed_data) > max_size:
        output = io.BytesIO()
        img.save(output, format=IMAGE_CONFIG["format"], quality=quality, optimize=True)
        compressed_data = output.getvalue()
        quality -= 10
    
    # 如果还是太大，缩小尺寸
    if len(compressed_data) > max_size:
        width, height = img.size
        while len(compressed_data) > max_size and width > 400:
            width = int(width * 0.8)
            height = int(height * 0.8)
            img_resized = img.resize((width, height), Image.Resampling.LANCZOS)
            output = io.BytesIO()
            img_resized.save(output, format=IMAGE_CONFIG["format"], quality=80, optimize=True)
            compressed_data = output.getvalue()
    
    return compressed_data
