#!/usr/bin/env python3
"""Perbaiki artikel TSC yang barisnya terpotong di tengah kalimat.

Penyebab: paragraf ditulis berbaris-baris (satu baris baru di dalam <p>), lalu WordPress
mengubahnya jadi <br> sehingga kalimat patah di tengah saat dibaca di situs.

Hanya menyentuh artikel yang benar-benar punya patahan di tengah kalimat. Atribut tag dipertahankan.
Jalankan tanpa argumen = uji. Dengan --go = perbaiki.
"""
import base64, importlib.util, json, re, sys, time, urllib.request

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
spec = importlib.util.spec_from_file_location("cfg", f"{WS}/cfg_tsc.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
S = "https://www.theskincodeclinic.com"
A = base64.b64encode(f"{m.CFG['user']}:{m.CFG['pass']}".encode()).decode()
H = {"Authorization": f"Basic {A}", "User-Agent": "Mozilla/5.0", "Content-Type": "application/json"}

TAG = ("p", "li", "h1", "h2", "h3", "h4", "blockquote", "figcaption", "td", "th")


def patahan(isi):
    """Hitung baris yang dipotong di tengah kalimat di dalam elemen teks."""
    n = 0
    for mo in re.finditer(r"<(" + "|".join(TAG) + r")(?:\s[^>]*)?>(.*?)</\1>", isi, re.S | re.I):
        dalam = mo.group(2).strip()
        if "\n" not in dalam or "<br" in dalam:
            continue
        baris = [b.strip() for b in dalam.split("\n")]
        for b in baris[:-1]:
            if b and not re.search(r"[.!?:;]\s*$", b):
                n += 1
    return n


def rapikan(isi):
    def ganti(mo):
        buka, dalam = mo.group(1), mo.group(3)
        if "<br" in dalam:
            return mo.group(0)
        rapi = re.sub(r"\s{2,}", " ", re.sub(r"\s*\n\s*", " ", dalam)).strip()
        return f"{buka}{rapi}</{mo.group(2)}>"
    pola = re.compile(r"(<(" + "|".join(TAG) + r")(?:\s[^>]*)?>)(.*?)</\2>", re.S | re.I)
    return pola.sub(ganti, isi)


def daftar(status):
    hasil, hal = [], 1
    while True:
        u = (f"{S}/wp-json/wp/v2/posts?per_page=100&page={hal}&status={status}&context=edit"
             "&_fields=id,link,content,status")
        try:
            d = json.loads(urllib.request.urlopen(urllib.request.Request(u, headers=H), timeout=180).read())
        except Exception:
            break
        if not isinstance(d, list) or not d:
            break
        hasil += d
        if len(d) < 100:
            break
        hal += 1
    return hasil


semua = daftar("publish") + daftar("future") + daftar("draft")
GO = "--go" in sys.argv
cadangan, n = {}, 0
for x in semua:
    c = x["content"]["raw"]
    p = patahan(c)
    if p == 0:
        continue
    rapi = rapikan(c)
    teks1 = re.sub(r"\s+", " ", re.sub("<[^>]+>", " ", c)).strip()
    teks2 = re.sub(r"\s+", " ", re.sub("<[^>]+>", " ", rapi)).strip()
    n += 1
    print(f"   #{x['id']:<6} [{x['status']:<7}] patahan: {p:<3} · teks {len(teks1)}→{len(teks2)} char · "
          f"{'AMAN' if teks1 == teks2 else '⚠ TEKS BERUBAH'} · {x['link'].replace(S, '')[:40]}")
    cadangan[str(x["id"])] = {"konten": c, "patahan": p}
    if GO and teks1 == teks2:
        for _ in range(3):
            try:
                r = urllib.request.Request(f"{S}/wp-json/wp/v2/posts/{x['id']}",
                                           data=json.dumps({"content": rapi}).encode(), headers=H, method="POST")
                urllib.request.urlopen(r, timeout=180).read()
                break
            except Exception as e:
                print(f"        gagal: {str(e)[:60]}")
                time.sleep(3)
        time.sleep(0.8)

if GO:
    json.dump(cadangan, open(f"{WS}/tsc_backup_rapi_baris.json", "w"), ensure_ascii=False)
    print(f"\n✅ {n} artikel dirapikan · cadangan: tsc_backup_rapi_baris.json")
else:
    print(f"\n(uji) {n} dari {len(semua)} artikel punya patahan di tengah kalimat.")
