#!/usr/bin/env python3
"""Pasang tombol WhatsApp "Konsultasi Gratis" di SEMUA artikel StudioSoft yang belum punya.
Idempoten. Dry run default; --apply untuk eksekusi."""
import base64, json, re, sys, time, urllib.request, urllib.error

S = "https://studiosoft.id"
AUTH = base64.b64encode(b"bambangbot:q26r RePo BVy6 pwU2 F3z7 ouyl").decode()
WA = "https://wa.me/6281935000624?text=Halo%20StudioSoft%2C%20saya%20ingin%20konsultasi%20gratis%20untuk%20bisnis%20saya"
ICON = ('<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="#ffffff" aria-hidden="true">'
        '<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164'
        '-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458'
        '.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207'
        '-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 '
        '1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.872.118'
        '.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 '
        '9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 '
        '9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884'
        'm8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335 .157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654'
        'a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg>')

BLOK = f"""
<style>
.ss-cta-wa{{display:inline-flex;align-items:center;gap:10px;background-color:#6878d6;color:#ffffff !important;
font-family:'Open Sans',sans-serif;font-weight:600;font-size:17px;padding:15px 30px;border-radius:8px;
text-decoration:none !important;line-height:1.2;box-shadow:0 2px 8px rgba(104,120,214,.35)}}
.ss-cta-wa:hover{{background-color:#4d61d6;color:#ffffff !important}}
</style>
<p style="text-align:center;margin:34px 0 6px">
<a class="ss-cta-wa" href="{WA}" target="_blank" rel="noopener" role="button">{ICON}<span>WhatsApp: Konsultasi Gratis</span></a>
</p>
<p style="text-align:center;font-size:14px;color:#5b5b6b;margin:0 0 26px">Dibalas langsung oleh tim StudioSoft, tanpa biaya dan tanpa komitmen.</p>
"""


def api(path, data=None):
    h = {"Authorization": f"Basic {AUTH}", "User-Agent": "Mozilla/5.0"}
    body = None
    if data is not None:
        body = json.dumps(data).encode(); h["Content-Type"] = "application/json"
    r = urllib.request.Request(S + path, data=body, headers=h, method="POST" if data else "GET")
    for coba 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:
            pesan = e.read().decode()[:200]
            if e.code in (404, 500, 502, 503, 504):
                time.sleep(3); continue
            return e.code, pesan
        except Exception as e:
            time.sleep(3)
            terakhir = f"{type(e).__name__}: {e}"
    return 0, terakhir


posts, page = [], 1
while True:
    st, d = api(f"/wp-json/wp/v2/posts?per_page=100&page={page}&context=edit&_fields=id,title,content,link")
    if not isinstance(d, list):
        print("gagal ambil halaman", page, str(d)[:120]); break
    posts += d
    if len(d) < 100:
        break
    page += 1

sudah = [p for p in posts if isinstance(p["content"], dict) and "ss-cta-wa" in p["content"]["raw"]]
belum = [p for p in posts if isinstance(p["content"], dict) and "ss-cta-wa" not in p["content"]["raw"]]
print(f"total artikel publish : {len(posts)}")
print(f"sudah ada tombol      : {len(sudah)}")
print(f"belum ada tombol      : {len(belum)}")
for p in belum[:10]:
    print("   -", p["title"]["rendered"][:64])

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

ok = gagal = 0
mulai = time.time()
for i, p in enumerate(belum, 1):
    baru = p["content"]["raw"].rstrip() + "\n" + BLOK
    st, _ = api(f"/wp-json/wp/v2/posts/{p['id']}", {"content": baru})
    _, chk = api(f"/wp-json/wp/v2/posts/{p['id']}?context=edit&_fields=content")
    jadi = isinstance(chk, dict) and "ss-cta-wa" in chk.get("content", {}).get("raw", "")
    if jadi:
        ok += 1
    else:
        gagal += 1
        print(f"  GAGAL #{p['id']} ({st}) {p['title']['rendered'][:45]}")
    if i % 20 == 0 or i == len(belum):
        menit = (time.time() - mulai) / 60
        print(f"  progres {i}/{len(belum)} | sukses {ok} | gagal {gagal} | {menit:.1f} menit")
print(f"\nSELESAI: {ok} terpasang | {gagal} gagal | total waktu {(time.time()-mulai)/60:.1f} menit")
