# pip install pillow
"""
yjm_png_rgba_fix.py

목적:
- Windows 탐색기에서 썸네일이 검정 배경으로 보이거나,
  팔레트(P) + transparency 형태의 PNG가 이상하게 보일 때,
  이를 RGBA truecolor PNG로 다시 저장해주는 프로그램.

기능:
1) 파일 또는 폴더 드래그앤드롭 실행 지원
2) 인자가 없으면 파일/폴더 선택창 표시
3) 기본값: 원본은 건드리지 않고 "_rgba_fixed" 폴더에 저장
4) 옵션 --overwrite 사용 시 원본 덮어쓰기 가능
5) 크기(예: 360x360)는 그대로 유지
6) 투명 배경(alpha)은 유지

사용 예:
- 파일 드래그:
    python yjm_png_rgba_fix.py "C:\\img\\01_또미_안녕.png"
- 폴더 드래그:
    python yjm_png_rgba_fix.py "C:\\img_folder"
- 원본 덮어쓰기:
    python yjm_png_rgba_fix.py --overwrite "C:\\img_folder"

주의:
- 이 프로그램은 "배경 제거" AI가 아닙니다.
- 이미 있는 투명 배경(alpha)을 정상적인 RGBA PNG로 재저장하는 용도입니다.
"""

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


SUPPORTED = {".png"}


def normalize_drop_path(p: str) -> str:
    """Windows 드래그앤드롭 경로의 중괄호/따옴표 제거."""
    p = p.strip().strip('"').strip("'")
    if p.startswith("{") and p.endswith("}"):
        p = p[1:-1]
    return p


def gather_pngs(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("*.png"):
                rp = f.resolve()
                if rp not in seen:
                    files.append(rp)
                    seen.add(rp)

    return sorted(files)


def has_palette_transparency(img: Image.Image) -> bool:
    return img.mode == "P" and ("transparency" in img.info)


def convert_one(src: Path, overwrite: bool = False):
    try:
        with Image.open(src) as im:
            original_mode = im.mode
            original_size = im.size

            # RGBA 변환
            rgba = im.convert("RGBA")

            # 저장 위치
            if overwrite:
                dst = src
            else:
                out_dir = src.parent / "_rgba_fixed"
                out_dir.mkdir(parents=True, exist_ok=True)
                dst = out_dir / src.name

            rgba.save(dst, format="PNG", optimize=True)

        return {
            "ok": True,
            "src": str(src),
            "dst": str(dst),
            "mode_before": original_mode,
            "size": original_size,
            "palette_fix": original_mode == "P",
        }
    except Exception as e:
        return {
            "ok": False,
            "src": str(src),
            "error": str(e),
        }


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

    answer = messagebox.askyesno(
        "PNG RGBA Fix",
        "폴더 전체를 처리할까요?\n\n예 = 폴더 선택\n아니오 = PNG 파일 여러 개 선택"
    )

    if answer:
        folder = filedialog.askdirectory(title="PNG 폴더 선택")
        root.destroy()
        return [folder] if folder else []
    else:
        files = filedialog.askopenfilenames(
            title="PNG 파일 선택",
            filetypes=[("PNG files", "*.png")]
        )
        root.destroy()
        return list(files)


def main():
    overwrite = False
    raw_args = []

    for a in sys.argv[1:]:
        if a == "--overwrite":
            overwrite = True
        else:
            raw_args.append(a)

    if not raw_args:
        raw_args = ask_paths()

    files = gather_pngs(raw_args)

    if not files:
        print("처리할 PNG 파일이 없습니다.")
        try:
            root = tk.Tk()
            root.withdraw()
            messagebox.showwarning("PNG RGBA Fix", "처리할 PNG 파일이 없습니다.")
            root.destroy()
        except Exception:
            pass
        return

    print(f"총 {len(files)}개 PNG 처리 시작")
    print(f"저장 방식: {'원본 덮어쓰기' if overwrite else '_rgba_fixed 폴더에 저장'}")
    print("-" * 70)

    ok_count = 0
    fail_count = 0
    fixed_palette_count = 0

    for src in files:
        result = convert_one(src, overwrite=overwrite)
        if result["ok"]:
            ok_count += 1
            if result["palette_fix"]:
                fixed_palette_count += 1
            print(
                f"[완료] {Path(result['src']).name} | "
                f"mode: {result['mode_before']} -> RGBA | "
                f"size: {result['size'][0]}x{result['size'][1]}"
            )
        else:
            fail_count += 1
            print(f"[실패] {Path(result['src']).name} | {result['error']}")

    print("-" * 70)
    print(f"완료: {ok_count}개, 실패: {fail_count}개")
    print(f"P 모드(팔레트)에서 RGBA로 변환된 파일 수: {fixed_palette_count}개")

    try:
        root = tk.Tk()
        root.withdraw()
        messagebox.showinfo(
            "PNG RGBA Fix 완료",
            f"완료: {ok_count}개\n실패: {fail_count}개\n"
            f"P 모드 -> RGBA 변환: {fixed_palette_count}개\n\n"
            f"{'원본 덮어쓰기' if overwrite else '_rgba_fixed 폴더에 저장 완료'}"
        )
        root.destroy()
    except Exception:
        pass


if __name__ == "__main__":
    main()
