#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Konten VISUAL Threads untuk growth: gambar quotes @ukyhandoko + carousel StudioSoft.
Diisi di slot kosong (27 Sep+). Caption ≤500 char + ajakan diskusi.
"""
import sys, json, os, shutil, urllib.request
from datetime import datetime, timedelta, timezone
sys.path.insert(0, "/home/mantapman/.openclaw/workspace-atun")
from repliz_client import HEADERS, BASE
from pangkas_threads import batasi

WIB = timezone(timedelta(hours=7))
SLOTS = [5, 8, 11, 14, 17, 20, 23]
UKY = "6a334e89c5ff4ce3a3225a48"
SS = "6a335b9ec5ff4ce3a3225c2a"
IMG_DIR = "/home/mantapman/.openclaw/workspace-atun/openclaw-img"
IMG_URL = "https://mantapserver.tail3947bb.ts.net/openclaw-img/"

# tema + caption gambar quotes uky
UKY_IMGS = {
    "02_blue_website_optimasi.png": ("Optimasi website itu bukan sekali kerja, tapi kebiasaan. Cek kecepatan, konten, dan pengalaman pengguna setiap bulan. 🔧", "website"),
    "03_blue_3_hal_bisnis.png": ("3 hal yang bikin bisnis digital tumbuh: website yang benar, konten yang konsisten, dan data yang dibaca. 📈", "bisnis"),
    "04_white_leadership.png": ("Leadership bukan soal paling pintar di ruangan, tapi soal bikin orang lain tumbuh. 🌱", "leadership"),
    "05_white_brand.png": ("Brand yang kuat lahir dari konsistensi, bukan dari sekali viral. 🎯", "branding"),
    "06_white_gagal.png": ("Gagal itu biaya kursus, bukan akhir segalanya. Yang penting: catat, pelajari, perbaiki. 📝", "gagal"),
    "10_blue_geo.png": ("GEO — era baru SEO untuk AI search. Kontenmu harus jadi jawaban yang dikutip, bukan cuma peringkat. 🤖", "geo"),
    "11_white_meaning.png": ("Makna bisnis bukan cuma profit, tapi seberapa banyak orang yang hidupnya membaik karena usahamu. ✨", "makna"),
    "12_white_filosofi.png": ("Filosofi kerja saya: kecil tapi konsisten, lebih baik daripada besar tapi sekali jalan. 🌿", "filosofi"),
    "13_orange_website.png": ("Website itu etalase yang buka 24 jam. Kalau berantakan, orang pergi sebelum tahu produkmu. 🌐", "website"),
    "14_orange_kesalahan.png": ("Kesalahan yang paling mahal bukan salah langkah, tapi diam terlalu lama karena takut salah. 🚀", "kesalahan"),
    "15_blue_jangan_post.png": ("Jangan posting cuma karena harus posting. Posting karena ada nilai yang mau kamu bagikan. 💡", "konten"),
    "16_blue_personal_branding.png": ("Personal branding bukan pamer. Ini soal orang ingat kamu karena apa yang kamu bantu. 🙌", "personal branding"),
    "17_white_mindset.png": ("Mindset bertumbuh: setiap masalah itu data, setiap kegagalan itu umpan balik. 🧠", "mindset"),
    "18_white_modal.png": ("Modal terbesar bukan uang, tapi kemauan belajar dan konsistensi menjalankannya. 💪", "modal"),
    "19_orange_klien_ideal.png": ("Klien ideal bukan yang bayar paling mahal, tapi yang cocok nilai dan visinya sama kita. 🤝", "klien"),
    "20_orange_klien_pergi.png": ("Klien pergi bukan selalu karena harga — sering karena komunikasi yang kurang dijaga. 📞", "klien"),
}

# carousel SSIGSEP untuk StudioSoft
SS_ALBUMS = [5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 18, 19, 20]

def compress_to_jpg(src, dst, max_kb=120, quality=82):
    """Kompres gambar ke JPEG ringan (≤ max_kb kalau bisa). Return path."""
    from PIL import Image
    img = Image.open(src)
    if img.mode in ("RGBA", "LA", "P"):
        bg = Image.new("RGB", img.size, (255, 255, 255))
        img = img.convert("RGBA")
        bg.paste(img, mask=img.split()[-1])
        img = bg
    else:
        img = img.convert("RGB")
    # batasi lebar maksimal 1080 (standar feed)
    if img.width > 1080:
        ratio = 1080 / img.width
        img = img.resize((1080, int(img.height * ratio)), Image.LANCZOS)
    q = quality
    while q >= 55:
        img.save(dst, format="JPEG", quality=q, optimize=True, progressive=True)
        if os.path.getsize(dst) <= max_kb * 1024 or q <= 55:
            break
        q -= 7
    return dst


def get_pending(accid):
    out = []
    for p in range(1, 90):
        raw = urllib.request.Request(f"{BASE}/public/schedule?page={p}&limit=100", headers=HEADERS)
        with urllib.request.urlopen(raw, timeout=30) as r:
            docs = json.load(r)["docs"]
        for d in docs:
            if d.get("accountId") == accid and (d.get("status") or "").lower() == "pending":
                out.append(d)
    return out

def taken_set(pend):
    s = set()
    for d in pend:
        at = d.get("scheduleAt") or ""
        try:
            dt = datetime.fromisoformat(at.replace("Z", "+00:00")).astimezone(WIB)
            s.add(dt.strftime("%Y-%m-%d %H"))
        except Exception:
            continue
    return s

def next_slot(day, taken):
    for _ in range(30):
        for h in SLOTS:
            cand = day.replace(hour=h)
            if cand <= datetime.now(WIB):
                continue
            if cand.strftime("%Y-%m-%d %H") not in taken:
                return cand
        day += timedelta(days=1)
    return None

def create(accid, cap, at, title, topic, medias, type_):
    payload = {"accountId": accid, "title": title, "description": batasi(cap),
               "topic": topic, "type": type_, "medias": medias, "scheduleAt": at, "replies": []}
    req = urllib.request.Request(f"{BASE}/public/schedule", data=json.dumps(payload).encode(),
                                 headers={**HEADERS, "Content-Type": "application/json"})
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.load(r)

# ── 1) uky: gambar quotes ──
pend = get_pending(UKY)
taken = taken_set(pend)
day = datetime.now(WIB).replace(minute=0, second=0, microsecond=0)
cnt = 0
print("=== @ukyhandoko — gambar quotes ===")
for fn, (hook, tema) in UKY_IMGS.items():
    src = f"uky_threads_images/{fn}"
    if not os.path.exists(src):
        continue
    dst_name = "uky_quote_" + fn.replace(".png", ".jpg")
    dst = os.path.join(IMG_DIR, dst_name)
    if not os.path.exists(dst):
        compress_to_jpg(src, dst)
    slot = next_slot(day, taken)
    if slot is None:
        break
    taken.add(slot.strftime("%Y-%m-%d %H"))
    at = slot.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
    cap = f"{hook}\n\nMenurut kamu, bagaimana? Cerita di komentar! 👇\n\n#seo #digitalmarketing #bisnis #personalbranding"
    try:
        create(UKY, cap, at, f"Uky — Quote {tema}", tema,
               [{"url": IMG_URL + dst_name, "type": "image", "alt": dst_name}], "image")
        cnt += 1
        print(f"  ✅ {slot.strftime('%d/%m %H:00')} | {fn}")
    except Exception as e:
        print(f"  ❌ {fn}: {e}")
print(f"  → uky visual: {cnt}")

# ── 2) SS: carousel SSIGSEP ──
pend = get_pending(SS)
taken = taken_set(pend)
day = datetime.now(WIB).replace(minute=0, second=0, microsecond=0)
cnt2 = 0
print("\n=== StudioSoft — carousel ===")
for n in SS_ALBUMS:
    slides = sorted([f for f in os.listdir(IMG_DIR) if f.startswith(f"SSIGSEP_{n:02d}_")])
    if len(slides) < 4:
        continue
    slot = next_slot(day, taken)
    if slot is None:
        break
    taken.add(slot.strftime("%Y-%m-%d %H"))
    at = slot.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
    cap = ("Slide ini rangkuman tips digital marketing yang sering kami bagikan ke klien. 📊\n\n"
           "Poin pentingnya: fokus ke kebutuhan pelanggan, ukur hasilnya, dan konsisten.\n\n"
           "Bagian mana yang paling relevan buat bisnismu? Cerita di komentar! 👇\n\n"
           "#studiosoft #digitalmarketing #seo #bisnissurabaya")
    medias = []
    for s in slides[:4]:
        src = os.path.join(IMG_DIR, s)
        dst_name = f"ss_opt_{n:02d}_{s.split('_')[-1].replace('.jpg', '.jpg')}"
        dst = os.path.join(IMG_DIR, dst_name)
        if not os.path.exists(dst):
            compress_to_jpg(src, dst, max_kb=110, quality=80)
        medias.append({"url": IMG_URL + dst_name, "type": "image", "alt": dst_name})
    try:
        create(SS, cap, at, f"StudioSoft — Carousel {n:02d}", "Carousel", medias, "album")
        cnt2 += 1
        print(f"  ✅ {slot.strftime('%d/%m %H:00')} | SSIGSEP_{n:02d}")
    except Exception as e:
        print(f"  ❌ SSIGSEP_{n:02d}: {e}")
print(f"  → SS visual: {cnt2}")
print(f"\n📊 Total konten visual: {cnt + cnt2}")
