#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""pasang_car10_properti.py — pasang carousel 10 slide 'Digital Marketing Bisnis Properti'
ke FEED IG StudioSoft (08:30 WIB hari ini) + story mirror 08:40 WIB.

Gate: JPEG q85 ke openclaw-img/, HTTP 200 di KEDUA ingress funnel, abort kalau ada yang bukan 200.
Idempoten: kalau slot (akun + scheduleAt) sudah terisi → SKIP.
Jalankan: python3 pasang_car10_properti.py [--go]
"""
import json
import os
import subprocess
import sys
from datetime import datetime, timedelta, timezone

from PIL import Image
from repliz_client import get_client, ReplizError, IMG_BASE_URL

WIB = timezone(timedelta(hours=7))
WS = "/home/mantapman/.hermes/profiles/atun/workspace"
SRC = os.path.join(WS, "ss_ig_car10_properti")
IMG_DIR = os.path.join(WS, "openclaw-img")
ACC_IG_SS = "6a38ac33c5ff4ce3a3231232"
INGRESS = ["103.84.155.153", "103.84.155.217"]
HOST = "mantapserver.tail3947bb.ts.net"
ARTIKEL = "https://studiosoft.id/digital-marketing-bisnis-properti/"

CAPTION = f"""Bisnis properti jarang kalah karena produknya. Yang membuatnya kalah biasanya calon pembeli tidak menemukan halaman yang tepat, atau menemukannya tapi belum cukup percaya.

Di carousel ini saya rangkum cara digital marketing bekerja untuk sepuluh segmen properti: developer dan cluster, agen dan broker, sewa dan kontrakan, kos, apartemen, kavling, kontraktor, interior, ruko dan gudang, sampai villa. Tiap segmen punya calon pembelinya sendiri, kata kuncinya sendiri, dan kanal yang berbeda. Satu strategi untuk semuanya biasanya berujung pada anggaran habis di tempat yang salah.

Versi lengkapnya, termasuk contoh kata kunci per segmen dan cara mengukurnya, ada di sini:
{ARTIKEL}

Menurut Anda, segmen properti mana yang paling sulit dipasarkan secara digital? Tulis di kolom komentar.

#properti #digitalmarketing #seo #propertysurabaya #bisnisproperti #jasaseo #studiosoft"""


def jpeg_kan():
    hasil = []
    for i in range(1, 11):
        nama_png = f"ss_car10_properti_{i:02d}.png"
        nama_jpg = f"ss_car10_properti_{i:02d}.jpg"
        src = os.path.join(SRC, nama_png)
        dst = os.path.join(IMG_DIR, nama_jpg)
        im = Image.open(src).convert("RGB")
        assert im.size == (1080, 1350), f"{nama_png} ukuran {im.size}"
        im.save(dst, "JPEG", quality=85, optimize=True)
        hasil.append((nama_jpg, os.path.getsize(dst)))
    return hasil


