#!/usr/bin/env python3
"""DMark: pemeriksaan menyeluruh — kesehatan situs, GSC, GA4, dan inventaris konten WordPress."""
import base64, html, json, re, sys, time, urllib.parse, urllib.request, urllib.error, importlib.util
from datetime import date, timedelta

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
TOKEN = f"{WS}/seo-oauth/google_token_atun.json"
UA = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0 Safari/537.36"}

from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
c = Credentials.from_authorized_user_file(TOKEN)
if c.expired and c.refresh_token:
    c.refresh(Request()); open(TOKEN, "w").write(c.to_json())
H = {"Authorization": f"Bearer {c.token}", "Content-Type": "application/json"}


def api(u, data=None):
    r = urllib.request.Request(u, headers=H, data=json.dumps(data).encode() if data else None)
    for _ in range(3):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return json.loads(x.read())
        except urllib.error.HTTPError as e:
            return {"err": e.code}
        except Exception:
            time.sleep(3)
    return {}


def ambil(u, timeout=90):
    t0 = time.time()
    try:
        with urllib.request.urlopen(urllib.request.Request(u, headers=UA), timeout=timeout) as x:
            return x.status, x.read().decode("utf-8", "replace"), time.time() - t0, dict(x.headers)
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode("utf-8", "replace")[:400], time.time() - t0, dict(e.headers)
    except Exception as e:
        return 0, str(e)[:90], time.time() - t0, {}


print("=== 1. KESEHATAN SITUS ===")
for u in ("https://www.dmark.id/", "https://dmark.id/", "https://www.dmark.id/robots.txt",
          "https://www.dmark.id/sitemap_index.xml", "https://www.dmark.id/wp-json/"):
    st, h, d, head = ambil(u)
    judul = re.search(r"<title[^>]*>(.*?)</title>", h, re.S)
    print(f"   {st} | {d:5.2f}s | {len(h):>7} | {u[:52]:<54} {html.unescape(re.sub('<[^>]+>','',judul.group(1)))[:40] if judul else ''}")
    if u.endswith("robots.txt") and st == 200:
        print("      " + h.replace("\n", "\n      ")[:300])
    if "sitemap" in u and st == 200:
        subs = re.findall(r"<loc>([^<]+)</loc>", h)
        print(f"      sitemap: {len(subs)} berkas → {[s.split('/')[-1] for s in subs]}")

print("\n=== 2. GSC ===")
SITE = "https://www.dmark.id/"
SITE_ENC = urllib.parse.quote(SITE, safe="")
akhir = date.today() - timedelta(days=3)
awal = akhir - timedelta(days=27)
lalu_akhir = awal - timedelta(days=1)
lalu_awal = lalu_akhir - timedelta(days=27)
S = lambda x: x.isoformat()


def gsc(dim, a, b, baris=200):
    d = api(f"https://www.googleapis.com/webmasters/v3/sites/{SITE_ENC}/searchAnalytics/query",
            {"startDate": a, "endDate": b, "dimensions": dim, "rowLimit": baris})
    return (d or {}).get("rows", [])


for nama, (a, b) in (("28 hari ini", (S(awal), S(akhir))), ("28 sebelumnya", (S(lalu_awal), S(lalu_akhir)))):
    rows = gsc(["date"], a, b, 100)
    klik = sum(r["clicks"] for r in rows); tay = sum(r["impressions"] for r in rows)
    print(f"   {nama:<16} klik {klik:>4} | tayang {tay:>6} | CTR {round(klik/tay*100,2) if tay else 0}%")

rows90 = gsc(["query"], S(akhir - timedelta(days=89)), S(akhir), 1000)
print("\n   kueri 90 hari (tayangan terbanyak):")
for r in sorted(rows90, key=lambda x: -x["impressions"])[:12]:
    print(f"      {r['clicks']:>2} klik | {r['impressions']:>5} tayang | pos {round(r['position'],1):>6} | {r['keys'][0][:52]}")
print("\n   halaman 28 hari:")
for r in sorted(gsc(["page"], S(awal), S(akhir), 100), key=lambda x: -x["clicks"])[:10]:
    print(f"      {r['clicks']:>2} klik | {r['impressions']:>5} | pos {round(r['position'],1):>6} | {r['keys'][0].replace('https://www.dmark.id','')[:56]}")

