#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""RSIA: pastikan semua featured image == webp max 1000x567.
Alur: list post->featured, untuk tiap featured yg belum sesuai (bukan webp ATAU >1000x567):
  unduh -> resize keep aspect (max dim 1000 x 567) -> konversi webp -> upload REST
  -> set featured_media post. Log ringkas, aman (tidak hapus gambar lama).
Catatan: REST upload 401 untuk user editor via app password; gunakan jalur yang bisa.
Kita coba REST upload dulu; kalau 401, fallback Playwright async-upload per file.
"""
import os, sys, io, json, time, base64
import urllib.request
from PIL import Image

BASE="https://rsia.kendangsari.com"
USER="bambangbot"
APPPASS="INJ6 7ag4 iouR Fqkm 4alp Dkng"
PW="C00l_man&314554"
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120 Safari/537.36"
MAXW,MAXH=1000,567
WORK="/tmp/rsia_norm"
os.makedirs(WORK,exist_ok=True)
LOG=f"{WORK}/log.txt"

def log(*a):
    line=" ".join(str(x) for x in a)
    print(line,flush=True)
    with open(LOG,'a') as f: f.write(line+"\n")

def rest(url, method="GET", body=None, ctype=None, timeout=60):
    tok=base64.b64encode(f"{USER}:{APPPASS}".encode()).decode()
    data=None; hdr={"Authorization":"Basic "+tok,"User-Agent":UA,"Accept":"application/json"}
    if body is not None:
        data=body
        if ctype: hdr["Content-Type"]=ctype
    req=urllib.request.Request(url, data=data, method=method, headers=hdr)
    with urllib.request.urlopen(req,timeout=timeout) as r:
        return json.loads(r.read())

def process_image(src_url, out_path):
    """resize (keep aspect, fit within 1000x567) lalu convert webp (lossless off)."""
    raw=urllib.request.urlopen(urllib.request.Request(src_url,headers={"User-Agent":UA}),
                               timeout=90).read()
    im=Image.open(io.BytesIO(raw))
    im=im.convert("RGB")
    w,h=im.size
    # fit dalam 1000x567 tanpa mengubah proporsi
    scale=min(MAXW/w, MAXH/h, 1.0)
    if scale<1.0:
        nw,nhe=max(1,int(w*scale)),max(1,int(h*scale))
        im=im.resize((nw,nhe), Image.LANCZOS)
    im.save(out_path,"WEBP",quality=85,method=6)
    return im.size, os.path.getsize(out_path)

def rest_upload(path, filename):
    """Upload via REST. Return (ok,media_id or err)."""
    try:
        with open(path,'rb') as f: raw=f.read()
        return rest(f"{BASE}/wp-json/wp/v2/media", "POST", raw,
                    ctype="image/webp")["id"]
    except Exception as e:
        return ("ERR", str(e)[:120])

def main():
    if os.path.exists(LOG): os.remove(LOG)
    # 1. kumpulkan featured image
    posts=json.load(open('/tmp/posts_p1.json'))
    featmap={}  # media_id -> list post
    for p in posts:
        fm=p.get('featured_media')
        if fm: featmap.setdefault(fm,[]).append(p['id'])
    # 2. detail media untuk semua featured
    detail={}
    try:
        media_all=json.load(open('/tmp/media_p1.json'))+json.load(open('/tmp/media_p2.json'))
        for m in media_all: detail[int(m['id'])]=m
    except Exception as e:
        log("media cache load err",e)
    log("post dgn featured:",len(featmap),"| media cached:",len(detail))

    todo=[]  # (media_id, w,h,mime,src, [posts])
    for fid,posts_ in featmap.items():
        m=detail.get(fid)
        if not m:
            # featured id merujuk media yg belum ke-cache (page lanjutan) -> catat utk cek
            todo.append((fid,None,None,None,None,posts_)); continue
        det=m.get('media_details') or {}
        w=det.get('width'); h=det.get('height'); mt=m.get('mime_type'); src=m.get('source_url')
        ok = (mt=='image/webp' and w and h and w<=MAXW and h<=MAXH)
        if not ok:
            todo.append((fid,w,h,mt,src,posts_))
    log("perlu difix:",len(todo))

    done=[]; fail=[]
    for fid,w,h,mt,src,posts_ in todo:
        if not src:
            log(f"  {fid}: featured id tak ada di cache (mungkin media id salah). posts={posts_}")
            fail.append((fid,"no-src")); 
            # coba fetch detail langsung
            try:
                d=rest(f"{BASE}/wp-json/wp/v2/media/{fid}")
                m=d.get('mime_type'); det=d.get('media_details') or {}
                src=d.get('source_url'); w=det.get('width'); h=det.get('height')
                if src and (m!='image/webp' or w>MAXW or h>MAXH):
                    posts_.append(fid)
                else:
                    m=src
            except Exception as e:
                log(f"    fetch err {e}")
                continue
        try:
            outp=f"{WORK}/{fid}.webp"
            newsize,size=process_image(src,outp)
            newid=rest_upload(outp,f"{fid}.webp")
            if isinstance(newid,int):
                # set featured_media utk semua post terkait
                for pid in posts_:
                    try:
                        rest(f"{BASE}/wp-json/wp/v2/posts/{pid}","POST",json.dumps({"featured_media":newid}).encode(),"application/json")
                    except Exception as e:
                        fail.append((fid,"setfm",str(e)[:60]))
                done.append((fid,newid,newsize))
                log(f"  OK media {fid} -> new {newid} {newsize} webp (post {posts_})")
            else:
                fail.append((fid,"upload",newid))
                log(f"  FAIL media {fid} upload err: {newid}")
        except Exception as e:
            fail.append((fid,str(e)[:80])); log(f"  FAIL media {fid}: {str(e)[:80]}")
        time.sleep(0.5)

    log("\n=== HASIL ===")
    log("berhasil:",len(done),"| gagal:",len(fail))
    for x in fail: log("  fail:",x)

sys.exit(main() if __name__=="__main__" else 0)
