#!/usr/bin/env python3
"""StudioSoft Healthcare Carousel — hc32 "7 Aplikasi Mental Health Anak Usia 4-10 Tahun"
Cron run 8 Sep 2026 (19:00 UTC) = hc32 (state index 31).

ATURAN (5 Sep + koreksi hc30/hc31, Bos):
- LinkedIn StudioSoft: SKIP — semua artikel sudah punya text ss_li pending (artikel ini sudah
  terjadwal text LinkedIn 7 Okt via ss_li pipeline), nambah = duplikat URL. LinkedIn text HC
  hanya kalau ada artikel BARU di studiosoft.id (terbaru 3 Sep, sudah masuk kuota).
- Threads + FB: album carousel TETAP OK. IG: jangan sentuh (carousel SSIGSEP jalan sendiri).
- Sumber artikel: 16 slug artikel healthcare-marketing studiosoft.id HABIS dipakai hc01-hc31
  (hc31 = yg terakhir). Artikel ini (7 aplikasi mental health anak) = artikel healthcare
  studiosoft.id tersisa yg BELUM pernah jadi carousel seri hc; pernah jadi text FB 15 Agu
  (batch lama) — reuse preseden hc22/hc24/hc31; konten carousel 100% baru.
"""
import json, os, sys, re, urllib.request
from datetime import datetime, timezone, timedelta

sys.path.insert(0, "/home/mantapman/.hermes/profiles/atun/workspace")
from repliz_client import ReplizClient, ACC
from diskusi_engine import tambahkan_diskusi

c = ReplizClient()

CAROUSEL_DIR = os.path.expanduser("~/.openclaw/workspace-atun/studiosoft_hc32_carousel")
SLIDE_FILES = ["01_cover.png", "02_kenapa.png", "03_isi.png", "04_lanjutan.png", "05_cta.png"]

ARTICLE_URL = "https://studiosoft.id/7-aplikasi-mental-health-anak-usia-4-10-tahun-yang-harus-dicoba-orang-tua/"

# TOPIK #32 — state index 31
TOPIC = "7 Aplikasi Mental Health Anak Usia 4-10 Tahun: Bantu Si Kecil Mengelola Emosi di Era Digital"
HASHTAG_LINE = "#studiosoft #kesehatamental #aplikasianak #parentingdigital #healthcare"

THREADS = tambahkan_diskusi(
    ("Kesehatan mental anak di era digital itu nyata: anak usia 4-10 tahun sedang belajar "
     "mengenali emosi, dan teknologi bisa jadi alat bantu — asal dipilih tepat dan didampingi.\n"
     "\n"
     "Ada 7 aplikasi yang bisa dicoba: Worry Dolls (curhat lewat boneka kekhawatiran), "
     "Mindful Powers (mindfulness lewat game), Calm Kids (meditasi & napas), Smiling Mind "
     "(program psikolog), Breathe Think Do with Sesame, Headspace for Kids, sampai "
     "Super Stretch Yoga.\n"
     "\n"
     "Kuncinya satu: dampingi anak saat memakainya."),
    platform='threads', industri='kesehatan', tone='netral', force=True)

