#!/usr/bin/env python3
"""Re-air TSC yang gagal serentak 20 Sep 2026 + carousel tahi lalat Threads.

Keputusan Bos 21 Sep: "gas".
Target (WIB):
  - IG       23 Sep 17:00  tsc_ig_baru_1.jpg    (post #1 seri stock baru)
  - Threads  23 Sep 09:00  tsc_thr_baru_1.jpg   (idem, caption <=500)
  - FB       23 Sep 19:30  tsc_fb_baru_1.jpg    (replies wajib [])
  - LinkedIn 23 Sep 08:00  tsc_li_baru_1.jpg    (replies wajib [])
  - Threads  25 Sep 09:00  carousel tahi lalat (3 slide) — re-air yang error 16 Sep

Caption diambil apa adanya dari doc error 20 Sep (biar tidak ada teks baru yang belum disetujui).
Usage: python3 reschedule_tsc_20sep.py preview | run
"""
import json
import subprocess
import sys
import time

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

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
IMG = "https://mantapserver.tail3947bb.ts.net/openclaw-img/"
LOG = f"{WS}/tsc_reschedule_20sep_log.json"

TSC_FB = "6a3b41ddc5ff4ce3a327542c"
TSC_LI = "6a4da7f520e4f4f195e796e1"

# doc error 20 Sep yang jadi sumber caption
SRC_IG = "6aacdfaa9aa606c3bdaca56c"
SRC_TH = "6aace2849aa606c3bdad17f0"
SRC_FB = "6aace2859aa606c3bdad1818"
SRC_LI = "6aace2869aa606c3bdad1832"
SRC_TH_TAHI = "6aa626e0b595e690a63d060e"

TARGETS = [
    ("IG", ACC.TSC_IG, SRC_IG, "2026-09-23T10:00:00.000Z",
     [{"url": IMG + "tsc_ig_baru_1.jpg", "type": "image", "alt": "tsc_ig_baru_1.jpg"}], "image"),
    ("Threads", ACC.TSC_THREADS, SRC_TH, "2026-09-23T02:00:00.000Z",
     [{"url": IMG + "tsc_thr_baru_1.jpg", "type": "image", "alt": "tsc_thr_baru_1.jpg"}], "image"),
    ("FB", TSC_FB, SRC_FB, "2026-09-23T12:30:00.000Z",
     [{"url": IMG + "tsc_fb_baru_1.jpg", "type": "image", "alt": "tsc_fb_baru_1.jpg"}], "image"),
    ("LinkedIn", TSC_LI, SRC_LI, "2026-09-23T01:00:00.000Z",
     [{"url": IMG + "tsc_li_baru_1.jpg", "type": "image", "alt": "tsc_li_baru_1.jpg"}], "image"),
    ("Threads", ACC.TSC_THREADS, SRC_TH_TAHI, "2026-09-25T02:00:00.000Z",
     [{"url": IMG + f"tsc_tahilalat_{i:02d}.jpg", "type": "image",
       "alt": f"tsc_tahilalat_{i:02d}"} for i in range(1, 4)], "album"),
]

TITLES = {SRC_TH_TAHI: "The Skin Code Clinic — Carousel Solusi Menghilangkan Tahi Lalat"}


def semua_jadwal():
    c = get_client()
    first = c.get_schedules(page=1, limit=100)
    docs = list(first.get("docs", []))
    for p in range(2, (first.get("totalDocs", 0) + 99) // 100 + 1):
        docs.extend(c.get_schedules(page=p, limit=100).get("docs", []))
    return docs


def cek_media(url):
    r = subprocess.run(["curl", "-s", "-o", "/dev/null", "-w", "%{http_code} %{size_download}",
                        "--max-time", "60", url], capture_output=True, text=True)
    return r.stdout.strip()


def main():
    mode = sys.argv[1] if len(sys.argv) > 1 else "preview"
    docs = {d.get("id"): d for d in semua_jadwal()}

    plan = []
    print(f"=== {'RUN' if mode == 'run' else 'PREVIEW'} — re-air TSC ===")
    for tag, acc, src, at, medias, typ in TARGETS:
        s = docs.get(src)
        assert s, f"doc sumber {src} tidak ketemu"
        cap = s.get("description") or ""
        assert cap, f"caption kosong untuk {src}"
        if tag == "Threads":
            assert len(cap) <= 500, f"Threads {len(cap)} char > 500"
        for m in medias:
            code = cek_media(m["url"])
            ok = code.startswith("200")
            print(f"  media {m['url'].rsplit('/', 1)[-1]:26s} → {code} {'✅' if ok else '❌ STOP'}")
            assert ok, "media tidak siap → stop"
        print(f"  [{tag:8s}] {at} | {typ} | {len(cap)} char | {medias[0]['url'].rsplit('/', 1)[-1]}")
        plan.append({"platform": tag, "acc": acc, "at": at, "caption": cap,
                     "medias": medias, "type": typ, "src": src})

    # pastikan slot belum terisi (anti duplikat)
    for p in plan:
        bentrok = [d for d in docs.values()
                   if d.get("accountId") == p["acc"] and d.get("scheduleAt") == p["at"]
                   and (d.get("status") or "").lower() not in ("error", "failed")]
        if bentrok:
            print(f"  ⚠️ slot {p['at']} akun {p['platform']} sudah ada jadwal {bentrok[0].get('id')} — SKIP")
            p["skip"] = True
        for m in p["medias"]:
            sudah = [d for d in docs.values() if d.get("accountId") == p["acc"]
                     and m["url"] in json.dumps(d.get("medias") or [])
                     and (d.get("status") or "").lower() not in ("error", "failed")]
            if sudah:
                print(f"  ⚠️ {p['platform']} sudah punya {m['url'].rsplit('/', 1)[-1]} ({sudah[0].get('id')}) — SKIP")
                p["skip"] = True

    if mode != "run":
        print("\n(preview saja). Jalankan: python3 reschedule_tsc_20sep.py run")
        return

    c = get_client()
    log = []
    for p in plan:
        if p.get("skip"):
            print(f"  ⏭️  {p['platform']} {p['at']} dilewati (sudah ada)")
            continue
        res = c.create_schedule(p["acc"], p["caption"], p["at"],
                                title=TITLES.get(p["src"], ""), topic="Edukasi Kulit",
                                type_=p["type"], medias=p["medias"], replies=[])
        sid = res.get("scheduleId") or res.get("_id") or res.get("id")
        print(f"  ✅ {p['platform']:8s} {p['at']} → {sid} | {str(res)[:100]}")
        log.append({"platform": p["platform"], "at": p["at"], "id": sid, "src": p["src"],
                    "media": [m["url"] for m in p["medias"]]})
        time.sleep(1)

    json.dump(log, open(LOG, "w"), indent=1, ensure_ascii=False)
    print(f"\nlog → {LOG}")

    print("\n=== VERIFIKASI (tarik ulang dari API) ===")
    fresh = {d.get("id"): d for d in semua_jadwal()}
    for row in log:
        d = fresh.get(row["id"])
        if not d:
            print(f"  ❌ {row['platform']} {row['at']}: {row['id']} tidak ketemu di dump")
            continue
        med = [m["url"].rsplit("/", 1)[-1] for m in (d.get("medias") or [])]
        print(f"  {row['platform']:8s} | {d.get('scheduleAt')} | {d.get('status')} | "
              f"{d.get('type')} | replies={len(d.get('replies') or [])} | {med}")


if __name__ == "__main__":
    main()