def kanvas_story(nama):
    """Slide 4:5 → media story 1080x1920 sewarna latar slide (WAJIB, pitfall 2 Okt 2026).

    Story IG memaksa media memenuhi kanvas 9:16; slide 4:5 mentah kepotong ~228 px per sisi
    (kasus nyata: story mirror carousel properti, screenshot Bos).
    """
    dst_nama = f"ss_story_canvas_{nama}"
    dst = os.path.join(IMG_DIR, dst_nama)
    if os.path.exists(dst) and os.path.getsize(dst) > 1000:
        return dst_nama
    im = Image.open(os.path.join(IMG_DIR, nama)).convert("RGB")
    if im.size == (1080, 1920):
        return nama
    bg = im.getpixel((8, 8))
    if min(bg) >= 235:
        bg = (255, 255, 255)
    skala = min(1080 / im.width, 1920 / im.height)
    kecil = im.resize((round(im.width * skala), round(im.height * skala)), Image.LANCZOS)
    knv = Image.new("RGB", (1080, 1920), bg)
    knv.paste(kecil, ((1080 - kecil.width) // 2, (1920 - kecil.height) // 2))
    knv.save(dst, quality=90)
    print(f"   kanvas story: {nama} → {dst_nama} (bg {bg})")
    return dst_nama


def cek_ingress(nama):
    url = f"https://{HOST}/openclaw-img/{nama}"
    for ip in INGRESS:
        code = 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()
        if code != "200":
            return False, f"{nama} @{ip} → {code}"
    return True, ""


def main():
    go = "--go" in sys.argv
    sekarang = datetime.now(WIB)
    tayang = sekarang.replace(hour=8, minute=30, second=0, microsecond=0)
    story = sekarang.replace(hour=8, minute=40, second=0, microsecond=0)
    at_utc = tayang.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
    story_utc = story.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")

    print("=== 1. render JPEG q85 ===")
    for nama, ukuran in jpeg_kan():
        print(f"   {nama} {ukuran//1024} KB")

    print("=== 2. gate 200 dua ingress ===")
    for i in range(1, 11):
        ok, pesan = cek_ingress(f"ss_car10_properti_{i:02d}.jpg")
        if not ok:
            print("   ⛔ ABORT:", pesan)
            sys.exit(1)
    print("   10/10 media 200 di KEDUA ingress ✅")

    c = get_client()
    print("=== 3. cek slot (idempoten) ===")
    terpakai = []
    page = 1
    while True:
        r = c.get_schedules(page=page, limit=100)
        docs = r.get("docs") or r.get("data") or []
        if not docs:
            break
        for d in docs:
            if d.get("accountId") == ACC_IG_SS and (d.get("scheduleAt") or "").startswith(at_utc[:13]):
                terpakai.append((d.get("_id"), d.get("type"), d.get("scheduleAt"), d.get("status")))
        if len(docs) < 100:
            break
        page += 1
    print("   jadwal di slot 08:30 WIB hari ini:", terpakai if terpakai else "kosong ✅")
    if terpakai:
        print("   SKIP: slot sudah terisi (maksimal 1 carousel/hari/akun).")
        return

    payload = {
        "accountId": ACC_IG_SS,
        "title": "Carousel IG SS — Digital Marketing Bisnis Properti",
        "topic": "Seri Properti: SEO & Digital Marketing",
        "type": "album",
        "description": CAPTION,
        "medias": [{"url": f"{IMG_BASE_URL}/openclaw-img/ss_car10_properti_{i:02d}.jpg",
                    "type": "image", "alt": f"Slide {i} digital marketing bisnis properti"}
                   for i in range(1, 11)],
        "scheduleAt": at_utc,
        "replies": [],
        "additionalInfo": {"isShareToFeed": True},
    }
    if not go:
        print("\n(dry run — caption", len(CAPTION), "char | pakai --go untuk create)")
        print(CAPTION)
        return

    print("=== 4. create album ===")
    res = c.post("/public/schedule", payload)
    sid = res.get("scheduleId") or res.get("_id") or res.get("id")
    print(f"   album id={sid} @ {tayang.strftime('%d %b %H:%M')} WIB")

    print("=== 5. story mirror 08:40 ===")
    story_payload = {
        "accountId": ACC_IG_SS,
        "title": "Story IG SS mirror carousel properti",
        "topic": "Seri Properti: SEO & Digital Marketing",
        "type": "story",
        "description": "",
        "medias": [{"url": f"{IMG_BASE_URL}/openclaw-img/{kanvas_story('ss_car10_properti_01.jpg')}",
                    "type": "image", "alt": "Slide 1 digital marketing bisnis properti"}],
        "scheduleAt": story_utc,
        "replies": [],
    }
    res2 = c.post("/public/schedule", story_payload)
    sid2 = res2.get("scheduleId") or res2.get("_id") or res2.get("id")
    print(f"   story id={sid2} @ {story.strftime('%d %b %H:%M')} WIB")

    print("=== 6. verifikasi baca balik ===")
    for label, sid_ in (("album", sid), ("story", sid2)):
        d = c.get(f"/public/schedule/{sid_}")
        d = d.get("data") or d
        med = d.get("medias") or []
        print(f"   {label}: status={d.get('status')} type={d.get('type')} "
              f"scheduleAt={d.get('scheduleAt')} media={len(med)} "
              f"akun={(d.get('account') or {}).get('name')} "
              f"caption={len(d.get('description') or '')} char")


if __name__ == "__main__":
    try:
        main()
    except ReplizError as e:
        print("ReplizError:", e)
        sys.exit(1)
