#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Pasang / perbarui seri carousel Threads @ukyhandoko (gaya White & Black), ritme 2 hari sekali.

Jumlah slide tiap seri BEDA (Bos: angka random 5-10 poin + cover + penutup) dan diambil
dari `gen_uky_carousel.py` (single source of truth), caption dari `caption_uky_car_<seri>.txt`.

Pakai:
  python3 pasang_carousel_uky_seri.py media          # copy semua seri ke openclaw-img + gate 200
  python3 pasang_carousel_uky_seri.py run [--go]     # PUT kalau seri sudah ada, CREATE kalau belum
"""
import os, re, sys, json, shutil, importlib.util, subprocess, urllib.parse, urllib.request, time

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

spec = importlib.util.spec_from_file_location("g", "/home/mantapman/.hermes/profiles/atun/workspace/gen_uky_carousel.py")
g = importlib.util.module_from_spec(spec)
spec.loader.exec_module(g)

UKY = "6a334e89c5ff4ce3a3225a48"
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|setuju|pendapat", re.I)
CJK = re.compile(r"[\u3000-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff00-\uffef]")

TANGGAL = {"a": "2026-10-11", "b": "2026-10-13", "c": "2026-10-15", "d": "2026-10-17",
           "e": "2026-10-19", "f": "2026-10-21", "g": "2026-10-23",
           "h": "2026-10-25", "i": "2026-10-27", "j": "2026-10-29", "k": "2026-10-31"}


def jumlah_slide(seri):
    return g.SERI[seri]["jumlah"] + 2


def slides(seri):
    return [f"uky_car_{seri}_{i:02d}.jpg" for i in range(1, jumlah_slide(seri) + 1)]


def judul_jadwal(seri):
    info = g.SERI[seri]
    n = info["jumlah"]
    cover = " ".join(b.replace("{n}", str(n)) for b in info["judul"])
    return f"uky — {cover.title().replace('Ai', 'AI')}"


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


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())
        b = d.get("docs") or []
        docs += b
        if not b or page * 100 >= (d.get("totalDocs") or 0):
            break
        page += 1
    return docs


mode = sys.argv[1] if len(sys.argv) > 1 else "media"
go = "--go" in sys.argv

if mode == "media":
    os.makedirs("openclaw-img", exist_ok=True)
    for seri in g.SERI:
        for i in range(1, jumlah_slide(seri) + 1):
            shutil.copyfile(f"/tmp/uky_car_{seri}/uky_car_{i:02d}.jpg",
                            os.path.join("openclaw-img", f"uky_car_{seri}_{i:02d}.jpg"))
        # bersihkan file lama yang sudah tidak dipakai seri ini
        for f_ in os.listdir("openclaw-img"):
            m = re.match(rf"uky_car_{seri}_(\d+)\.jpg$", f_)
            if m and int(m.group(1)) > jumlah_slide(seri):
                os.remove(os.path.join("openclaw-img", f_))
    total = sum(jumlah_slide(s) for s in g.SERI)
    print(f"copy {total} file → openclaw-img/uky_car_<seri>_*.jpg")
    gagal = 0
    for seri in g.SERI:
        for s in slides(seri):
            gg = gate(IMG + s)
            if not all(v == "200" for v in gg.values()):
                gagal += 1
                print(f"  ❌ {s} {gg}")
    print("gate selesai | gagal:", gagal)
    sys.exit(1 if gagal else 0)

# ── run ──
caps = {}
for seri in g.SERI:
    cap = open(f"caption_uky_car_{seri}.txt").read().strip()
    masalah = []
    if len(cap) > 500:
        masalah.append(f"panjang={len(cap)}")
    if not CTA_RE.search(cap[-160:]):
        masalah.append("tanpa-CTA-di-ekor")
    if CJK.search(cap):
        masalah.append("CJK")
    tags = re.findall(r"#(\w+)", cap)
    if any(t != t.lower() for t in tags):
        masalah.append("hashtag-besar")
    print(f"[{seri}] {TANGGAL[seri]} | {jumlah_slide(seri)} slide | caption {len(cap)} char "
          f"{'✅' if not masalah else '❌ ' + ','.join(masalah)}")
    if masalah:
        sys.exit("⛔ caption bermasalah — batal")
    caps[seri] = cap

docs = all_schedules()
milik = [x for x in docs if (x.get("account") or {}).get("_id") == UKY and x.get("status") == "pending"]
c = get_client()

for seri in g.SERI:
    y, mo, d_ = [int(v) for v in TANGGAL[seri].split("-")]
    saat = f"{y:04d}-{mo:02d}-{d_:02d}T02:00:00.000Z"
    med = [{"url": IMG + s} for s in slides(seri)]
    ada = [x for x in milik
           if any((m.get("url") or "").split("/")[-1].startswith(f"uky_car_{seri}_01") for m in (x.get("medias") or []))]
    if not go:
        aksi = f"PUT {ada[0]['_id']}" if ada else "CREATE"
        print(f"[{seri}] (dry) {aksi} | {TANGGAL[seri]} 09:00 WIB | {len(med)} slide")
        continue
    if ada:
        x = ada[0]
        c.update_schedule(x["_id"], {"description": caps[seri], "title": judul_jadwal(seri),
                                     "topic": x.get("topic"), "medias": med, "scheduleAt": saat})
        b = c.get_schedule(x["_id"])
    else:
        res = c.create_schedule(UKY, caps[seri], saat, title=judul_jadwal(seri), topic="Bisnis & Strategi",
                                type_="album", medias=med, replies=[])
        time.sleep(0.5)
        b = c.get_schedule(res.get("scheduleId") or res.get("_id") or res.get("id"))
    bb = b.get("data", b) if isinstance(b, dict) else b
    urut = [(m.get("url") or "").split("/")[-1] for m in (bb.get("medias") or [])]
    print(f"[{seri}] {'PUT' if ada else 'CREATE'} {bb.get('_id')} | {bb.get('status')} | {bb.get('scheduleAt')} | "
          f"{len(urut)} slide | urut={'OK' if urut == slides(seri) else urut} | {bb.get('title')}")
