#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""pasang_album_korea_uky.py — carousel FOTO KOREA di Threads @ukyhandoko.

Perintah Bos 4 Okt 2026: "Beberapa postingan tiap hari juga sesekali share tentang foto
foto di Korea. Pakai carousel minimal 10 images sekali bahas tentang Korea."

Isi: album (type=album) 10 foto Korea milik Bos yang sudah ada di media server
(`openclaw-img/Bukchon_*`, `SeoulHujan_*`, `AlbumKorea_*` — semua 1600x1202), caption
bahasa Indonesia yang membahas Korea dari sudut fotografer + pelajaran kerja.
Slot: 09:00 WIB (aturan album) setiap 2 hari. `replies=[]`, tanpa link, 0 mention, 0 CJK.

Pakai: python3 pasang_album_korea_uky.py            (dry run + gate URL)
       python3 pasang_album_korea_uky.py --run
"""
import sys, json, datetime, subprocess
sys.path.insert(0, "/home/mantapman/.hermes/profiles/atun/workspace")
from repliz_client import ReplizClient, ACC
from bank_fotografi_uky import validasi

WIB = datetime.timezone(datetime.timedelta(hours=7))
RUN = "--run" in sys.argv
BASE = "https://mantapserver.tail3947bb.ts.net/openclaw-img"
INGRESS = ["103.84.155.153", "103.84.155.217"]
HOST = "mantapserver.tail3947bb.ts.net"
JAM = 9
TOPIC = "Foto Korea"
STATE = "/home/mantapman/.hermes/profiles/atun/workspace/album_korea_uky_state.json"

ALBUMS = [
{
 "tgl": "2026-10-06", "tema": "Gyeongbokgung",
 "files": ["AlbumKorea_01_Gyeongbokkung.jpg", "AlbumKorea_02_DSCF8622ok.jpg",
           "AlbumKorea_03_DSCF8624ok.jpg", "AlbumKorea_05_DSCF8837ok.jpg",
           "AlbumKorea_06_DSCF8873ok.jpg", "AlbumKorea_07_DSCF8882ok.jpg",
           "AlbumKorea_08_DSCF8886ok.jpg", "AlbumKorea_09_DSCF8895ok.jpg",
           "AlbumKorea_11_DSCF8924ok.jpg", "AlbumKorea_15_DSCF8954ok.jpg"],
 "caption": """Gyeongbokgung jam 9 pagi, dan saya langsung paham kenapa orang Korea bangga sama sejarahnya.

Bukan cuma bangunan tua: ada kolam yang memantulkan atap, jalan batu berumur ratusan tahun, dan pengunjung yang sengaja pakai hanbok.

Tempat seperti ini ngajarin saya sabar: nunggu kerumunan lewat, nunggu air kolam tenang.

Kalau ke Korea, kamu pilih kotanya dulu atau sejarahnya dulu? Ceritakan di komentar.

#korea #seoul #gyeongbokgung #fotografi""",
},
{
 "tgl": "2026-10-08", "tema": "Bukchon Hanok Village",
 "files": ["Bukchon_01.jpg", "Bukchon_05.jpg", "Bukchon_06.jpg", "Bukchon_07.jpg",
           "Bukchon_08.jpg", "Bukchon_09.jpg", "Bukchon_10.jpg", "Bukchon_14.jpg",
           "Bukchon_18.jpg", "Bukchon_19.jpg"],
 "caption": """Bukchon Hanok Village waktu hujan jadi hari favorit saya di Seoul.

Gang-nya sempit, rumahnya masih bentuk hanok, dan payung warna-warni jadi aksen yang tidak mungkin saya atur.

Yang menarik, warga di sana tetap hidup normal. Turisnya ramai, tapi kampungnya tidak kehilangan fungsinya.

Kamu lebih suka tempat wisata yang masih dihuni warga atau yang sepi? Ceritakan di komentar ya.

#korea #seoul #bukchon #hanok""",
},
{
 "tgl": "2026-10-10", "tema": "Seoul saat hujan",
 "files": ["SeoulHujan_01.jpg", "SeoulHujan_02.jpg", "SeoulHujan_06.jpg", "SeoulHujan_10.jpg",
           "SeoulHujan_15.jpg", "SeoulHujan_17.jpg", "SeoulHujan_21.jpg", "SeoulHujan_22.jpg",
           "SeoulHujan_29.jpg", "SeoulHujan_30.jpg"],
 "caption": """Seoul saat hujan beda total: aspal hitam mengkilap, lampu kota memantul, orang jalan lebih cepat.

Saya jalan tanpa rencana, cuma bawa kamera dan payung. Hasilnya frame yang tidak saya dapat waktu cerah: taksi, kabel kusut, tulisan yang tidak saya mengerti.

Pelajaran yang saya bawa pulang: rencana terlalu rapi bikin kehilangan hal tak terduga.

Menurut kamu, tanpa rencana itu kaya pengalaman atau buang waktu? Tulis di komentar.

#korea #seoul #hujan #streetphotography""",
},
{
 "tgl": "2026-10-12", "tema": "Detail kecil Korea",
 "files": ["Bukchon_03.jpg", "SeoulHujan_04.jpg", "Bukchon_11.jpg", "SeoulHujan_09.jpg",
           "SeoulHujan_05.jpg", "Bukchon_13.jpg", "SeoulHujan_19.jpg", "SeoulHujan_08.jpg",
           "SeoulHujan_23.jpg", "SeoulHujan_34.jpg"],
 "caption": """Yang paling saya bawa pulang dari Korea bukan foto istana, tapi detail kecil.

Tulisan warung yang saya tidak bisa baca, pintu kayu yang catnya retak, nomor rumah yang digantung di dinding bata, papan nama jalan yang bertumpuk di satu tiang.

Detail begitu yang bikin foto terasa seperti tempat, bukan katalog wisata. Cara kerja saya ke klien juga sama.

Detail apa yang paling kamu perhatikan kalau jalan-jalan? Tulis di komentar.

#korea #seoul #detail #fotografi""",
},
]

