#!/usr/bin/env python3
"""
Catchup & Schedule IG Carousel StudioSoft — Juli 2026
Semua jadwal: slot kosong berikutnya (5, 8, 11, 14, 17, 20, 23 WIB)
Urut dari tgl 1 Juli dulu, baru lanjut 15-31 Juli.
"""
import os, sys, json, base64, urllib.request, urllib.error, time
from datetime import datetime, timezone, timedelta

from repliz_client import HEADERS, BASE, ACC
ACCOUNT_ID = ACC.STUDIOSOFT_IG  # StudioSoft IG


WIB = timezone(timedelta(hours=7))
WORKSPACE = os.path.expanduser("~/.openclaw/workspace-atun")
LOG_FILE = os.path.join(WORKSPACE, "studiosoft_ig_upload_log.json")

CAPTION = (
    "Temukan solusi digital terbaik untuk bisnis Anda bersama StudioSoft! 🚀\n\n"
    "Dari website company profile, toko online, hingga aplikasi custom — "
    "kami siap bantu bisnis Anda naik kelas di era digital.\n\n"
    "Website bukan lagi pilihan, tapi kebutuhan."
)
HASHTAG = "#StudioSoft #Website #DigitalMarketing #JasaWebsite #WebDeveloperIndonesia #BisnisOnline"

THEMES = [
    ("Mengapa Website Penting untuk Bisnis?", "Website adalah wajah digital bisnis Anda."),
    ("Tips Memilih Domain yang Tepat", "Domain yang baik: singkat, relevan, mudah diingat."),
    ("Website vs Social Media", "Sosmed hanya tempat numpang. Website adalah aset Anda sendiri."),
    ("5 Fitur Wajib Website UMKM", "Mobile-friendly, loading cepat, WA terintegrasi."),
    ("Keamanan Website Penting!", "SSL, backup rutin, update CMS — jangan sampai diretas!"),
    ("SEO untuk Pemula", "Riset kata kunci, konten berkualitas, meta deskripsi."),
    ("Desain Website Tingkatkan Penjualan", "Navigasi jelas, CTA strategis, brand konsisten."),
    ("Mobile-First: Kenapa Penting?", "Google pake mobile-first indexing."),
    ("Kecepatan Website Mempengaruhi Konversi", "53% pengunjung pergi jika loading > 3 detik."),
    ("CMS Terbaik untuk UMKM", "WordPress, Webflow, atau custom CMS?"),
    ("Website + SEO = Traffic Organik", "Konten berkualitas = traffic gratis dari Google."),
    ("Digital Marketing untuk UMKM", "Google Ads, SEO, email marketing — padukan."),
    ("Peran Branding di Website", "Branding kuat bikin bisnis diingat dan dipercaya."),
    ("Landing Page untuk Tingkatkan Konversi", "Halaman fokus pada satu tujuan: konversi."),
    ("Call to Action yang Efektif", "Tombol CTA harus jelas dan mendorong tindakan."),
    ("Tips Copywriting untuk Website", "Kata-kata tepat bisa menggandakan konversi."),
    ("Integrasi WhatsApp di Website", "Chat langsung dengan satu klik."),
    ("Multi-Bahasa Website", "Website bilingual buka pasar lebih luas."),
    ("Analytics Ukur Kinerja Website", "Google Analytics bantu keputusan tepat."),
    ("Email Marketing + Website", "Kumpulkan email, kirim newsletter."),
    ("Website untuk Toko Fisik", "Toko offline + website = jangkauan tanpa batas."),
    ("Tips Hemat Bikin Website", "Mulai template, upgrade bertahap."),
    ("Website sebagai Portofolio", "Tampilkan karya dan pencapaian."),
    ("Sitemap dan Navigasi Baik", "Navigasi intuitif = pengunjung betah."),
    ("Pentingnya Halaman About Us", "Cerita brand bikin pelanggan terhubung."),
    ("Google My Business + Website", "Integrasi GMB tingkatkan visibilitas lokal."),
    ("Fitur Pencarian di Website", "Search bar memudahkan cari produk."),
    ("Website untuk Toko Online", "E-commerce vs custom: pilih sesuai skala."),
    ("Hosting yang Tepat", "Uptime, kecepatan, support adalah prioritas."),
    ("Website vs Marketplace", "Marketplace pinjam tanah — website milik sendiri."),
    ("Mulai Digitalisasi Sekarang", "Setiap hari tanpa website = peluang hilang."),
]

SLOTS_WIB = [5, 8, 11, 14, 17, 20, 23]


def read_b64(filepath):
    """FIX 21/08: no base64 — return URL server OpenClaw."""
    return upload_image_to_server(filepath)


def get_next_slots_needed(count):
    """Generate count jadwal WIB ke depan, mulai dari slot berikutnya"""
    now_wib = datetime.now(WIB)
    slots = []
    cur = now_wib
    
    while len(slots) < count:
        current_hour = cur.hour
        # Cari slot berikutnya dari jam ini
        found = False
        for s in SLOTS_WIB:
            if current_hour < s or (current_hour == s and cur.minute < 55):
                slot_dt = datetime(cur.year, cur.month, cur.day, s, 0, 0, tzinfo=WIB)
                if slot_dt > now_wib:
                    slots.append(slot_dt)
                    found = True
                    cur = slot_dt + timedelta(hours=1)
                    break
        
        if not found:
            # Lompat ke besok jam 05:00
            tomorrow = cur + timedelta(days=1)
            cur = datetime(tomorrow.year, tomorrow.month, tomorrow.day, 5, 0, 0, tzinfo=WIB)
    
    return slots


