#!/usr/bin/env python3
"""verify_hc41.py — verifikasi run hc41 (20 Sep 2026 02:00 WIB) SETELAH create.

Cek:
 1. Fetch ULANG per-ID dari API (album Threads, LinkedIn, FB)
 2. Album Threads: 5 media, urutan benar, caption <=500 char, tanpa mention, hashtag lowercase
 3. 2 reply anak menempel ke album (normalisasi ObjectId-dict — PITFALL Repliz)
 4. LinkedIn & FB: 0 media; FB replies=[] (kalau ada replies -> error postId)
 5. IG SS tidak disentuh (0 media hc41 di IG)
 6. Tidak ada duplikat media hc41 di jadwal lain
 7. Semua media hc41 masih 200 di KEDUA ingress (jalur fetch Repliz)
"""
import json
import os
import re
import subprocess
import sys

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
sys.path.insert(0, WS)
from repliz_client import ReplizClient, ACC, IMG_BASE_URL

c = ReplizClient()
FAIL = []

IDS = {
    "threads": "6aaedd3c3032e3a79c697b26",
    "linkedin": "6aaedd3c3032e3a79c697b3c",
    "facebook": "6aaedd3c02078a414a6451c6",
}
MEDIA_FILES = [
    "ss_hc41_analytics_01_cover.jpg",
    "ss_hc41_analytics_02_data.jpg",
    "ss_hc41_analytics_03_contoh.jpg",
    "ss_hc41_analytics_04_langkah.jpg",
    "ss_hc41_analytics_05_cta.jpg",
]
MEDIA_URLS = [IMG_BASE_URL.rstrip("/") + "/openclaw-img/" + f for f in MEDIA_FILES]
INGRESS = ["103.84.155.153", "103.84.155.217"]


def ck(label, cond, extra=""):
    print("  %s %s %s" % ("\u2705" if cond else "\u274c", label, extra))
    if not cond:
        FAIL.append(label)
    return cond


def norm_replies(v):
    """Normalisasi field replies: bisa ['6aa...'] ATAU [{'0':'6','1':'a',...,'status':'success'}]
    (ObjectId diserialisasi per karakter + field status/postId — PITFALL Repliz)."""
    out = []
    for r in (v or []):
        if isinstance(r, dict):
            keys = [k for k in r if str(k).isdigit()]
            if keys:
                out.append("".join(str(r[k]) for k in sorted(keys, key=lambda x: int(x))))
            else:
                out.append(json.dumps(r))
        else:
            out.append(str(r))
    return out


def fetch(sid):
    d = c.get("/public/schedule/%s" % sid)
    return d.get("doc") or d.get("data") or d


def all_docs():
    docs, page = [], 1
    while True:
        d = c.get("/public/schedule?page=%d&limit=100" % page)
        docs.extend(d.get("docs", []))
        if page >= (d.get("totalPages") or 1):
            break
        page += 1
    return docs


print("=" * 78)
print("VERIFIKASI hc41 \u2014 fetch ULANG dari API per-ID")
print("=" * 78)

docs = {k: fetch(v) for k, v in IDS.items()}

print("\n1) PER-ID:")
for k, d in docs.items():
    print("  %-9s status=%s at=%s type=%s medias=%d replies=%d" % (
        k, d.get("status"), d.get("scheduleAt"), d.get("type"),
        len(d.get("medias") or []), len(d.get("replies") or [])))

print("\n2) ALBUM THREADS:")
t = docs["threads"]
ck("status pending", (t.get("status") or "").lower() == "pending", t.get("status"))
ck("scheduleAt 2026-09-20T02:00", (t.get("scheduleAt") or "").startswith("2026-09-20T02:00"),
   t.get("scheduleAt"))
ck("type album", t.get("type") == "album", t.get("type"))
urls = [(m.get("url") or "") for m in (t.get("medias") or [])]
ck("5 media", len(urls) == 5, len(urls))
ck("urutan media benar", urls == MEDIA_URLS,
   "beda: %s" % [u.split("/")[-1] for u in urls])