cli = ReplizClient()


def url_ok(url):
    """200 di KEDUA ingress funnel (jalur yang dilihat Repliz)."""
    hasil = []
    for ip in INGRESS:
        r = subprocess.run(["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}",
                            "--max-time", "25", "--resolve", f"{HOST}:443:{ip}", url],
                           capture_output=True, text=True)
        hasil.append(r.stdout.strip())
    return all(h == "200" for h in hasil), hasil


def slot_terisi():
    isi, page = set(), 1
    while True:
        d = cli.get(f"/public/schedule?page={page}&limit=100")
        for s in d.get("docs") or []:
            if s.get("accountId") != ACC.UKY_THREADS:
                continue
            if s.get("status") not in ("pending", "processing", "draft"):
                continue
            iso = s.get("scheduleAt")
            if not iso:
                continue
            dt = datetime.datetime.fromisoformat(iso.replace("Z", "+00:00")).astimezone(WIB)
            isi.add((dt.date().isoformat(), dt.hour))
        if page >= (d.get("totalPages") or 1):
            break
        page += 1
    return isi


def utama():
    print("=== validasi caption + gate URL (200 di dua ingress) ===")
    siap = []
    for a in ALBUMS:
        m = validasi(a["caption"])
        print(f"— {a['tgl']} {a['tema']}: caption {len(a['caption'])} char, "
              f"{len(a['files'])} foto, validasi {'OK' if not m else m}")
        if m:
            continue
        gagal = []
        for f in a["files"]:
            ok, kode = url_ok(f"{BASE}/{f}")
            if not ok:
                gagal.append(f"{f} {kode}")
        if gagal:
            print(f"   ❌ URL bukan 200: {gagal}")
            continue
        print(f"   ✅ 10/10 foto 200 di kedua ingress")
        siap.append(a)

    terpakai = slot_terisi()
    print(f"\n=== pasang ({'RUN' if RUN else 'DRY RUN'}) ===")
    hasil = []
    for a in siap:
        tgl = datetime.date.fromisoformat(a["tgl"])
        if (a["tgl"], JAM) in terpakai:
            print(f"⏭️  {a['tgl']} 09:00 sudah terisi — skip")
            continue
        urls = [f"{BASE}/{f}" for f in a["files"]]
        judul = f"uky {TOPIC} — {a['tema']} {a['tgl']}"
        schedule_at = cli.make_schedule(tgl.year, tgl.month, tgl.day, JAM, 0, wib=True)
        print(f"— {a['tgl']} 09:00 WIB | {judul} | {schedule_at}")
        if not RUN:
            continue
        res = cli.create_schedule(ACC.UKY_THREADS, a["caption"], schedule_at, title=judul,
                                  topic=TOPIC, type_="album",
                                  medias=[cli.make_media(u, "image") for u in urls], replies=[])
        sid = res.get("scheduleId") or res.get("_id") or res.get("id")
        if not sid:
            print(f"   ❌ create gagal: {res}")
            continue
        s = cli.get_schedule(sid)
        s = s.get("schedule") or s
        med = [mm.get("url") for mm in (s.get("medias") or [])]
        dt = datetime.datetime.fromisoformat(s["scheduleAt"].replace("Z", "+00:00")).astimezone(WIB)
        baik = (s.get("status") == "pending" and s.get("type") == "album" and med == urls
                and dt.date() == tgl and dt.hour == JAM and len(s.get("description") or "") == len(a["caption"])
                and not (s.get("replies") or []))
        print(f"   {'✅' if baik else '⚠️'} id={sid} status={s.get('status')} type={s.get('type')} "
              f"{len(med)} media urut={'ya' if med == urls else 'TIDAK'} jam={dt:%d %b %H:%M} WIB")
        hasil.append({"id": sid, "tgl": a["tgl"], "tema": a["tema"], "status": s.get("status"),
                      "media": len(med), "urut_benar": med == urls, "verified": bool(baik)})

    if RUN and hasil:
        json.dump({"dipasang_at": datetime.datetime.now(WIB).isoformat(), "hasil": hasil},
                  open(STATE, "w"), indent=1)
        print(f"\nstate -> {STATE}")


if __name__ == "__main__":
    utama()
