#!/usr/bin/env python3
"""TSC: audit 167 artikel + cocokkan dengan GSC (impresi/klik/posisi) dan GA4 (sesi per halaman).
Sekaligus uji apakah meta Yoast artikel bisa dibaca/ditulis lewat XML-RPC."""
import base64, html, json, os, re, time, urllib.request, urllib.error, importlib.util
from collections import Counter
from google.oauth2 import service_account
from googleapiclient.discovery import build

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
KEY = os.path.expanduser("~/.hermes/gsc_service_account.json")
UA = {"User-Agent": "Mozilla/5.0"}
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()


def rest(path):
    r = urllib.request.Request(f"https://{DOM}{path}", headers={"Authorization": f"Basic {AUTH}", **UA})
    for _ in range(3):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return json.loads(x.read())
        except Exception:
            time.sleep(3)
    return []


print("=== 1. tarik semua artikel ===")
posts, page = [], 1
while True:
    d = rest(f"/wp-json/wp/v2/posts?per_page=100&page={page}&status=publish"
             f"&context=edit&_fields=id,slug,link,title,content,featured_media,categories,tags")
    if not isinstance(d, list):
        break
    posts += d
    if len(d) < 100:
        break
    page += 1
print(f"   {len(posts)} artikel terbit")

ringkas = []
for p in posts:
    raw = p.get("content", {}).get("raw", "")
    teks = re.sub(r"\s+", " ", html.unescape(re.sub(r"<[^>]+>", " ", re.sub(r"<(script|style)[^>]*>.*?</\1>", " ", raw, flags=re.S | re.I))))
    keluar = set(re.findall(r'href="https://www\.theskincodeclinic\.com(/[^"]*)"', raw))
    ringkas.append({"id": p["id"], "slug": p["slug"], "url": "/" + p["slug"] + "/",
                    "judul": html.unescape(p["title"]["rendered"]), "kata": len(teks.split()),
                    "gambar": p.get("featured_media", 0), "kat": p.get("categories", []),
                    "tag": len(p.get("tags", [])), "keluar": sorted(keluar)})

print("\n=== 2. GSC: impresi & posisi per artikel (90 hari) ===")
gsc = build("searchconsole", "v1", credentials=service_account.Credentials.from_service_account_file(
    KEY, scopes=["https://www.googleapis.com/auth/webmasters.readonly"]), cache_discovery=False)
rows = gsc.searchanalytics().query(siteUrl="https://www.theskincodeclinic.com/", body={
    "startDate": "2026-06-28", "endDate": "2026-09-25", "dimensions": ["page"], "rowLimit": 5000}).execute().get("rows", [])
gsc_map = {}
for r in rows:
    u = r["keys"][0].replace("https://www.theskincodeclinic.com", "")
    if not u.endswith("/"):
        u += "/"
    gsc_map[u] = {"imp": r["impressions"], "klik": r["clicks"], "pos": round(r["position"], 1), "ctr": round(r["ctr"] * 100, 2)}

print("\n=== 3. GA4: sesi per halaman pendaratan (90 hari) ===")
ga = build("analyticsdata", "v1beta",
           credentials=service_account.Credentials.from_service_account_file(
               KEY, scopes=["https://www.googleapis.com/auth/analytics.readonly"]), cache_discovery=False)
ga_map = {}
r = ga.properties().runReport(property="properties/490140645", body={
    "dateRanges": [{"startDate": "2026-06-28", "endDate": "2026-09-25"}],
    "dimensions": [{"name": "landingPagePlusQueryString"}],
    "metrics": [{"name": "sessions"}, {"name": "userEngagementDuration"}],
    "limit": 500, "orderBys": [{"metric": {"metricName": "sessions"}, "desc": True}]}).execute()
for row in r.get("rows", []):
    u = row["dimensionValues"][0]["value"].split("?")[0]
    if not u.endswith("/"):
        u += "/"
    ga_map[u] = {"sesi": int(row["metricValues"][0]["value"]),
                 "durasi": round(float(row["metricValues"][1]["value"]) / max(int(row["metricValues"][0]["value"]), 1))}

print("\n=== 4. gabungkan & nilai ===")
for a in ringkas:
    g = gsc_map.get(a["url"], {})
    a.update({"imp": g.get("imp", 0), "klik": g.get("klik", 0), "pos": g.get("pos"), "ctr": g.get("ctr", 0),
              "sesi": ga_map.get(a["url"], {}).get("sesi", 0), "durasi": ga_map.get(a["url"], {}).get("durasi", 0)})

masuk = Counter()
for a in ringkas:
    for k in a["keluar"]:
        masuk[k.strip("/")] = masuk.get(k.strip("/"), 0) + 1
for a in ringkas:
    a["masuk"] = masuk.get(a["slug"], 0)

print(f"   artikel punya impresi GSC : {sum(1 for a in ringkas if a['imp'] > 0)}")
print(f"   artikel dapat sesi GA4    : {sum(1 for a in ringkas if a['sesi'] > 0)}")
print(f"   artikel tanpa tautan keluar: {sum(1 for a in ringkas if not a['keluar'])}")
print(f"   artikel yatim (tak ditautkan): {sum(1 for a in ringkas if a['masuk'] == 0)}")
print(f"   artikel di bawah 800 kata : {sum(1 for a in ringkas if a['kata'] < 800)}")
print(f"   tanpa gambar utama        : {sum(1 for a in ringkas if not a['gambar'])}")

print("\n=== 5. prioritas: berimpresi tapi nol klik (posisi <= 25) ===")
kandidat = [a for a in ringkas if a["imp"] >= 20 and a["klik"] == 0 and (a["pos"] or 99) <= 25]
kandidat.sort(key=lambda x: -x["imp"])
for a in kandidat[:15]:
    print(f"   imp {a['imp']:>4} | pos {a['pos']:>5} | sesi {a['sesi']:>3} | {a['kata']:>5} kata | {a['url'][:52]}")

print("\n=== 6. artikel paling banyak mendatangkan sesi (GA4) ===")
for a in sorted(ringkas, key=lambda x: -x["sesi"])[:12]:
    print(f"   sesi {a['sesi']:>3} | durasi {a['durasi']:>4}s | imp {a['imp']:>4} | {a['url'][:56]}")

json.dump(ringkas, open(f"{WS}/drafts/tsc_audit_artikel.json", "w"), indent=1, ensure_ascii=False)
print(f"\n→ data lengkap: drafts/tsc_audit_artikel.json")
