#!/usr/bin/env python3
"""TSLaw: ubah judul SEO + meta description beranda (#833).
Metode: perbarui SEMUA baris meta (id disertakan) supaya tidak ada baris kembar yang menang.
Menyimpan salinan nilai lama dulu. Isi halaman (content) TIDAK disentuh."""
import base64, json, os, re, sys, time, urllib.request, urllib.error
from xml.sax.saxutils import escape

DOM = "tslaw.id"
USER, PASS = "bambangbot", "EFKm EYGx VQCP Y9go ncPr uM2Y"
AUTH = base64.b64encode(f"{USER}:{PASS}".encode()).decode()
UA = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124 Safari/537.36"}
PID = 833
BACKUP = "/home/mantapman/.hermes/profiles/atun/workspace/tslaw_pemulihan/yoast_beranda_lama.json"

JUDUL_BARU = "Tito Suprianto Law Firm | Law Firm Surabaya"
META_BARU = ("Law firm Surabaya untuk sengketa tanah, kontrak bisnis, merek dagang, dan legalitas usaha. "
             "Konsultasi gratis bersama advokat Tito Suprianto Law Firm.")


def rpc(method, params=()):
    def val(v):
        if isinstance(v, bool):
            return f"<value><boolean>{1 if v else 0}</boolean></value>"
        if isinstance(v, int):
            return f"<value><int>{v}</int></value>"
        if isinstance(v, list):
            return "<value><array><data>" + "".join(val(x) for x in v) + "</data></array></value>"
        if isinstance(v, dict):
            return "<value><struct>" + "".join(f"<member><name>{escape(str(k))}</name>{val(x)}</member>"
                                               for k, x in v.items()) + "</struct></value>"
        return f"<value><string>{escape(str(v))}</string></value>"
    body = ("<?xml version=\"1.0\"?><methodCall><methodName>" + method + "</methodName><params>" +
            "".join(f"<param>{val(p)}</param>" for p in params) + "</params></methodCall>").encode()
    r = urllib.request.Request(f"https://www.{DOM}/xmlrpc.php", data=body,
                               headers={"Content-Type": "text/xml", "User-Agent": "Mozilla/5.0",
                                        "Authorization": f"Basic {AUTH}"}, method="POST")
    for _ in range(3):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return x.status, x.read().decode("utf-8", "replace")
        except urllib.error.HTTPError as e:
            return e.code, e.read().decode("utf-8", "replace")[:250]
        except Exception:
            time.sleep(4)
    return 0, "gagal"


def baris_meta(isi, kunci):
    """Semua baris (id + nilai) untuk satu kunci meta."""
    return [(m.group(1), m.group(2)) for m in re.finditer(
        r"<member><name>id</name><value><string>(\d+)</string></value></member>\s*"
        r"<member><name>key</name><value><string>" + re.escape(kunci) +
        r"</string></value></member>\s*<member><name>value</name><value><string>(.*?)</string>", isi, re.S)]


def live():
    h = urllib.request.urlopen(urllib.request.Request(f"https://www.tslaw.id/?cek={int(time.time())}",
                                                      headers=UA), timeout=90).read().decode("utf-8", "replace")
    t = re.search(r"<title>(.*?)</title>", h, re.S)
    d = re.search(r'<meta name="description" content="([^"]*)"', h)
    return (t.group(1).strip() if t else "-"), (d.group(1).strip() if d else "-")


st, isi = rpc("wp.getPost", [1, USER, PASS, PID])
rows_title = baris_meta(isi, "_yoast_wpseo_title")
rows_desc = baris_meta(isi, "_yoast_wpseo_metadesc")
print(f"=== keadaan sekarang ({len(rows_title)} baris judul, {len(rows_desc)} baris meta) ===")
for i, v in rows_title:
    print(f"   judul id {i}: {v[:80]}")
for i, v in rows_desc:
    print(f"   meta  id {i}: {v[:80]}")
t_lama, d_lama = live()
print(f"\n   live sekarang → judul: {t_lama}\n                   meta : {d_lama[:90]}")

os.makedirs(os.path.dirname(BACKUP), exist_ok=True)
json.dump({"judul": rows_title, "metadesc": rows_desc, "live": [t_lama, d_lama]}, open(BACKUP, "w"), indent=1)
print(f"   salinan nilai lama: {BACKUP}")

print(f"\n=== rencana ===")
print(f"   judul baru ({len(JUDUL_BARU)} char): {JUDUL_BARU}")
print(f"   meta  baru ({len(META_BARU)} char): {META_BARU}")

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

print("\n=== menyimpan ===")
for kunci, baris, nilai in (("_yoast_wpseo_title", rows_title, JUDUL_BARU),
                            ("_yoast_wpseo_metadesc", rows_desc, META_BARU)):
    for mid, lama in baris:
        st, res = rpc("wp.editPost", [1, USER, PASS, PID,
                                      {"custom_fields": [{"id": int(mid), "key": kunci, "value": nilai}]}])
        ok = "<boolean>1</boolean>" in res
        print(f"   {kunci} id {mid} → HTTP {st} | {'✅' if ok else '❌ ' + res[:100]}")

print("\n=== verifikasi ===")
time.sleep(4)
st, isi2 = rpc("wp.getPost", [1, USER, PASS, PID])
for kunci in ("_yoast_wpseo_title", "_yoast_wpseo_metadesc"):
    nilai = [v for _, v in baris_meta(isi2, kunci)]
    unik = set(nilai)
    print(f"   {kunci}: {len(nilai)} baris | nilai unik: {len(unik)} → {list(unik)[:1]}")
t_baru, d_baru = live()
print(f"\n   live sekarang → judul: {t_baru}\n                   meta : {d_baru[:100]}")
print(f"\n   judul berubah: {'YA' if t_baru != t_lama else 'BELUM'}")
print(f"   meta berubah : {'YA' if d_baru != d_lama else 'BELUM'}")
