#!/usr/bin/env python3
"""DAS: ringankan gambar artikel — tambah srcset (agar ponsel tidak mengunduh versi penuh),
width/height (cegah tata letak bergeser), loading="lazy", dan decoding="async".

Pakai --apply untuk menulis; tiap artikel disalin dulu.
"""
import base64, json, os, re, sys, time, urllib.request, urllib.error, importlib.util

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
spec = importlib.util.spec_from_file_location("cfg_das", f"{WS}/cfg_das.py")
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
CFG = m.CFG
DOM, AUTH = CFG["domain"], base64.b64encode(f'{CFG["user"]}:{CFG["pass"]}'.encode()).decode()
UA = {"User-Agent": "Mozilla/5.0"}
BACKUP = f"{WS}/das_pemulihan/gambar"
os.makedirs(BACKUP, exist_ok=True)
PETA = json.load(open(f"{WS}/drafts/das_peta_media.json"))


def rest(p, method="GET", data=None):
    h = {"Authorization": f"Basic {AUTH}", **UA}
    body = None
    if data is not None:
        body = json.dumps(data).encode(); h["Content-Type"] = "application/json"
    r = urllib.request.Request(f"https://{DOM}{p}", data=body, headers=h, method=method)
    for _ in range(3):
        try:
            with urllib.request.urlopen(r, timeout=200) as x:
                return x.status, json.loads(x.read())
        except urllib.error.HTTPError as e:
            return e.code, e.read().decode()[:200]
        except Exception:
            time.sleep(5)
    return 0, "gagal"


def kunci_dari(u):
    k = u.split("?")[0].strip()
    if k.startswith("//"):
        k = "https:" + k
    elif k.startswith("/"):
        k = "https://dasindonesia.com" + k
    elif not k.startswith("http"):
        k = "https://dasindonesia.com/" + k.lstrip("/")
    return k.replace("http://dasindonesia.com", "https://dasindonesia.com")


def tambah_atribut(tag):
    """Kembalikan tag baru + keterangan perubahan."""
    src = re.search(r'src="([^"]+)"', tag)
    if not src:
        return tag, None
    info = PETA.get(kunci_dari(src.group(1)))
    ubah = []

    if info and info.get("w") and info.get("h"):
        # srcset dari ukuran yang tersedia (kecil → besar)
        if "srcset=" not in tag:
            calon = []
            for nama, s in (info.get("sizes") or {}).items():
                if s.get("w") and s.get("url") and nama != "full":
                    calon.append((s["w"], s["url"]))
            calon.append((info["w"], src.group(1)))
            calon = sorted({(w, u): None for w, u in calon}.keys())
            if len(calon) > 1:
                tag = tag.replace("<img", '<img srcset="' + ", ".join(f"{u} {w}w" for w, u in calon) + '"', 1)
                tag = tag.replace("<img", '<img sizes="(max-width: 768px) 100vw, 800px"', 1)
                ubah.append("srcset")
        if 'width="' not in tag:
            tag = tag.replace("<img", f'<img width="{info["w"]}"', 1)
            ubah.append("width")
        if 'height="' not in tag:
            tag = tag.replace("<img", f'<img height="{info["h"]}"', 1)
            ubah.append("height")

    if 'loading="' not in tag:
        tag = tag.replace("<img", '<img loading="lazy"', 1)
        ubah.append("lazy")
    if 'decoding="' not in tag:
        tag = tag.replace("<img", '<img decoding="async"', 1)
        ubah.append("decoding")

    if not re.search(r'alt="[^"]+"', tag) and info and info.get("alt"):
        tag = tag.replace("<img", f'<img alt="{info["alt"]}"', 1)
        ubah.append("alt")

    return tag, (ubah or None)


posts, page = [], 1
while True:
    st, d = rest(f"/wp-json/wp/v2/posts?per_page=100&page={page}&status=publish&context=edit&_fields=id,slug,content")
    if not isinstance(d, list):
        break
    posts += d
    if len(d) < 100:
        break
    page += 1

rencana = []
for p in posts:
    raw = p.get("content", {}).get("raw", "") or ""
    n = [0]

    def ganti(mm):
        baru, ubah = tambah_atribut(mm.group(0))
        if ubah:
            n[0] += 1
        return baru

    baru = re.sub(r"<img[^>]*>", ganti, raw, flags=re.I)
    if n[0]:
        rencana.append({"id": p["id"], "slug": p["slug"], "raw": raw, "baru": baru, "n": n[0]})

print(f"artikel yang gambarnya dibereskan: {len(rencana)} | gambar disentuh: {sum(r['n'] for r in rencana)}")
for r in rencana[:8]:
    print(f"   #{r['id']} /{r['slug'][:52]} ({r['n']} gambar)")
if not rencana:
    sys.exit(0)

if "--apply" not in sys.argv:
    print("(dry run — pakai --apply)")
    sys.exit(0)

ok = 0
for r in rencana:
    open(f"{BACKUP}/post_{r['id']}.txt", "w").write(r["raw"])
    rest(f"/wp-json/wp/v2/posts/{r['id']}", "POST", {"content": r["baru"]})
    _, cek = rest(f"/wp-json/wp/v2/posts/{r['id']}?context=edit&_fields=content")
    raw2 = cek.get("content", {}).get("raw", "") if isinstance(cek, dict) else ""
    sama = raw2 == r["baru"]
    ok += 1 if sama else 0
    print(f"   #{r['id']} {'✅' if sama else '⚠️'} | jumlah <img>: {len(re.findall('<img', raw2, re.I))} "
          f"| srcset: {len(re.findall('srcset=', raw2))} | lazy: {len(re.findall('loading=', raw2))}")
print(f"selesai: {ok}/{len(rencana)}")