def upload_carousel(files, schedule_utc, day_num):
    """Upload carousel ke Repliz"""
    medias = []
    for fp in files:
        img_url = read_b64(fp)
        medias.append({"url": img_url, "type": "image"})

    caption_text = f"{CAPTION}\n\n{HASHTAG}"
    
    payload = {
        "title": "",
        "description": caption_text,
        "topic": "Website & Digital Marketing",
        "type": "album",
        "medias": medias,
        "meta": {"title": "", "description": "", "url": ""},
        "additionalInfo": {
            "isAiGenerated": False, "isDraft": False,
            "collaborators": [], "mentions": [],
            "music": {"id": "", "artist": "", "name": "", "thumbnail": ""},
            "products": [], "tags": []
        },
        "replies": [],
        "accountId": ACCOUNT_ID,
        "scheduleAt": schedule_utc,
    }

    body = json.dumps(payload).encode()
    req = urllib.request.Request(f"{BASE}/public/schedule", data=body, headers=HEADERS, method="POST")
    try:
        with urllib.request.urlopen(req) as r:
            result = json.loads(r.read())
            sid = result.get("scheduleId", "?")
            print(f"    ✅ Upload sukses! Schedule ID: {sid}")
            return sid
    except urllib.error.HTTPError as e:
        err_body = e.read().decode()[:300]
        print(f"    ❌ HTTP {e.code}: {err_body}")
        return None


def load_log():
    if os.path.exists(LOG_FILE):
        try:
            with open(LOG_FILE) as f:
                return json.load(f)
        except: pass
    return []


def save_log(log_data, result):
    log_data.append(result)
    with open(LOG_FILE, "w") as f:
        json.dump(log_data, f, indent=2)


def main():
    print("=" * 70)
    print("📸 STUDIOSOFT IG CAROUSEL — CATCHUP & SCHEDULE JULI 2026")
    print("=" * 70)
    
    now = datetime.now(WIB)
    print(f"⏰ Waktu sekarang: {now.strftime('%d %b %Y %H:%M')} WIB")
    
    # Load log untuk cek apa yang sudah terupload
    uploaded_log = load_log()
    uploaded_days = {entry["day"] for entry in uploaded_log if entry.get("status") == "success"}
    print(f"📋 Hari yang sudah terupload: {sorted(uploaded_days)}")
    
    # Tentukan hari yang perlu diupload
    hari_butuh = [d for d in range(1, 32) if d not in uploaded_days]
    print(f"📋 Hari yang perlu diupload: {hari_butuh}")
    
    if not hari_butuh:
        print("\n✅ Semua hari sudah terupload!")
        return
    
    # Generate slot untuk hari-hari yang butuh
    slots = get_next_slots_needed(len(hari_butuh))
    
    print(f"\n📅 Akan mengupload {len(hari_butuh)} carousel ke slot berikut:")
    for i, slot in enumerate(slots):
        print(f"   {hari_butuh[i]:2d} Jul → {slot.strftime('%d %b %H:%M')} WIB")
    
    print("\n" + "=" * 70)
    hasil = []
    
    for idx, day_num in enumerate(hari_butuh):
        theme_idx = day_num - 1
        theme_title, _ = THEMES[theme_idx]
        variant = "BIRU" if day_num % 2 == 1 else "PUTIH"
        
        folder = os.path.join(WORKSPACE, f"studiosoft_batch/202607{day_num:02d}")
        
        img_files = sorted([os.path.join(folder, f) for f in os.listdir(folder) if f.endswith('.png')])
        
        if not img_files:
            print(f"\n❌ {day_num:02d} Jul — Folder kosong, skip!")
            hasil.append({"day": day_num, "status": "skip", "note": "no images"})
            save_log(uploaded_log, hasil[-1])
            continue
        
        slot_dt = slots[idx]
        sched_utc = slot_dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.000Z")
        
        print(f"\n{'='*60}")
        print(f"📅 {day_num:02d} Jul | {variant} | {theme_title[:40]}")
        print(f"  📂 {len(img_files)} gambar → {slot_dt.strftime('%d %b %H:%M')} WIB")
        
        sid = upload_carousel(img_files, sched_utc, day_num)
        
        entry = {
            "day": day_num,
            "theme": theme_title,
            "scheduled_wib": slot_dt.strftime("%Y-%m-%d %H:%M"),
            "schedule_id": sid or "",
            "status": "success" if sid else "failed",
            "timestamp": datetime.now(WIB).isoformat()
        }
        hasil.append(entry)
        save_log(uploaded_log, entry)
        
        # Rate limiting
        time.sleep(1.5)
    
    print(f"\n\n{'='*70}")
    print("📊 HASIL UPLOAD IG CAROUSEL STUDIOSOFT — JULI 2026")
    print(f"{'='*70}")
    sukses = sum(1 for h in hasil if h.get("status") == "success")
    for h in hasil:
        icon = "✅" if h.get("status") == "success" else ("⏭️" if h.get("status") == "skip" else "❌")
        print(f"  {icon} {h['day']:2d} Jul | {h.get('schedule_id','')[-8:]:8s} | {h.get('theme','')[:40]}")
    print(f"\n✅ {sukses}/{len(hasil)} sukses!")


if __name__ == "__main__":
    main()

