#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""fix_story_canvas_ig_ss.py — perbaiki story IG StudioSoft yang kepotong kiri-kanan.

Perintah Bos 2 Okt 2026 (screenshot story mirror carousel properti yang teksnya terpotong):
*"Jangan kepotong gini kalo buat story IG StudioSoft. Revisi jika ada yang sudah dijadwal"*

Sebab: story mirror dibuat oleh `pasang_car10_*.py` / `pasang_car_generik.py` memakai slide 4:5
(1080x1350) APA ADANYA. IG memaksa media story memenuhi kanvas 9:16 → ~228 px terpotong per sisi.
Obat: slide ditaruh utuh di tengah kanvas 1080x1920 SEWARNA latar slide (piksel sudut (8,8)),
lalu URL media jadwal story di-PUT ke file kanvas itu.

Pakai:
  python3 fix_story_canvas_ig_ss.py            # dry run
  python3 fix_story_canvas_ig_ss.py --go       # eksekusi (kanvas + gate 200 + PUT + baca balik)
"""
import argparse
import datetime
import os
import subprocess
import sys
import time

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
sys.path.insert(0, WS)
from repliz_client import get_client, ReplizError, IMG_BASE_URL  # noqa: E402

IG_SS = "6a38ac33c5ff4ce3a3231232"
WIB = datetime.timezone(datetime.timedelta(hours=7))
IMG_DIR = os.path.join(WS, "openclaw-img")
HOST = "mantapserver.tail3947bb.ts.net"
INGRESS = ["103.84.155.153", "103.84.155.217"]
CW, CH = 1080, 1920


def semua(c):
    docs, page = [], 1
    while page <= 60:
        r = None
        for a in range(5):
            try:
                r = c.get_schedules(page=page, limit=100)
                break
            except Exception:
                time.sleep(4 + 2 * a)
        if r is None:
            raise SystemExit("gagal baca jadwal Repliz")
        b = r.get("docs") or []
        docs += b
        if len(b) < 100:
            break
        page += 1
    return docs


def cek_ingress(nama):
    url = f"https://{HOST}/openclaw-img/{nama}"
    for ip in INGRESS:
        kode = subprocess.run(["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "--max-time", "30",
                               "--resolve", f"{HOST}:443:{ip}", url],
                              capture_output=True, text=True).stdout.strip()
        print(f"      {ip}: {kode}")
        if kode != "200":
            return False
    return True


def kanvas(nama):
    """Slide 4:5 → 1080x1920 sewarna latar slide. Return nama file kanvas (atau None)."""
    src = os.path.join(IMG_DIR, nama)
    if not os.path.exists(src):
        return None, "file tidak ada di openclaw-img"
    from PIL import Image
    with Image.open(src) as im0:
        asli = im0.size
    if asli == (CW, CH):
        return nama, "sudah 9:16"
    baru = f"ss_story_canvas_{nama}"
    dst = os.path.join(IMG_DIR, baru)
    im = Image.open(src).convert("RGB")
    bg = im.getpixel((8, 8))
    if min(bg) >= 235:
        bg = (255, 255, 255)
    skala = min(CW / im.width, CH / im.height)
    kecil = im.resize((round(im.width * skala), round(im.height * skala)), Image.LANCZOS)
    knv = Image.new("RGB", (CW, CH), bg)
    knv.paste(kecil, ((CW - kecil.width) // 2, (CH - kecil.height) // 2))
    knv.save(dst, quality=90)
    print(f"      kanvas: {nama} {asli} → {baru} 1080x1920 (bg {bg}, {os.path.getsize(dst)//1024} KB)")
    return baru, f"{asli} → 1080x1920"


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--go", action="store_true")
    ap.add_argument("--akun", default=IG_SS)
    a = ap.parse_args()

    c = get_client()
    docs = [d for d in semua(c) if d.get("accountId") == a.akun and str(d.get("type")).lower() == "story"]
    sekarang = datetime.datetime.now(datetime.timezone.utc)

    target = []
    for d in docs:
        st = str(d.get("status") or "").lower()
        if st not in ("pending", "draft"):
            continue
        sa = str(d.get("scheduleAt") or "").replace("Z", "+00:00")
        try:
            dt = datetime.datetime.fromisoformat(sa)
        except Exception:
            continue
        if dt <= sekarang:
            continue
        meds = d.get("medias") or []
        if not meds:
            continue
        nama = (meds[0].get("url") or "").split("/")[-1]
        if nama.lower().endswith((".mp4", ".mov", ".m4v")):
            continue
        p = os.path.join(IMG_DIR, nama)
        if not os.path.exists(p):
            print(f"⚠️  {dt.astimezone(WIB):%d %b %H:%M}  {nama}: file lokal tidak ada — lewati")
            continue
        from PIL import Image
        try:
            with Image.open(p) as im:
                uk = im.size
        except Exception:
            continue
        if uk == (CW, CH):
            continue
        target.append((d, dt, nama, uk))

    print(f"akun {a.akun} | {len(docs)} jadwal story | sekarang {sekarang.astimezone(WIB):%d %b %H:%M} WIB")
    print(f"story PANDAI/TENGAH akan kepotong (media bukan 9:16): {len(target)}\n")
    for d, dt, nama, uk in target:
        print(f"  {d['_id']} | {dt.astimezone(WIB):%d %b %H:%M} WIB | status={d.get('status')} | "
              f"{nama} {uk[0]}x{uk[1]} | {d.get('title','')}")
    if not target:
        print("tidak ada yang perlu direvisi ✅")
        return
    if not a.go:
        print("\n(dry run — pakai --go untuk eksekusi)")
        return

    print("\n=== perbaikan ===")
    for d, dt, nama, uk in target:
        print(f"\n• {nama} ({dt.astimezone(WIB):%d %b %H:%M} WIB) id {d['_id']}")
        baru, info = kanvas(nama)
        if not baru:
            print(f"      ⛔ {info} — dilewati")
            continue
        if baru == nama:
            continue
        if not cek_ingress(baru):
            print("      ⛔ kanvas tidak 200 di kedua ingress — dilewati")
            continue
        meds = list(d.get("medias") or [])
        meds[0] = dict(meds[0])
        meds[0]["url"] = f"{IMG_BASE_URL}/openclaw-img/{baru}"
        payload = {"accountId": d["accountId"], "title": d.get("title") or "",
                   "topic": d.get("topic") or "", "type": d.get("type") or "story",
                   "description": d.get("description") or "", "medias": meds,
                   "scheduleAt": d.get("scheduleAt"),
                   "replies": d.get("replies") or []}
        try:
            c._request("PUT", f"/public/schedule/{d['_id']}", payload)
        except ReplizError as e:
            print(f"      ❌ PUT gagal: {e}")
            continue
        d2 = c.get(f"/public/schedule/{d['_id']}")
        d2 = d2.get("data") or d2
        m2 = (d2.get("medias") or [{}])[0].get("url", "")
        ok = m2.split("/")[-1] == baru
        print(f"      → status={d2.get('status')} scheduleAt={d2.get('scheduleAt')} "
              f"media={'✅ ' + m2.split('/')[-1] if ok else '⚠️ ' + m2}")
    print("\nselesai.")


if __name__ == "__main__":
    main()
