#!/usr/bin/env python3
"""StudioSoft Healthcare Carousel — hc26 10 Channel Digital Marketing RS & Klinik (cron run)
Posts the 5-slide carousel (album) to Threads + LinkedIn + FB
at the next common-free 7-slot, with nested replies on Threads + discussion hooks.

FIX 2 Sep 2026 (learned from hc23-hc25 errors): LinkedIn & FB reply-schedules to an
album ERROR at post time ("Cannot read properties of undefined (reading 'postId')"),
4/4 failures. So LinkedIn & FB get the album with article link + hashtags embedded in
the description and NO reply schedules. Threads replies to albums are proven (success).
"""
import json, os, sys
from datetime import datetime, timezone, timedelta
from repliz_client import ReplizClient, ACC
from diskusi_engine import tambahkan_diskusi

c = ReplizClient()

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

ARTICLE_URL = "https://studiosoft.id/10-channel-digital-marketing-rumah-sakit-yang-wajib-dikelola-di-era-online/"

# TOPIK #26 — state index 25
TOPIC = "10 Channel Digital Marketing RS & Klinik yang Wajib Dikelola"
HASHTAG_LINE = "#StudioSoft #ChannelRS #DigitalMarketing #RumahSakit #Klinik #HealthcareDigital"

THREADS = tambahkan_diskusi(
    ('Pasien kini mencari RS/klinik lewat banyak pintu: Google, Instagram, WhatsApp, '
     'sampai ulasan online. RS yang hanya andal di satu channel otomatis kehilangan '
     'calon pasien di channel lain.\n\n'
     'Kabar baiknya: tidak perlu langsung mengelola 10 channel. Mulai dari channel yang '
     'paling sering dipakai pasien Anda — website, Google, dan WhatsApp — lalu perluas '
     'bertahap. Konsistensi lebih penting daripada jumlah channel.'),
    platform='threads', industri='rumah_sakit', tone='netral', force=True)

LINKEDIN = tambahkan_diskusi(
    ('10 channel digital marketing yang wajib dikelola RS dan klinik di era online:\n\n'
     '1. Website rumah sakit — pusat informasi & pendaftaran\n'
     '2. Google (SEO + Business Profile) — tempat pasien mencari\n'
     '3. WhatsApp & booking online — komunikasi cepat\n'
     '4. Instagram — edukasi visual & cerita pasien\n'
     '5. Facebook — menjangkau komunitas lebih luas\n'
     '6. TikTok & Reels — konten pendek yang mudah tersebar\n'
     '7. YouTube — edukasi kesehatan yang mendalam\n'
     '8. Ulasan pasien online — fondasi kepercayaan\n'
     '9. Iklan digital (Google/Meta) — mempercepat hasil\n'
     '10. Landing page pendaftaran — mengubah minat jadi janji temu\n\n'
     'Kuncinya bukan mengelola semuanya sekaligus, tapi konsisten di channel yang tepat '
     'untuk pasien Anda.\n\n'
     f'Baca artikel lengkapnya: {ARTICLE_URL}\n\n'
     f'{HASHTAG_LINE}'),
    platform='linkedin', industri='rumah_sakit', tone='opini', force=True)

FB = tambahkan_diskusi(
    ('Rumah sakit dan klinik kini harus hadir di banyak channel digital — karena calon '
     'pasien tersebar di mana-mana.\n\n'
     'Channel yang wajib diperhatikan:\n'
     '✓ Website rumah sakit (pusat info & pendaftaran)\n'
     '✓ Google: SEO + Business Profile\n'
     '✓ WhatsApp & booking online\n'
     '✓ Instagram, Facebook, TikTok, YouTube\n'
     '✓ Ulasan pasien online\n'
     '✓ Iklan digital (Google/Meta)\n'
     '✓ Landing page pendaftaran\n\n'
     'Tidak perlu semuanya sekaligus: kuasai dulu channel yang paling sering dipakai '
     'pasien Anda, lalu kembangkan bertahap. Konsistensi lebih penting daripada jumlah '
     'channel.\n\n'
     f'Baca artikel lengkapnya: {ARTICLE_URL}\n\n'
     f'{HASHTAG_LINE}'),
    platform='facebook', industri='rumah_sakit', tone='sanjungan', force=True)


def find_common_free_slot(account_ids, max_days=25):
    """Cari slot 7-slot (05/08/11/14/17/20/23 WIB) pertama yang KOSONG di SEMUA akun.
    Cluster slot dianggap terisi kalau ada pending pada H:00..H:04 UTC (termasuk reply :01/:02)."""
    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])  # normalisasi ke "YYYY-MM-DDTHH:MM:SS"
        if page >= (d.get("totalPages") or 1):
            break
        page += 1

    def occupied(aid, dt_wib):
        # cek 5 menit cluster (H:00..H:04) dalam representasi UTC
        for off in range(5):
            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=45):
                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_hc26_{f}")
        if not u:
            print(f"GAGAL upload {f}")
            return None
        urls.append(u)
        print(f"OK {f} -> {u.split('/')[-1]}")
    return urls


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

    slot_wib = find_common_free_slot([ACC.STUDIOSOFT_THREADS, ACC.STUDIOSOFT_LINKEDIN,
                                      ACC.STUDIOSOFT_FB])
    if not slot_wib:
        print("TIDAK ADA slot kosong bersama di 25 hari ke depan — lapor Bos.")
        return False
    slot = slot_wib.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
    print(f"Slot kosong bersama berikutnya: {slot_wib.strftime('%Y-%m-%d %H:%M')} WIB -> UTC {slot}")

    url = upload_slides()
    if not url:
        return False
    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 sukses hc19-hc25) ──
    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 strategi konten digital RS/klinik:\nwww.studiosoft.id",
            r2, type_="text", replies=[pid])
        c.create_schedule(ACC.STUDIOSOFT_THREADS,
            "#StudioSoft #ChannelRS #DigitalMarketing #RumahSakit #Klinik",
            r3, type_="text", replies=[pid])
        print("  OK 2 replies")
        results["threads"] = True
    except Exception as e:
        print(f"  GAGAL {e}")
        results["threads"] = False

    # ── LINKEDIN: album saja, NO replies (replies ke album selalu error) ──
    print("\nLINKEDIN:")
    try:
        album = c.schedule_album(ACC.STUDIOSOFT_LINKEDIN, LINKEDIN, slot, medias, title=TOPIC)
        pid = album.get("scheduleId") or album.get("_id")
        print(f"  OK Album -> {pid}")
        results["linkedin"] = True
    except Exception as e:
        print(f"  GAGAL {e}")
        results["linkedin"] = False

    # ── FACEBOOK: album saja, NO replies (pola hc23-hc25 reply FB selalu error) ──
    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:
        state = {"index": 25, "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")
    return ok


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