d = api(f"https://www.googleapis.com/webmasters/v3/sites/{SITE_ENC}/sitemaps")
print("\n   sitemap di GSC:")
for s in (d.get("sitemap") or []):
    print(f"      {s['path'].replace('https://www.dmark.id','')[:34]:<36} unduh {str(s.get('lastDownloaded'))[:10]} | error {s.get('errors',0)} | warning {s.get('warnings',0)}")

print("\n=== 3. GA4 (properti 541315541) ===")
GA4 = "541315541"


def ga(dim, met, hari=90, limit=20, urut="sessions"):
    d = api(f"https://analyticsdata.googleapis.com/v1beta/properties/{GA4}:runReport",
            {"dateRanges": [{"startDate": f"{hari}daysAgo", "endDate": "today"}],
             "dimensions": [{"name": x} for x in dim], "metrics": [{"name": x} for x in met],
             "limit": limit, "orderBys": [{"metric": {"metricName": urut}, "desc": True}]})
    return (d or {}).get("rows", [])


for r in ga(["sessionDefaultChannelGroup"], ["sessions", "engagementRate", "keyEvents"]):
    print(f"   {r['dimensionValues'][0]['value']:<22} {r['metricValues'][0]['value']:>5} sesi | "
          f"keterlibatan {round(float(r['metricValues'][1]['value'])*100)}% | kunci {r['metricValues'][2]['value']}")
print("\n   halaman masuk:")
for r in ga(["landingPagePlusQueryString"], ["sessions"], 90, 10):
    print(f"      {r['metricValues'][0]['value']:>4} sesi | {r['dimensionValues'][0]['value'][:60]}")
print("\n   peristiwa:")
for r in ga(["eventName"], ["eventCount"], 90, 20, "eventCount"):
    print(f"      {r['metricValues'][0]['value']:>6}x {r['dimensionValues'][0]['value'][:50]}")

print("\n=== 4. INVENTARIS KONTEN (WordPress) ===")
spec = importlib.util.spec_from_file_location("cfg_dmark", f"{WS}/cfg_dmark.py")
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
CFG = m.CFG
DOM = CFG.get("domain", "www.dmark.id")
AUTH = base64.b64encode(f'{CFG["user"]}:{CFG["pass"]}'.encode()).decode()


def rest(p):
    r = urllib.request.Request(f"https://{DOM}{p}", 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(4)
    return []


post, page = [], 1
while True:
    d = rest(f"/wp-json/wp/v2/posts?per_page=100&page={page}&status=publish&context=edit&_fields=id,slug,title,content,date,modified")
    if not isinstance(d, list):
        break
    post += d
    if len(d) < 100:
        break
    page += 1
halaman = rest("/wp-json/wp/v2/pages?per_page=100&status=publish&context=edit&_fields=id,slug,title,content")
print(f"   artikel: {len(post)} | halaman: {len(halaman) if isinstance(halaman, list) else '?'}")
kata = [len(re.sub(r"<[^>]+>", " ", p["content"]["raw"] or "").split()) for p in post]
if kata:
    print(f"   panjang artikel: rata-rata {round(sum(kata)/len(kata))} kata | terpendek {min(kata)} | terpanjang {max(kata)}")
    tipis = [p for p, k in zip(post, kata) if k < 600]
    print(f"   artikel di bawah 600 kata: {len(tipis)}")
    nol_wa = [p for p in post if not re.search(r"wa\.me|whatsapp|wa\.link", p["content"]["raw"] or "", re.I)]
    print(f"   artikel tanpa tautan WhatsApp: {len(nol_wa)}")
    nol_faq = [p for p in post if "FAQPage" not in (p["content"]["raw"] or "")]
    print(f"   artikel tanpa skema FAQ: {len(nol_faq)}")
    terbaru = sorted(post, key=lambda p: p["modified"], reverse=True)[:5]
    print("   5 artikel terakhir diubah:")
    for p in terbaru:
        print(f"      #{p['id']} {p['modified'][:10]} | {html.unescape(re.sub('<[^>]+>','',p['title']['raw']))[:56]}")
