#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""TS Law — carousel 10 slide "Mitos atau Fakta? 8 anggapan soal proses hukum".

Deck: `deck_tslaw_mitosproses.json` (mitos baru, belum pernah dipakai — lihat
registry di references/tslaw-slide-generator.md). Render: gen_tslaw_slide.py.
Tayang **24 Okt 2026** (poster seri Bos habis 22 Okt, carousel terakhir 12 Okt):
  Threads 09:00 WIB (02:00Z) · IG 09:00 WIB (02:00Z) · FB 19:30 WIB (12:30Z)
LinkedIn TSLaw tetap SKIP (STOP sejak 10 Sep).

Pakai:
  python3 schedule_tslaw_mitosproses.py media   # PNG -> JPEG q90 + gate 200 (3 jalur)
  python3 schedule_tslaw_mitosproses.py run     # create 3 album (idempoten)
"""
import sys, os, re, json, subprocess, urllib.parse, urllib.request, time

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

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

IMG = "https://mantapserver.tail3947bb.ts.net/openclaw-img/"
SRC = "/tmp/tslaw_mitosproses"
PREFIX = "tslaw_mitosproses"
SLIDES = [f"{PREFIX}_{i:02d}.jpg" for i in range(1, 11)]
URLS = [IMG + f for f in SLIDES]
INGRESS = ["103.84.155.153", "103.84.155.217"]

JUDUL = "TS Law — Carousel Mitos atau Fakta: 8 Anggapan soal Proses Hukum"

CAP = """Mitos atau Fakta? Ada 8 anggapan soal proses hukum yang sering dipercaya, padahal keliru. ⚖️

Kami rangkum dalam satu carousel biar gampang dibaca:

1. Somasi itu sama dengan panggilan pengadilan.
2. Tidak punya biaya berarti tidak bisa menuntut hak.
3. Damai cukup disepakati lisan, tidak perlu ditulis.
4. Nama usaha dan logo otomatis terlindungi tanpa didaftarkan.
5. Semua perkara wajib pakai pengacara.
6. Menunda menuntut hak tidak ada akibatnya.
7. Surat kuasa bebas diisi apa saja.
8. Mediasi cuma buang waktu.

Delapannya sering bikin orang salah langkah, karena keputusan diambil berdasarkan asumsi, bukan aturan yang berlaku.

Geser slide-nya sampai habis ya, tiap slide ada bagian mitos dan faktanya.

Kalau kalian punya anggapan hukum lain yang bikin ragu, tulis di kolom komentar 👇

Butuh pendampingan hukum? Konsultasikan dengan Tito Suprianto Law Firm: https://tslaw.id

📲 WhatsApp: +62 819-0922-2026

Konten ini edukasi umum, bukan nasihat hukum untuk kasus spesifik.

#mitosataufakta #hukumacara #hukumperdata #hukumacaraperdata #edukasihukum #proseshukum #tslaw"""

CAP_THREADS = """Mitos atau Fakta? Ada 8 anggapan soal proses hukum yang sering dipercaya padahal keliru. ⚖️

Dari "somasi itu panggilan pengadilan", "damai cukup lisan", sampai "mediasi cuma buang waktu".

Geser slide-nya sampai habis ya.

Anggapan mana yang paling sering kamu dengar? Tulis di komentar 👇

#mitosataufakta #hukumacara #edukasihukum #tslaw"""

JOBS = [
    ("Threads", THREADS, "2026-10-24T02:00:00.000Z", CAP_THREADS),
    ("IG",      IG,      "2026-10-24T02:00:00.000Z", CAP),
    ("FB",      FB,      "2026-10-24T12:30:00.000Z", CAP),
]

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]")


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):
    """200 di jalur lokal + 2 IP ingress."""
    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


def buat_media():
    from PIL import Image
    os.makedirs("openclaw-img", exist_ok=True)
    hasil = []
    for i in range(1, 11):
        src = os.path.join(SRC, f"tslaw_gen_{i:02d}.png")
        dst = os.path.join("openclaw-img", SLIDES[i - 1])
        im = Image.open(src).convert("RGB")
        if im.size != (1080, 1350):
            print("  ⚠️ ukuran tidak standar:", src, im.size)
        im.save(dst, "JPEG", quality=90, optimize=True)
        hasil.append(dst)
    print(f"konversi: {len(hasil)} file → openclaw-img/{PREFIX}_*.jpg")
    return hasil


def main():
    mode = sys.argv[1] if len(sys.argv) > 1 else "media"

    if mode == "media":
        buat_media()
        for u in URLS:
            g = gate(u)
            ok = all(v == "200" for v in g.values())
            print(f"  {'✅' if ok else '❌'} {u.split('/')[-1]} {g}")
            if not ok:
                sys.exit(1)
        return

    # ── run: validasi caption lalu create ──
    for nama, acc, saat, cap in JOBS:
        m = []
        if len(cap) > (500 if acc == THREADS_ACC else 2200):
            m.append(f"panjang={len(cap)}")
        # Threads: ajakan komentar wajib di EKOR (160 char terakhir), karena caption dipotong di situ.
        # IG/FB: caption memang ditutup link + WA + disclaimer + hashtag, jadi CTA dicek di seluruh caption.
        if acc == THREADS_ACC:
            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 d in docs:
        aid = (d.get("account") or {}).get("_id")
        if aid in punya:
            for m_ in (d.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=JUDUL,
                               topic="Mitos atau Fakta Hukum", 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}")


if __name__ == "__main__":
    main()