FB = tambahkan_diskusi(
    ("Anak usia 4-10 tahun sedang berada di fase emas belajar mengenali emosi. Di era "
     "digital, aplikasi mental health bisa jadi alat bantu yang menyenangkan — selama "
     "orang tua mendampingi.\n"
     "\n"
     "Artikel StudioSoft merangkum 7 aplikasi pilihan:\n"
     "1. Worry Dolls — anak mencurahkan kecemasan lewat boneka kekhawatiran interaktif.\n"
     "2. Mindful Powers — latihan mindfulness lewat permainan, belajar kelola stres.\n"
     "3. Calm Kids — meditasi singkat & latihan pernapasan untuk usia dini.\n"
     "4. Smiling Mind — program berbasis studi dari psikolog, sesi sesuai usia.\n"
     "5. Breathe, Think, Do with Sesame — tokoh Sesame Street mengajarkan berpikir positif "
     "dan empati.\n"
     "6. Headspace for Kids — meditasi berpemandu suara ramah plus cerita yang menenangkan.\n"
     "7. Super Stretch Yoga — yoga & relaksasi untuk kesadaran tubuh dan kebiasaan sehat.\n"
     "\n"
     "Tipsnya: pilih yang sesuai usia anak, dampingi saat dipakai, dan jadikan momen untuk "
     "mengobrol tentang perasaannya. Aplikasi bukan pengganti peran orang tua.\n"
     "\n"
     "Bagi RS, klinik, dan layanan kesehatan lain, konten edukasi seperti ini juga bisa "
     "menjadi strategi membangun kepercayaan pasien — konsultasi gratis: www.studiosoft.id\n"
     "\n"
     f"Baca artikel lengkapnya: {ARTICLE_URL}\n"
     "\n"
     f"{HASHTAG_LINE}"),
    platform='facebook', industri='kesehatan', tone='sanjungan', force=True)


def find_free_slot(account_ids, max_days=30):
    """Slot :00 WIB pertama yg bebas (6-menit window) di SEMUA account_ids."""
    slots = [5, 8, 11, 14, 17, 20, 23]
    now_wib = datetime.now(timezone(timedelta(hours=7)))
    pending = {aid: set() for aid in account_ids}
    page = 1
    while True:
        d = c.get(f"/public/schedule?page={page}&limit=100")
        docs = d.get("docs", [])
        for s in docs:
            aid = s.get("accountId")
            if aid not in pending:
                continue
            if s.get("status") not in ("pending", "scheduled", "draft"):
                continue
            st = s.get("scheduleAt", "")
            if st:
                pending[aid].add(st[:19])
        if page >= (d.get("totalPages") or 1):
            break
        page += 1

    def occupied(aid, dt_wib):
        for off in range(6):
            u = (dt_wib + timedelta(minutes=off)).astimezone(timezone.utc)
            if u.strftime("%Y-%m-%dT%H:%M:%S") in pending[aid]:
                return True
        return False

    for day in range(max_days + 1):
        day_dt = now_wib + timedelta(days=day)
        for hour in slots:
            cand = datetime(day_dt.year, day_dt.month, day_dt.day, hour, 0,
                            tzinfo=timezone(timedelta(hours=7)))
            if cand <= now_wib + timedelta(minutes=90):
                continue
            if all(not occupied(aid, cand) for aid in account_ids):
                return cand
    return None


def upload_slides():
    urls = []
    for f in SLIDE_FILES:
        p = os.path.join(CAROUSEL_DIR, f)
        u = c.upload_to_wp(p, filename=f"ss_hc32_{f}")
        if not u:
            print(f"GAGAL upload {f}")
            return None
        urls.append(u)
        print(f"OK {f} -> {u.split('/')[-1]}")
    return urls


def verify(urls, slot_utc):
    """Re-list pending akun TH+FB: cari jadwal dgn media ss_hc32_01_cover.jpg."""
    need = urls[0].split("/")[-1]
    hits = []
    page = 1
    while True:
        d = c.get(f"/public/schedule?page={page}&limit=100")
        for s in d.get("docs", []):
            if s.get("accountId") not in (ACC.STUDIOSOFT_THREADS, ACC.STUDIOSOFT_FB):
                continue
            if (s.get("status") or "").lower() != "pending":
                continue
            ms = [m.get("url", "") for m in (s.get("medias") or [])]
            if any(need in m for m in ms):
                hits.append((s.get("accountId"), (s.get("scheduleAt") or "")[:16],
                             (s.get("title") or "")[:45], len(ms)))
        if page >= (d.get("totalPages") or 1):
            break
        page += 1
    print("\nVERIFIKASI jadwal dgn media", need)
    for h in hits:
        print("  ", h)
    return hits


