#!/usr/bin/env python3
"""TSLaw: buat artikel ketiga (draft) — 8 Pengacara & Konsultan Hukum Sengketa Tanah dan Sertifikat di Surabaya.
Tahapan: siapkan foto (crop 1000x567 webp) → unggah media + alt → buat post draft (REST, JSON) →
meta Yoast (REST; XML-RPC hanya kalau REST tidak menyimpan) → verifikasi baca ulang.
Jalankan tanpa argumen = dry run; dengan --apply = benar-benar membuat di WordPress."""
import base64, json, os, re, sys, time, urllib.request, urllib.error
from xml.sax.saxutils import escape
from PIL import Image

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from tslaw_listikel_3 import A3

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"}
OUT = "/home/mantapman/.hermes/profiles/atun/workspace/tslaw_listikel"
KATEGORI = [14]          # Hukum Bisnis
TUJUAN = (1000, 567)
SALINAN = f"{OUT}/artikel3.html"


def rest(path, 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}{path}", data=body, headers=h, method=method)
    for i in range(4):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return x.status, json.loads(x.read())
        except urllib.error.HTTPError as e:
            return e.code, e.read().decode()[:300]
        except Exception as e:
            print(f"    (ulang {i+1}: {str(e)[:60]})")
            time.sleep(8)
    return 0, "gagal"


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(6)
    return 0, "gagal"


