# pip install pillow
"""
yjm_img_to_360.py

목적:
- 큰 이미지를 360x360 규격으로 자동 변환
- PNG / JPG / JPEG / WEBP 지원
- 파일 또는 폴더 드래그앤드롭 가능
- 기본은 원본을 건드리지 않고 "_360x360" 폴더에 저장

기본 동작:
1) 투명 여백이 있는 PNG는 여백을 자동으로 잘라냄
2) 원본 비율은 유지
3) 360x360 캔버스 중앙에 배치
4) 출력은 PNG
5) 배경은 기본 투명
"""

import sys
from pathlib import Path
from PIL import Image
import tkinter as tk
from tkinter import filedialog, messagebox

SUPPORTED = {".png", ".jpg", ".jpeg", ".webp"}


def normalize_drop_path(p: str) -> str:
    p = p.strip().strip('"').strip("'")
    if p.startswith("{") and p.endswith("}"):
        p = p[1:-1]
    return p


def gather_images(paths):
    files = []
    seen = set()

    for raw in paths:
        raw = normalize_drop_path(str(raw))
        if not raw:
            continue

        p = Path(raw)
        if not p.exists():
            print(f"[경고] 경로 없음: {p}")
            continue

        if p.is_file() and p.suffix.lower() in SUPPORTED:
            rp = p.resolve()
            if rp not in seen:
                files.append(rp)
                seen.add(rp)

        elif p.is_dir():
            for f in p.rglob("*"):
                if f.is_file() and f.suffix.lower() in SUPPORTED:
                    rp = f.resolve()
                    if rp not in seen:
                        files.append(rp)
                        seen.add(rp)

    return sorted(files)


def crop_transparent_bbox(im: Image.Image) -> Image.Image:
    if im.mode != "RGBA":
        im = im.convert("RGBA")
    alpha = im.getchannel("A")
    bbox = alpha.getbbox()
    if bbox:
        return im.crop(bbox)
    return im


def make_360_image(src: Path, out_dir: Path, canvas_size=360, padding=4):
    with Image.open(src) as im:
        has_alpha = "A" in im.getbands() or im.mode in ("RGBA", "LA", "PA")
        im = im.convert("RGBA")

        # 투명 여백 자동 크롭
        im = crop_transparent_bbox(im)

        avail = canvas_size - (padding * 2)
        scale = min(avail / im.width, avail / im.height)
        new_w = max(1, int(round(im.width * scale)))
        new_h = max(1, int(round(im.height * scale)))

        resized = im.resize((new_w, new_h), Image.Resampling.LANCZOS)

        # 배경: 알파 있으면 투명, 아니면 흰색
        if has_alpha:
            canvas = Image.new("RGBA", (canvas_size, canvas_size), (0, 0, 0, 0))
        else:
            canvas = Image.new("RGBA", (canvas_size, canvas_size), (255, 255, 255, 255))

        x = (canvas_size - new_w) // 2
        y = (canvas_size - new_h) // 2
        canvas.alpha_composite(resized, (x, y))

        out_dir.mkdir(parents=True, exist_ok=True)
        out_name = src.stem + ".png"
        out_path = out_dir / out_name
        canvas.save(out_path, format="PNG", optimize=True)

        return out_path, canvas.size


def ask_paths():
    root = tk.Tk()
    root.withdraw()

    answer = messagebox.askyesno(
        "360x360 변환",
        "폴더 전체를 처리할까요?\n\n예 = 폴더 선택\n아니오 = 이미지 파일 여러 개 선택"
    )

    if answer:
        folder = filedialog.askdirectory(title="이미지 폴더 선택")
        root.destroy()
        return [folder] if folder else []
    else:
        files = filedialog.askopenfilenames(
            title="이미지 파일 선택",
            filetypes=[
                ("Image files", "*.png;*.jpg;*.jpeg;*.webp"),
                ("PNG", "*.png"),
                ("JPG", "*.jpg;*.jpeg"),
                ("WEBP", "*.webp"),
            ]
        )
        root.destroy()
        return list(files)


def main():
    raw_args = sys.argv[1:]
    if not raw_args:
        raw_args = ask_paths()

    files = gather_images(raw_args)
    if not files:
        print("처리할 이미지가 없습니다.")
        try:
            root = tk.Tk()
            root.withdraw()
            messagebox.showwarning("360x360 변환", "처리할 이미지가 없습니다.")
            root.destroy()
        except Exception:
            pass
        return

    print(f"총 {len(files)}개 처리 시작")
    print("-" * 70)

    ok_count = 0
    fail_count = 0

    for src in files:
        try:
            out_dir = src.parent / "_360x360"
            out_path, out_size = make_360_image(src, out_dir)
            ok_count += 1
            print(f"[완료] {src.name} -> {out_path.name} | {out_size[0]}x{out_size[1]}")
        except Exception as e:
            fail_count += 1
            print(f"[실패] {src.name} | {e}")

    print("-" * 70)
    print(f"완료: {ok_count}개, 실패: {fail_count}개")

    try:
        root = tk.Tk()
        root.withdraw()
        messagebox.showinfo(
            "360x360 변환 완료",
            f"완료: {ok_count}개\n실패: {fail_count}개\n\n"
            f"각 원본 폴더 아래 '_360x360' 폴더에 저장되었습니다."
        )
        root.destroy()
    except Exception:
        pass


if __name__ == "__main__":
    main()