def main():
    wib = datetime.now(timezone(timedelta(hours=7)))
    print(f"Time WIB: {wib.strftime('%Y-%m-%d %H:%M')}")
    print(f"Threads len: {len(THREADS)} (<=500: {len(THREADS) <= 500})")
    if len(THREADS) > 500:
        print("Threads caption > 500 karakter, tolak kirim.")
        return False
    print(f"FB len: {len(FB)}")
    for name, txt in (("Threads", THREADS), ("FB", FB)):
        m = re.findall(r"@\w+", txt)
        if m:
            print(f"mention di {name}: {m}")
            return False
        if "#" in txt and re.findall(r"#[A-Z]", txt):
            print(f"hashtag KAPITAL di {name}")
            return False

    # LinkedIn TIDAK diikutkan (semua artikel sdh punya text ss_li pending) -> THREADS+FB saja
    slot_wib = find_free_slot([ACC.STUDIOSOFT_THREADS, ACC.STUDIOSOFT_FB])
    if not slot_wib:
        print("TIDAK ADA slot kosong bersama Threads+FB 30 hari — lapor Bos.")
        return False
    slot = slot_wib.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
    print(f"Slot kosong Threads+FB: {slot_wib.strftime('%Y-%m-%d %H:%M')} WIB -> UTC {slot}")

    url = upload_slides()
    if not url:
        return False
    for u in url:
        try:
            with urllib.request.urlopen(urllib.request.Request(u, method="HEAD"), timeout=20) as r:
                code = r.status
        except Exception as e:
            code = f"ERR {e}"
        print(f"  URL {u.split('/')[-1]}: {code}")
    medias = [c.make_media(u, "image", f"slide{i+1}") for i, u in enumerate(url)]

    base_dt = datetime.fromisoformat(slot.replace("Z", "+00:00"))
    r2 = (base_dt + timedelta(minutes=1)).strftime("%Y-%m-%dT%H:%M:%S.000Z")
    r3 = (base_dt + timedelta(minutes=2)).strftime("%Y-%m-%dT%H:%M:%S.000Z")

    results = {}

    # THREADS: album + 2 replies (pola hc19-hc31)
    print("\nTHREADS:")
    try:
        album = c.schedule_album(ACC.STUDIOSOFT_THREADS, THREADS, slot, medias, title=TOPIC)
        pid = album.get("scheduleId") or album.get("_id")
        print(f"  OK Album -> {pid}")
        c.create_schedule(ACC.STUDIOSOFT_THREADS,
            f"Baca selengkapnya: {ARTICLE_URL}\n\nKonsultasi kebutuhan digital klinik/RS & layanan kesehatan Anda: www.studiosoft.id",
            r2, type_="text", replies=[pid])
        c.create_schedule(ACC.STUDIOSOFT_THREADS,
            HASHTAG_LINE,
            r3, type_="text", replies=[pid])
        print("  OK 2 replies")
        results["threads"] = True
    except Exception as e:
        print(f"  GAGAL {e}")
        results["threads"] = False

    # FACEBOOK: album saja, NO replies (pola hc23-hc31)
    print("\nFACEBOOK:")
    try:
        album = c.schedule_album(ACC.STUDIOSOFT_FB, FB, slot, medias, title=TOPIC)
        pid = album.get("scheduleId") or album.get("_id")
        print(f"  OK Album -> {pid}")
        results["fb"] = True
    except Exception as e:
        print(f"  GAGAL {e}")
        results["fb"] = False

    print("\n" + "=" * 50)
    ok = all(results.values())
    print("Semua platform dijadwalkan!" if ok else f"Gagal: {[k for k, v in results.items() if not v]}")

    if ok:
        verify(url, slot)
        state = {"index": 31, "topic": TOPIC,
                 "last_post": wib.strftime("%Y-%m-%d %H:%M")}
        with open(os.path.expanduser("~/.openclaw/workspace-atun/studiosoft_healthcare_state.json"), "w") as f:
            json.dump(state, f)
        print("State updated -> index 31 (hc32)")
    return ok


if __name__ == "__main__":
    sys.exit(0 if main() else 1)
