#!/usr/bin/env python3
"""Cocokkan foto cache mili (25 Sep, batch Korea) dengan hasil frame Bukchon/Seoul
→ temukan mana yang SUDAH dipakai dan mana yang masih menganggur.

Cara: hasil frame = foto di-resize fit ke dalam box lalu ditempel di kanvas putih.
Jadi crop box dari hasil frame, kecilkan ke 16x16 grayscale, dan bandingkan dengan
signature yang sama dari foto sumber.
"""
import os, sys, json
import numpy as np
from PIL import Image

CACHE = "/home/mantapman/.hermes/profiles/mili/cache/images"
BUK = "/home/mantapman/.hermes/profiles/mili/workspace-mili/output/album_bukchon"
SEO = "/home/mantapman/.hermes/profiles/mili/workspace-mili/output/album_seoul_hujan"

BOX_L = (57, 21, 1542, 1011)     # landscape 1600x1202
BOX_P = (57, 100, 1023, 1549)    # portrait 1080x1920
N = 16


def sig_photo(path):
    """Signature 16x16 grayscale dari FOTO SAJA (bukan kanvas frame)."""
    im = Image.open(path).convert("RGB")
    landscape = im.width >= im.height
    box = BOX_L if landscape else BOX_P
    bw, bh = box[2] - box[0], box[3] - box[1]
    sc = min(bw / im.width, bh / im.height)
    im2 = im.resize((max(1, int(im.width * sc)), max(1, int(im.height * sc))), Image.LANCZOS)
    g = np.asarray(im2.convert("L").resize((N, N), Image.LANCZOS), dtype=float)
    return g


def sig_frame(path):
    """Signature dari hasil frame: crop box foto (isi kanvas sudah pas di box)."""
    im = Image.open(path).convert("RGB")
    box = BOX_L if im.width > im.height else BOX_P
    crop = im.crop(box)
    g = np.asarray(crop.convert("L").resize((N, N), Image.LANCZOS), dtype=float)
    return g


def dist(a, b):
    return float(np.abs(a - b).mean())


def main():
    cache = [f for f in sorted(os.listdir(CACHE)) if f.lower().endswith((".jpg", ".jpeg", ".png"))]
    frames = []
    for d, pre in ((BUK, "Bukchon"), (SEO, "Seoul")):
        if not os.path.isdir(d):
            continue
        for f in sorted(os.listdir(d)):
            if f.lower().endswith((".jpg", ".jpeg", ".png")):
                frames.append((d, f))
    print(f"cache: {len(cache)} foto | frame: {len(frames)} file")

    csig = {f: sig_photo(os.path.join(CACHE, f)) for f in cache}
    fsig = {f"{pre}/{f}": sig_frame(os.path.join(d, f)) for d, f in frames}

    used = {}          # frame -> (cache, jarak)
    for fname, fs in fsig.items():
        best, bd = None, 1e9
        for cname, cg in csig.items():
            d = dist(fs, cg)
            if d < bd:
                best, bd = cname, d
        used[fname] = (best, bd)

    print("\n== hasil pencocokan frame -> foto sumber (jarak rata-rata pixel 0-255) ==")
    for fname in sorted(used):
        c, d = used[fname]
        flag = "OK" if d < 12 else ("RAGU" if d < 25 else "??")
        print(f"  {flag:4s} {fname:24s} -> {c}  (d={d:.1f})")

    matched_cache = {v[0] for v in used.values() if v[1] < 25}
    sisa = [c for c in cache if c not in matched_cache]
    print(f"\n== foto cache yang TIDAK dipakai oleh frame Bukchon/Seoul: {len(sisa)} ==")
    for c in sisa:
        st = os.stat(os.path.join(CACHE, c))
        import datetime
        print(f"   {c}  {st.st_size/1e6:5.2f}MB  {datetime.datetime.fromtimestamp(st.st_mtime):%d %b %H:%M}  "
              f"size={Image.open(os.path.join(CACHE,c)).size}")
    json.dump({"mapping": {k: v[0] for k, v in used.items()},
               "dipakai": sorted(matched_cache), "sisa": sisa},
              open("/tmp/korea_foto_mapping.json", "w"), indent=2, ensure_ascii=False)
    print("\narsip: /tmp/korea_foto_mapping.json")


if __name__ == "__main__":
    main()