desc = t.get("description") or ""
ck("caption <=500 char", len(desc) <= 500, len(desc))
ck("0 mention", not re.findall(r"@\w+", desc), re.findall(r"@\w+", desc))
ck("hashtag lowercase", all(x == x.lower() for x in re.findall(r"#(\w+)", desc)))
ck("link artikel ada", "data-analytics-rumah-sakit-kebutuhan-pasien" in desc)
ck("ada pancingan diskusi di ekor",
   bool(re.search(r"komentar|pendapat|diskusi|setuju|share|pengalaman|menurut|bagaimana",
                  desc[-200:], re.I)))

print("\n3) REPLY ANAK MENEMPEL KE ALBUM:")
pids = {}
for d in all_docs():
    if d.get("accountId") != ACC.STUDIOSOFT_THREADS:
        continue
    rs = norm_replies(d.get("replies"))
    if IDS["threads"] in rs:
        pids[(d.get("scheduleAt") or "")[:16]] = {"id": d.get("_id"), "desc": (d.get("description") or "")}
ck("2 reply anak ketemu", len(pids) == 2, list(pids))
for at in sorted(pids):
    print("      %s | %s | %s" % (at, pids[at]["id"], pids[at]["desc"][:60].replace("\n", " ")))
ck("reply memuat link artikel + CTA", any("data-analytics-rumah-sakit" in p["desc"] for p in pids.values()))
ck("reply memuat hashtag line", any("#studiosoft" in p["desc"] for p in pids.values()))

print("\n4) LINKEDIN & FACEBOOK:")
li = docs["linkedin"]
ck("LI type text", li.get("type") == "text", li.get("type"))
ck("LI 0 media", not (li.get("medias") or []))
ck("LI 0 replies", not norm_replies(li.get("replies")), norm_replies(li.get("replies")))
ck("LI caption 1400-2000 char", 1400 <= len(li.get("description") or "") <= 2000,
   len(li.get("description") or ""))
ck("LI link panduan-seo-klinik", "panduan-seo-klinik-rumah-sakit" in (li.get("description") or ""))
fb = docs["facebook"]
ck("FB type text", fb.get("type") == "text", fb.get("type"))
ck("FB 0 media", not (fb.get("medias") or []))
ck("FB replies=[] KOSONG (wajib)", norm_replies(fb.get("replies")) == [],
   norm_replies(fb.get("replies")))
ck("FB link klinik-kecil", "klinik-kecil-butuh-digital-marketing" in (fb.get("description") or ""))

print("\n5) IG SS TIDAK DISENTUH + 6) DUPLIKAT MEDIA:")
hits_ig, hits_other = [], []
for d in all_docs():
    for m in (d.get("medias") or []):
        b = os.path.basename((m.get("url") or "").split("?")[0]).lower()
        if b in [f.lower() for f in MEDIA_FILES]:
            if d.get("accountId") == ACC.STUDIOSOFT_IG:
                hits_ig.append((d.get("_id"), b))
            elif d.get("_id") != IDS["threads"]:
                hits_other.append((d.get("_id"), b, d.get("accountId")))
ck("0 media hc41 di IG SS", not hits_ig, hits_ig)
ck("0 duplikat media hc41 di jadwal lain", not hits_other, hits_other)

print("\n7) MEDIA 200 DI KEDUA INGRESS:")
for f, u in zip(MEDIA_FILES, MEDIA_URLS):
    codes = []
    for ip in INGRESS:
        r = subprocess.run(["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "--max-time", "30",
                            "--resolve", "mantapserver.tail3947bb.ts.net:443:%s" % ip, u],
                           capture_output=True, text=True)
        codes.append(r.stdout.strip())
    ck("%s" % f, codes == ["200", "200"], codes)

print("\n" + "=" * 78)
if FAIL:
    print("GAGAL: %s" % FAIL)
    sys.exit(1)
print("SEMUA CEK LULUS \u2705")
