#!/usr/bin/env python3
"""DAS: gabungkan isi artikel yang dikorbankan ke artikel pemenang (hanya bagian yang bernilai),
lalu tandai artikel kalah dengan kanonik + noindex.

Pakai: python3 das_gabung_klaster.py [--klaster nissan] [--apply]
"""
import base64, html, json, os, re, sys, time, urllib.request, urllib.error, importlib.util
from xml.sax.saxutils import escape

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
spec = importlib.util.spec_from_file_location("cfg_das", f"{WS}/cfg_das.py")
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
CFG = m.CFG
DOM, USER, PASS = CFG["domain"], CFG["user"], CFG["pass"]
AUTH = base64.b64encode(f"{USER}:{PASS}".encode()).decode()
UA = {"User-Agent": "Mozilla/5.0"}
BACKUP = f"{WS}/das_pemulihan/klaster"
os.makedirs(BACKUP, exist_ok=True)

WARNA, NOMOR = "#d02c35", "6285242380789"
TOMBOL = ('<p style="text-align:center;margin:34px 0 6px">'
          f'<a href="https://wa.me/{NOMOR}?text=Hallo+DAS+Saya+ingin+AMBIL+PROMO" target="_blank" rel="noopener" '
          f'style="display:inline-block;background-color:{WARNA};color:#ffffff;padding:16px 36px;font-size:20px;'
          'font-weight:bold;text-decoration:none;border-radius:8px;">AMBIL PROMO</a></p>')

KLASTER = {
    "alphard": {"menang": 5569, "kalah": [6304, 6566], "model": "Alphard"},
    "nissan": {"menang": 5657, "kalah": [8081], "model": "Nissan"},
    "lexus": {"menang": 5684, "kalah": [6708, 6705], "model": "Lexus"},
    "innova": {"menang": 6392, "kalah": [6932, 5600], "model": "Innova"},
    "pajero": {"menang": 6430, "kalah": [6435, 5603], "model": "Pajero"},
    "mercy": {"menang": 8296, "kalah": [6711], "model": "Mercedes-Benz"},
}

# judul bagian yang cuma basa-basi (tidak perlu digabung)
BASABASI = r"mengapa memilih|hubungi|jadwalkan|kesimpulan|baca juga|penutup|kata pengantar|pendahuluan|profil bengkel|layanan lengkap|layanan unggulan|keunggulan|alasan"
# judul bagian yang bernilai teknis
BERNILAI = r"servis|service|overhaul|transmisi|cvt|mesin|engine|4wd|kaki|suspensi|hybrid|faq|gejala|penyebab|biaya|perawatan|tune|rem|aki|ac|kapan|tips|panduan|tanda"


def rest(p, 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}{p}", data=body, headers=h, method=method)
    for _ in range(3):
        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()[:200]
        except Exception:
            time.sleep(4)
    return 0, "gagal"


def rpc(method, params=()):
    def val(v):
        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(2):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return x.read().decode("utf-8", "replace")
        except Exception:
            time.sleep(4)
    return ""


def pisah_bagian(raw):
    """Pecah konten jadi blok (judul + isi)."""
    blok = []
    posisi = [(mm.start(), mm.group(0)) for mm in re.finditer(r"<h[23][^>]*>.*?</h[23]>", raw, re.S | re.I)]
    for i, (p, judul) in enumerate(posisi):
        akhir = posisi[i + 1][0] if i + 1 < len(posisi) else len(raw)
        isi = raw[p:akhir]
        teks_judul = html.unescape(re.sub(r"\s+", " ", re.sub(r"<[^>]+>", "", judul))).strip()
        bersih = re.sub(r"<[^>]+>", " ", isi)
        blok.append({"judul": teks_judul, "html": isi.strip(), "kata": len(bersih.split())})
    return blok


def buang_tombol(raw):
    return re.sub(r'<p style="text-align:center[^>]*>\s*<a[^>]*>[^<]*AMBIL PROMO[^<]*</a>\s*</p>', "", raw, flags=re.I).rstrip()


hasil_lapor = {}
for nama, k in KLASTER.items():
    if "--klaster" in sys.argv and sys.argv[sys.argv.index("--klaster") + 1] != nama:
        continue
    st, pm = rest(f"/wp-json/wp/v2/posts/{k['menang']}?context=edit&_fields=id,slug,link,title,content")
    raw_m = pm["content"]["raw"]
    judul_m = [b["judul"].lower() for b in pisah_bagian(raw_m)]
    print(f"\n■ {nama.upper()} — pemenang #{pm['id']}  /{pm['slug']}  ({len(re.sub(chr(60)+'[^>]+>', ' ', raw_m).split())} kata)")

    tambahan = []
    for pid in k["kalah"]:
        st, pk = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=id,slug,link,title,content")
        raw_k = pk["content"]["raw"]
        blok = pisah_bagian(raw_k)
        pilih = []
        for b in blok:
            j = b["judul"].lower()
            if not re.search(BERNILAI, j):
                continue
            if re.search(BASABASI, j):
                continue
            if any(j[:30] in x or x[:30] in j for x in judul_m):
                continue
            if b["kata"] < 25:
                continue
            pilih.append(b)
        kata_pilih = sum(b["kata"] for b in pilih)
        print(f"   ← #{pk['id']} /{pk['slug'][:46]:<48} {len(blok)} bagian → ambil {len(pilih)} ({kata_pilih} kata)")
        for b in pilih:
            print(f"        + {b['judul'][:74]}")
        tambahan += pilih

    if not tambahan:
        print("   tidak ada bagian bernilai untuk digabung")
    batas = tambahan[:8]
    kata_tambah = sum(b["kata"] for b in batas)
    print(f"   total digabung: {len(batas)} bagian / {kata_tambah} kata")

    if "--apply" in sys.argv and batas:
        open(f"{BACKUP}/menang_{pm['id']}.txt", "w").write(raw_m)
        dasar = buang_tombol(raw_m)
        sisip = "\n\n" + "\n\n".join(b["html"] for b in batas) + "\n\n"
        baru = dasar + sisip + TOMBOL + "\n"
        rest(f"/wp-json/wp/v2/posts/{pm['id']}", "POST", {"content": baru})
        st, cek = rest(f"/wp-json/wp/v2/posts/{pm['id']}?context=edit&_fields=content")
        raw2 = cek.get("content", {}).get("raw", "") if isinstance(cek, dict) else ""
        print(f"   tulis pemenang: {'✅ cocok' if raw2 == baru else '⚠️ tidak cocok'} | {len(re.sub(chr(60)+'[^>]+>', ' ', raw2).split())} kata")

    if "--apply" in sys.argv:
        for pid in k["kalah"]:
            st, pk = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=id,slug,link,content")
            open(f"{BACKUP}/kalah_{pk['id']}.txt", "w").write(pk["content"]["raw"])
            rpc("wp.editPost", [1, USER, PASS, pk["id"], {"custom_fields": [
                {"key": "_yoast_wpseo_canonical", "value": pm["link"]},
                {"key": "_yoast_wpseo_meta-robots-noindex", "value": "1"}]}])
            print(f"   konsolidasi #{pk['id']} → kanonik ke /{pm['slug']} + noindex")
    hasil_lapor[nama] = {"menang": pm["id"], "digabung": len(batas), "kata_digabung": kata_tambah,
                         "kalah": [x for x in k["kalah"]]}

if "--apply" not in sys.argv:
    print("\n(dry run — pakai --apply untuk menulis)")
json.dump(hasil_lapor, open(f"{WS}/drafts/das_hasil_klaster.json", "w"), indent=1, ensure_ascii=False)
