#!/usr/bin/env python3
"""TSC: selaraskan judul SEO + meta description artikel prioritas dengan query nyata di GSC.
Target: artikel berimpresi tapi nol klik. Jalankan --apply untuk menulis."""
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_tsc", f"{WS}/cfg_tsc.py")
mod = importlib.util.module_from_spec(spec); spec.loader.exec_module(mod)
CFG = mod.CFG
DOM, USER, PASS = CFG["domain"], CFG["user"], CFG["pass"]
AUTH = base64.b64encode(f"{USER}:{PASS}".encode()).decode()
UA = {"User-Agent": "Mozilla/5.0"}
from google.oauth2 import service_account
from googleapiclient.discovery import build

KEY = os.path.expanduser("~/.hermes/gsc_service_account.json")
gsc = build("searchconsole", "v1", credentials=service_account.Credentials.from_service_account_file(
    KEY, scopes=["https://www.googleapis.com/auth/webmasters.readonly"]), cache_discovery=False)


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=150) as x:
                return x.read().decode("utf-8", "replace")
        except Exception:
            time.sleep(4)
    return ""


def baris(isi, kunci):
    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 rest(p):
    r = urllib.request.Request(f"https://{DOM}{p}", headers={"Authorization": f"Basic {AUTH}", **UA})
    with urllib.request.urlopen(r, timeout=150) as x:
        return json.loads(x.read())


# ── 1. kumpulkan query nyata per halaman
rows = gsc.searchanalytics().query(siteUrl="https://www.theskincodeclinic.com/", body={
    "startDate": "2026-06-28", "endDate": "2026-09-25", "dimensions": ["page", "query"],
    "rowLimit": 5000}).execute().get("rows", [])
per_halaman = {}
for r in rows:
    u = r["keys"][0].replace("https://www.theskincodeclinic.com", "").rstrip("/") or "/"
    per_halaman.setdefault(u, []).append(
        {"q": r["keys"][1], "imp": r["impressions"], "klik": r["clicks"], "pos": round(r["position"], 1)})

# ── 2. artikel prioritas (impresi >= 20, klik 0, posisi <= 25)
posts = rest("/wp-json/wp/v2/posts?per_page=100&page=1&status=publish&_fields=id,slug,link,title")
posts += rest("/wp-json/wp/v2/posts?per_page=100&page=2&status=publish&_fields=id,slug,link,title")
print(f"artikel terbaca: {len(posts)}")

prioritas = []
for p in posts:
    key = "/" + p["slug"]
    daftar = per_halaman.get(key, [])
    if not daftar:
        continue
    imp = sum(d["imp"] for d in daftar); klik = sum(d["klik"] for d in daftar)
    pos = round(sum(d["pos"] * d["imp"] for d in daftar) / imp, 1) if imp else None
    if imp >= 10 and klik <= 1 and pos and pos <= 35:
        daftar.sort(key=lambda d: -d["imp"])
        prioritas.append({"id": p["id"], "slug": p["slug"], "judul": html.unescape(p["title"]["rendered"]),
                          "imp": imp, "pos": pos, "query": daftar[:5]})

prioritas.sort(key=lambda x: -x["imp"])
print(f"\n=== {len(prioritas)} artikel prioritas (berimpresi, nol klik, posisi <= 25) ===")
for a in prioritas[:12]:
    print(f"\n   #{a['id']} {a['slug'][:50]}")
    print(f"      impresi {a['imp']} | posisi {a['pos']} | judul sekarang: {a['judul'][:70]}")
    for d in a["query"][:3]:
        print(f"        query: «{d['q'][:52]}» imp {d['imp']} pos {d['pos']}")

if "--apply" not in sys.argv:
    json.dump(prioritas, open(f"{WS}/drafts/tsc_prioritas_artikel.json", "w"), indent=1, ensure_ascii=False)
    print(f"\n→ drafts/tsc_prioritas_artikel.json (dry run — belum mengubah apa pun)")
