import sys
import os
import base64
import io

# 解决 Windows 控制台中文输出问题
if sys.platform == "win32":
    sys.stdout.reconfigure(encoding="utf-8")

# 把项目根目录加入 sys.path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from PIL import Image
from stitch_core import stitch_images

OUTPUT_DIR = os.path.join(os.path.dirname(__file__), "output")
os.makedirs(OUTPUT_DIR, exist_ok=True)


def make_color_image(color: str, width: int = 100, height: int = 80) -> str:
    img = Image.new("RGB", (width, height), color)
    buf = io.BytesIO()
    img.save(buf, format="PNG")
    return base64.b64encode(buf.getvalue()).decode()


def save_result(result: dict, filename: str):
    img_data = base64.b64decode(result["image"])
    path = os.path.join(OUTPUT_DIR, filename)
    with open(path, "wb") as f:
        f.write(img_data)
    print(f"  saved: {path}")


def test_horizontal():
    print("Test: horizontal stitch...")
    red = make_color_image("red", 100, 80)
    blue = make_color_image("blue", 120, 80)
    result = stitch_images([red, blue], direction="horizontal", spacing=0)
    assert result["width"] == 220, f"width should be 220, got {result['width']}"
    assert result["height"] == 80, f"height should be 80, got {result['height']}"
    save_result(result, "horizontal.png")
    print("  [PASS] horizontal")


def test_vertical():
    print("Test: vertical stitch...")
    green = make_color_image("green", 100, 80)
    yellow = make_color_image("yellow", 100, 60)
    result = stitch_images([green, yellow], direction="vertical", spacing=10)
    assert result["width"] == 100, f"width should be 100, got {result['width']}"
    assert result["height"] == 150, f"height should be 150, got {result['height']}"
    save_result(result, "vertical.png")
    print("  [PASS] vertical")


def test_grid():
    print("Test: grid stitch...")
    imgs = [make_color_image(c, 50, 50) for c in ["red", "green", "blue", "yellow"]]
    result = stitch_images(imgs, direction="grid", columns=2, spacing=5)
    expected_w = 50 * 2 + 5 * 1  # 105
    expected_h = 50 * 2 + 5 * 1  # 105
    assert result["width"] == expected_w, f"width should be {expected_w}, got {result['width']}"
    assert result["height"] == expected_h, f"height should be {expected_h}, got {result['height']}"
    save_result(result, "grid.png")
    print("  [PASS] grid")


def test_resize_fit_width():
    print("Test: resize_mode=fit_width...")
    img1 = make_color_image("cyan", 100, 80)
    img2 = make_color_image("magenta", 60, 40)
    result = stitch_images([img1, img2], direction="horizontal", resize_mode="fit_width")
    # fit_width unifies to max width=100, result width = 100+100 = 200
    assert result["width"] == 200, f"width should be 200, got {result['width']}"
    save_result(result, "fit_width.png")
    print("  [PASS] fit_width")


def test_min_images_error():
    print("Test: error on < 2 images...")
    try:
        img = make_color_image("red")
        stitch_images([img], direction="horizontal")
        assert False, "Should raise ValueError"
    except ValueError as e:
        print(f"  [PASS] correct error: {e}")


if __name__ == "__main__":
    print("=== Image Stitcher Tests ===\n")
    test_horizontal()
    test_vertical()
    test_grid()
    test_resize_fit_width()
    test_min_images_error()
    print("\nAll tests passed!")
