#!/usr/bin/env python3
"""Cari & hapus tautan yang teksnya kosong setelah dibersihkan (termasuk spasi tak terlihat seperti &#8203;).

Jalankan tanpa argumen = uji. Dengan --go = kerjakan.
"""
import base64, json, re, sys, time, urllib.request

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
S = "https://studiosoft.id"
A = base64.b64encode(b"bambangbot:q26r RePo BVy6 pwU2 F3z7 ouyl").decode()
H = {"Authorization": f"Basic {A}", "User-Agent": "Mozilla/5.0", "Content-Type": "application/json"}
GO = "--go" in sys.argv
POLA = re.compile(r'<a\b[^>]*>(.*?)</a>', re.S)


def teks_jangkar(dalam):
    t = re.sub(r"<[^>]+>", "", dalam)
    t = (t.replace("&nbsp;", "").replace("&#8203;", "").replace("\u200b", "").replace("\ufeff", ""))
    return t.strip()


def rest(p, method="GET", payload=None, ulang=3):
    body = json.dumps(payload).encode() if payload is not None else None
    akhir = ""
    for i in range(ulang):
        try:
            r = urllib.request.Request(S + p, data=body, headers=H, method=method)
            with urllib.request.urlopen(r, timeout=150) as x:
                return json.loads(x.read())
        except Exception as e:
            akhir = str(e)[:40]
            time.sleep(5 + i * 5)
    raise RuntimeError(akhir)


daftar = []
for jenis in ("posts", "pages"):
    hal = 1
    while hal <= 12:
        try:
            d = rest(f"/wp-json/wp/v2/{jenis}?per_page=50&page={hal}&status=publish&_fields=id,slug")
        except Exception:
            break
        if not isinstance(d, list) or not d:
            break
        daftar += [(jenis, x["id"], x["slug"]) for x in d]
        if len(d) < 50:
            break
        hal += 1
print(f"memeriksa {len(daftar)} artikel/halaman")

cadangan, total, entri = {}, 0, 0
for i, (jenis, pid, slug) in enumerate(daftar, 1):
    try:
        isi = rest(f"/wp-json/wp/v2/{jenis}/{pid}?context=edit&_fields=content")["content"]["raw"]
    except Exception:
        continue
    temuan = [mo for mo in POLA.finditer(isi) if not teks_jangkar(mo.group(1))]
    if not temuan:
        continue
    baru = POLA.sub(lambda mo: "" if not teks_jangkar(mo.group(1)) else mo.group(0), isi)
    def bersih(h):
        t = re.sub(r"<[^>]+>", " ", h).replace("&nbsp;", " ").replace("\u200b", "")
        return re.sub(r"\s+", " ", t).strip()
    aman = bersih(isi) == bersih(baru)
    entri += 1
    total += len(temuan)
    print(f"   #{pid} [{jenis}] {slug[:44]:<46} {len(temuan)} tautan kosong · teks {'tetap' if aman else '⚠ BERUBAH'}")
    for mo in temuan[:2]:
        print(f"        {mo.group(0)[:120]}")
    cadangan[f"{jenis}:{pid}"] = isi
    if GO and aman:
        try:
            rest(f"/wp-json/wp/v2/{jenis}/{pid}", "POST", {"content": baru})
        except Exception as e:
            print(f"        gagal simpan: {e}")
        time.sleep(0.6)
    if i % 60 == 0:
        print(f"   … {i}/{len(daftar)}")

if GO:
    json.dump(cadangan, open(f"{WS}/ss_backup_tautan_kosong2.json", "w"), ensure_ascii=False)
    print(f"\n✅ {total} tautan kosong dihapus di {entri} entri · cadangan: ss_backup_tautan_kosong2.json")
else:
    print(f"\n(uji) {total} tautan kosong di {entri} entri. Pakai --go untuk mengerjakan.")
