#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Pemasang carousel TS Law yang bisa dipakai ulang (deck dari gen_tslaw_slide.py).

Pakai:
  python3 pasang_carousel_tslaw.py media --prefix tslaw_mitosbukti --src /tmp/tslaw_mitosbukti
  python3 pasang_carousel_tslaw.py run   --prefix tslaw_mitosbukti --tgl 2026-10-31 \
        --judul "TS Law — Carousel Mitos atau Fakta: 8 Anggapan soal Bukti dan Hak" \
        --cap-ig caption_tslaw_mitosbukti_ig.txt --cap-threads caption_tslaw_mitosbukti_threads.txt

Aturan tetap:
  - Threads & IG tayang 09:00 WIB (02:00Z), FB 19:30 WIB (12:30Z) — LinkedIn TSLaw SKIP (STOP 10 Sep)
  - gate media: HTTP 200 di jalur lokal + 2 IP ingress, ABORT kalau tidak
  - idempoten: kalau slide 01 sudah terjadwal di akun itu, skip
  - validasi: Threads <=500 char + ajakan komentar di 160 char terakhir; IG/FB <=2200 char
  - hashtag huruf kecil, tanpa mention, tanpa CJK
"""
import sys, os, re, json, subprocess, urllib.parse, urllib.request, time, argparse

sys.path.insert(0, "/home/mantapman/.hermes/profiles/atun/workspace")
from repliz_client import HEADERS, BASE, get_client

IG = "6a76a54d62caae1e04f30968"
THREADS = "6a35f8b7c5ff4ce3a322b2ed"
FB = "6a3b41d1c5ff4ce3a32753e8"

IMG = "https://mantapserver.tail3947bb.ts.net/openclaw-img/"
INGRESS = ["103.84.155.153", "103.84.155.217"]
CTA_RE = re.compile(r"komentar|tulis di|menurut (kamu|anda)|setuju|pendapat", re.I)
MENTION_RE = re.compile(r"@\w+")
CJK = re.compile(r"[\u3000-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff00-\uffef]")

ap = argparse.ArgumentParser()
ap.add_argument("mode", choices=["media", "run"])
ap.add_argument("--prefix", required=True)
ap.add_argument("--src", default=None, help="folder PNG hasil gen_tslaw_slide.py (mode media)")
ap.add_argument("--tgl", default=None, help="tanggal WIB tayang (mode run)")
ap.add_argument("--judul", default="")
ap.add_argument("--topik", default="Mitos atau Fakta Hukum")
ap.add_argument("--cap-ig", default=None, dest="cap_ig")
ap.add_argument("--cap-threads", default=None, dest="cap_threads")
ap.add_argument("--jumlah", type=int, default=10)
a = ap.parse_args()

SLIDES = [f"{a.prefix}_{i:02d}.jpg" for i in range(1, a.jumlah + 1)]
URLS = [IMG + f for f in SLIDES]


def all_schedules():
    docs, page = [], 1
    while True:
        q = urllib.parse.urlencode({"page": page, "limit": 100})
        req = urllib.request.Request(f"{BASE}/public/schedule?{q}", headers=HEADERS)
        with urllib.request.urlopen(req, timeout=60) as r:
            d = json.loads(r.read().decode())
        batch = d.get("docs") or []
        docs += batch
        if not batch or page * 100 >= (d.get("totalDocs") or 0):
            break
        page += 1
    return docs


def gate(url):
    out = {}
    for label, extra in (("lokal", []), *[(ip, ["--resolve", f"mantapserver.tail3947bb.ts.net:443:{ip}"]) for ip in INGRESS]):
        p = subprocess.run(["curl", "-4", "-s", "-o", "/dev/null", "-w", "%{http_code}",
                            "--max-time", "25", *extra, url], capture_output=True, text=True)
        out[label] = (p.stdout or "000").strip()
    return out


if a.mode == "media":
    from PIL import Image
    if not a.src:
        sys.exit("--src wajib untuk mode media")
    os.makedirs("openclaw-img", exist_ok=True)
    for i in range(1, a.jumlah + 1):
        src = os.path.join(a.src, f"tslaw_gen_{i:02d}.png")
        im = Image.open(src).convert("RGB")
        if im.size != (1080, 1350):
            print("  ⚠️ ukuran tidak standar:", src, im.size)
        im.save(os.path.join("openclaw-img", SLIDES[i - 1]), "JPEG", quality=90, optimize=True)
    print(f"konversi {a.jumlah} file → openclaw-img/{a.prefix}_*.jpg")
    gagal = 0
    for u in URLS:
        g = gate(u)
        ok = all(v == "200" for v in g.values())
        gagal += 0 if ok else 1
        print(f"  {'✅' if ok else '❌'} {u.split('/')[-1]} {g}")
    sys.exit(1 if gagal else 0)

# ── mode run ──
for f in (a.cap_ig, a.cap_threads, a.tgl):
    if not f:
        sys.exit("mode run butuh --tgl, --cap-ig, --cap-threads")
if a.tgl:
    y, m, d = [int(x) for x in a.tgl.split("-")]
    threads_ig_at = f"{y:04d}-{m:02d}-{d:02d}T02:00:00.000Z"     # 09:00 WIB
    fb_at = f"{y:04d}-{m:02d}-{d:02d}T12:30:00.000Z"            # 19:30 WIB
cap_ig = open(a.cap_ig).read().strip()
cap_th = open(a.cap_threads).read().strip()

JOBS = [("Threads", THREADS, threads_ig_at, cap_th), ("IG", IG, threads_ig_at, cap_ig), ("FB", FB, fb_at, cap_ig)]
JP = {THREADS: THREADS}

for nama, acc, saat, cap in JOBS:
    m = []
    if len(cap) > (500 if acc == THREADS else 2200):
        m.append(f"panjang={len(cap)}")
    if acc == THREADS:
        if not CTA_RE.search(cap[-160:]):
            m.append("tanpa-CTA-di-ekor")
    elif not CTA_RE.search(cap):
        m.append("tanpa-CTA")
    if MENTION_RE.search(cap):
        m.append("mention")
    if CJK.search(cap):
        m.append("CJK")
    tags = re.findall(r"#(\w+)", cap)
    if any(t != t.lower() for t in tags):
        m.append("hashtag-besar")
    print(f"[{nama}] len={len(cap)} tags={len(tags)} {'✅' if not m else '❌ ' + ','.join(m)}")
    if m:
        print("⛔ caption bermasalah — batal.")
        sys.exit(1)

docs = all_schedules()
punya = {aid: set() for aid in (IG, THREADS, FB)}
for x in docs:
    aid = (x.get("account") or {}).get("_id")
    if aid in punya:
        for m_ in (x.get("medias") or []):
            punya[aid].add((m_.get("url") or "").split("/")[-1])

c = get_client()
for nama, acc, saat, cap in JOBS:
    if SLIDES[0] in punya[acc]:
        print(f"[{nama}] ⏭️  sudah ada (slide 01 sudah terjadwal) — skip")
        continue
    res = c.create_schedule(acc, cap, saat, title=a.judul, topic=a.topik,
                            type_="album", medias=[{"url": u} for u in URLS], replies=[])
    sid = res.get("scheduleId") or res.get("_id") or res.get("id")
    time.sleep(0.5)
    b = c.get_schedule(sid)
    bb = b.get("data", b) if isinstance(b, dict) else b
    med = [m_.get("url", "").split("/")[-1] for m_ in (bb.get("medias") or [])]
    print(f"[{nama}] {sid} | status={bb.get('status')} | {bb.get('scheduleAt')} | media={len(med)} | "
          f"urut={'OK' if med == SLIDES else med}")