def potong_foto(pexels_id, nama):
    u = f"https://images.pexels.com/photos/{pexels_id}/pexels-photo-{pexels_id}.jpeg?auto=compress&cs=tinysrgb&w=1400"
    data = urllib.request.urlopen(urllib.request.Request(u, headers=UA), timeout=120).read()
    tmp = f"{OUT}/_tmp_{nama}.jpg"
    open(tmp, "wb").write(data)
    im = Image.open(tmp).convert("RGB")
    tw, th = TUJUAN
    w, h = im.size
    r = tw / th
    im = im.crop(((w - int(h * r)) // 2, 0, (w - int(h * r)) // 2 + int(h * r), h)) if w / h > r else \
         im.crop((0, (h - int(w / r)) // 2, w, (h - int(w / r)) // 2 + int(w / r)))
    f = f"{OUT}/{nama}"
    im.resize(TUJUAN, Image.LANCZOS).save(f, "WEBP", quality=90)
    os.remove(tmp)
    return f


def tulis_meta(pid, a, laporan):
    """Coba REST dulu; kalau nilai tidak tersimpan, pakai XML-RPC custom_fields."""
    st, r = rest(f"/wp-json/wp/v2/posts/{pid}", "POST", {"meta": {
        "_yoast_wpseo_focuskw": a["fokus"], "_yoast_wpseo_title": a["seo"],
        "_yoast_wpseo_metadesc": a["meta"]}})
    st2, c = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=meta")
    m = c.get("meta", {}) if isinstance(c, dict) else {}
    if m.get("_yoast_wpseo_focuskw") == a["fokus"]:
        laporan.append(f"  meta Yoast via REST  : tersimpan (HTTP {st})")
        return True
    st3, isi = rpc("wp.editPost", [1, USER, PASS, pid, {"custom_fields": [
        {"key": "_yoast_wpseo_focuskw", "value": a["fokus"]},
        {"key": "_yoast_wpseo_title", "value": a["seo"]},
        {"key": "_yoast_wpseo_metadesc", "value": a["meta"]}]}])
    ok = "<boolean>1</boolean>" in isi
    laporan.append(f"  meta Yoast           : REST gagal ({str(m)[:60]}) → XML-RPC HTTP {st3} "
                   f"{'tersimpan' if ok else 'GAGAL ' + isi[:100]}")
    return ok


def main():
    a = A3
    laporan = []
    teks = re.sub(r"<(script|style)[^>]*>.*?</\1>", " ", a["isi"], flags=re.S | re.I)
    kata = len([w for w in re.split(r"\s+", re.sub(r"<[^>]+>", " ", teks)) if w])
    print(f"=== PERSIAPAN ===\n  {a['slug']} | {kata} kata | meta {len(a['meta'])} char | judul SEO {len(a['seo'])} char")
    assert kata >= 1000, "kurang dari 1000 kata"
    assert len(a["meta"]) <= 158, "meta lebih dari 158"
    assert a["fokus"].lower() in a["meta"].lower(), "keyphrase tidak ada di meta"
    assert a["meta"].lower().startswith(a["fokus"].split()[0].lower()), "keyphrase tidak di awal meta"
    assert os.path.exists(SALINAN), "salinan lokal belum dibuat"
    print(f"  salinan isi lokal    : {SALINAN} ({os.path.getsize(SALINAN)} byte)")

    foto = potong_foto("8815843", a["slug"] + ".webp")
    print(f"  foto siap            : {foto} ({os.path.getsize(foto)//1024} KB) "
          f"{Image.open(foto).size}")

    if "--apply" not in sys.argv:
        print("\n(dry run — pakai --apply untuk membuat di WordPress)")
        return

    # 1. slug sudah dipakai?
    st, ada = rest(f"/wp-json/wp/v2/posts?slug={a['slug']}&status=any&_fields=id,slug,status,link")
    if isinstance(ada, list) and ada:
        print(f"\n  ⚠ slug sudah ada: {ada} → hentikan supaya tidak menimpa")
        return
    print(f"\n=== SLUG ===\n  {a['slug']} bebas dipakai")

    # 2. tag: cari yang sudah ada, buat yang belum
    st, semua = rest("/wp-json/wp/v2/tags?per_page=100&orderby=count&order=desc&_fields=id,name,slug,count")
    peta = {t["name"].lower(): t for t in semua} if isinstance(semua, list) else {}
    print("\n=== TAG ===")
    print("  tersedia (top 12): " + ", ".join(f"{t['id']}={t['name']}" for t in semua[:12]))
    tag_ids = []
    for nama in a["tag_nama"]:
        t = peta.get(nama.lower())
        if t:
            tag_ids.append(t["id"])
            print(f"  pakai   {nama:<20} #{t['id']} ({t['count']} artikel)")
        else:
            st, baru = rest("/wp-json/wp/v2/tags", "POST", {"name": nama})
            if isinstance(baru, dict) and "id" in baru:
                tag_ids.append(baru["id"])
                print(f"  buat    {nama:<20} #{baru['id']}")
            else:
                print(f"  GAGAL   {nama}: {str(baru)[:120]}")
    print(f"  tag dipakai: {tag_ids}")

    # 3. unggah foto + alt
    print("\n=== FOTO ===")
    h = {"Authorization": f"Basic {AUTH}", **UA, "Content-Type": "image/webp",
         "Content-Disposition": f'attachment; filename="{a["slug"]}.webp"'}
    req = urllib.request.Request(f"https://{DOM}/wp-json/wp/v2/media", data=open(foto, "rb").read(),
                                 headers=h, method="POST")
    try:
        with urllib.request.urlopen(req, timeout=240) as x:
            med = json.loads(x.read())
    except urllib.error.HTTPError as e:
        print(f"  GAGAL unggah foto: {e.code} {e.read().decode()[:200]}")
        return
    mid = med["id"]
    alt = "Menandatangani dokumen pertanahan bersama pengacara sengketa tanah Surabaya"
    rest(f"/wp-json/wp/v2/media/{mid}", "POST", {"alt_text": alt, "title": a["judul"]})
    st, cek = rest(f"/wp-json/wp/v2/media/{mid}?context=edit&_fields=id,alt_text,source_url")
    print(f"  media #{mid} → {med.get('source_url')}")
    print(f"  alt tersimpan: {'ya' if (isinstance(cek, dict) and cek.get('alt_text') == alt) else 'TIDAK — ' + str(cek)[:80]}")

    # 4. buat artikel draft
    print("\n=== ARTIKEL (draft) ===")
    payload = {"title": a["judul"], "slug": a["slug"], "content": a["isi"], "status": "draft",
               "categories": KATEGORI, "tags": tag_ids, "featured_media": mid,
               "excerpt": a["meta"]}
    st, p = rest("/wp-json/wp/v2/posts", "POST", payload)
    if st not in (200, 201):
        print(f"  GAGAL buat artikel: {st} {str(p)[:300]}")
        return
    pid = p["id"]
    print(f"  artikel #{pid} dibuat → {p.get('link')}  (status: {p.get('status')})")

    # 5. meta Yoast
    print("\n=== META YOAST ===")
    tulis_meta(pid, a, laporan)
    for baris in laporan:
        print(baris)

    # 6. verifikasi baca ulang
    print("\n=== VERIFIKASI (baca ulang via REST) ===")
    st, c = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=id,slug,link,status,content,title,"
                 f"categories,tags,featured_media,meta")
    raw = c.get("content", {}).get("raw", "") if isinstance(c, dict) else ""
    teks2 = re.sub(r"<(script|style)[^>]*>.*?</\1>", " ", raw, flags=re.S | re.I)
    kata2 = len([w for w in re.split(r"\s+", re.sub(r"<[^>]+>", " ", teks2)) if w])
    print(f"  #{pid} {c.get('status')} | {len(raw)} char | {kata2} kata")
    print(f"  slug        : {c.get('slug')}  (link: {c.get('link')})")
    print(f"  kategori    : {c.get('categories')} (Hukum Bisnis = 14)")
    print(f"  tag         : {len(c.get('tags', []))} buah → {c.get('tags')}")
    print(f"  foto utama  : media #{c.get('featured_media')}")
    print(f"  tombol WA   : {'ada' if 'wa.me/6281909222026' in raw else 'TIDAK'}")
    print(f"  FAQPage     : {'ada' if 'FAQPage' in raw else 'TIDAK'}")
    print(f"  tautan beranda TS Law : {'ada' if 'https://www.tslaw.id/' in raw else 'TIDAK'}")
    print(f"  meta tersimpan: {json.dumps(c.get('meta', {}), ensure_ascii=False)[:220]}")
    print(f"\n  LAPORAN: judul={a['judul']}")
    print(f"           url draft={c.get('link')}")
    print(f"           kata={kata2} | keyphrase={a['fokus']} | meta={len(a['meta'])} char")


if __name__ == "__main__":
    main()
