"""
根据抠图结果裁剪多余的透明区域，同时保证整个文件夹内的图片尺寸一致
"""
import sys
import os
from glob import glob
import numpy as np
from PIL import Image

SUPPORTED_FORMATS = [".png", ".jpg", ".jpeg", ".webp", ".bmp", ".tiff", ".tif"]

def collect_image_files(folder):
    """收集文件夹中所有支持格式的图片路径"""
    image_paths = []
    for ext in SUPPORTED_FORMATS:
        image_paths.extend(glob(os.path.join(folder, f"*{ext}")))
        image_paths.extend(glob(os.path.join(folder, f"*{ext.upper()}")))
    # 去重并排序（Windows文件系统不区分大小写）
    return sorted(set(image_paths))

def compute_global_bbox(image_paths, alpha_threshold=0):
    """
    计算所有图片中非透明像素的全局 bounding box
    Returns: (left, top, right, bottom)
    """
    min_x = None
    min_y = None
    max_x = None
    max_y = None

    for path in image_paths:
        try:
            image = Image.open(path).convert("RGBA")
            alpha = np.array(image)[:, :, 3]
            mask = alpha > alpha_threshold
            if not np.any(mask):
                continue

            rows, cols = np.where(mask)
            left, right = int(cols.min()), int(cols.max())
            top, bottom = int(rows.min()), int(rows.max())

            min_x = left if min_x is None else min(min_x, left)
            min_y = top if min_y is None else min(min_y, top)
            max_x = right if max_x is None else max(max_x, right)
            max_y = bottom if max_y is None else max(max_y, bottom)
        except Exception as error:
            print(f"读取 {path} 时出错: {error}")

    if min_x is None or min_y is None or max_x is None or max_y is None:
        return None

    # PIL 的 crop 右下角是开区间，因此 +1
    return (min_x, min_y, max_x + 1, max_y + 1)

def crop_images(input_folder, output_folder):
    """裁剪输入文件夹中的图片并输出到指定文件夹"""
    print('\n' + '=' * 60)
    print('[Step 2/2] Smart Cropping')
    print('=' * 60)
    
    if not os.path.exists(input_folder):
        print(f"[X] Error: Input folder not found: {input_folder}")
        return 0

    print(f"-> Input folder: {input_folder}")
    
    image_paths = collect_image_files(input_folder)
    if not image_paths:
        print(f"[X] Error: No supported image files found")
        return 0

    print(f"[OK] Found {len(image_paths)} images")
    print(f"-> Computing global crop area...")

    bbox = compute_global_bbox(image_paths)
    if bbox is None:
        print("[X] Warning: No valid non-transparent pixels detected")
        return 0

    left, top, right, bottom = bbox
    target_width = right - left
    target_height = bottom - top

    print(f"[OK] Crop area: left={left}, top={top}, width={target_width}, height={target_height}")

    os.makedirs(output_folder, exist_ok=True)
    print(f"-> Output folder: {output_folder}")
    print('-' * 60)

    success = 0
    for idx, path in enumerate(image_paths, 1):
        try:
            filename = os.path.basename(path)
            print(f"[{idx}/{len(image_paths)}] Cropping: {filename}")
            print(f'PROGRESS: {idx}/{len(image_paths)}')
            
            image = Image.open(path).convert("RGBA")
            cropped = image.crop(bbox)

            # 确保裁剪后的尺寸一致
            if cropped.size != (target_width, target_height):
                fixed = Image.new("RGBA", (target_width, target_height), (0, 0, 0, 0))
                fixed.paste(cropped, (0, 0), cropped)
                cropped = fixed

            output_path = os.path.join(output_folder, filename)
            cropped.save(output_path, "PNG")
            print(f"    [OK] Done")
            success += 1
        except Exception as error:
            print(f"    [X] Failed: {error}")

    print('\n' + '=' * 60)
    print(f"[Step 2 Complete] Success: {success}/{len(image_paths)}")
    print('=' * 60)
    return success

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print("用法: python cut-mini-size.py <输入文件夹> <输出文件夹>")
        sys.exit(1)
    
    input_folder = sys.argv[1]
    output_folder = sys.argv[2]
    
    processed = crop_images(input_folder, output_folder)
    sys.exit(0 if processed > 0 else 1)
