#!/usr/bin/env python3
"""
StudioSoft Threads Scheduler — posting carousel tiap jam 10:00 WIB
Bergantian: hari genap → BG Biru, hari ganjil → BG Putih
Konten: Website, SEO, Social Media, AI, GEO, SEM, Google Tips, Meta Tips
"""
import os, sys, json, base64, urllib.request
from datetime import datetime, timezone, timedelta
from PIL import Image, ImageDraw, ImageFont

from repliz_client import HEADERS, BASE, ACC
from threads_text_check import cek_teks_threads, ThreadsTextError
ACCOUNT_ID = ACC.STUDIOSOFT_THREADS

# === REPLIZ AUTH ===
WIB = timezone(timedelta(hours=7))

# === DIRS ===
OUT = os.path.expanduser("~/.openclaw/workspace-atun/studiosoft_carousel")
os.makedirs(OUT, exist_ok=True)
FD = os.path.expanduser("~/.fonts")
LOG_FILE = os.path.expanduser("~/.openclaw/workspace-atun/studiosoft_threads_log.txt")
STATE_FILE = os.path.expanduser("~/.openclaw/workspace-atun/studiosoft_threads_state.json")

# === WP UPLOAD ===
WP_USER = "bambangbot"
WP_PASS = "q26r RePo BVy6 pwU2 F3z7 ouyl"

# === CAROUSEL SPECS ===
W, H = 1080, 1350
BLUE_BG = (30, 64, 175)
WHITE_BG = (255, 255, 255)
WHITE_FG = (255, 255, 255)
BLUE_FG = (30, 64, 175)
SOFT_BLUE = (180, 200, 240)
SOFT_WHITE = (100, 130, 200)
M = 50
CONTENT_W = W - 2*M

J100 = ImageFont.truetype(f"{FD}/Poppins-Bold.ttf", 100)
B36  = ImageFont.truetype(f"{FD}/Poppins-Bold.ttf", 36)
R28  = ImageFont.truetype(f"{FD}/Poppins-Regular.ttf", 28)
R20  = ImageFont.truetype(f"{FD}/Poppins-Regular.ttf", 20)

def fh(d, text, font):
    bb = d.textbbox((0, 0), text, font=font)
    return bb[3] - bb[1]

def block_h(d, text, font, max_w):
    words = text.split()
    lines = []
    cur = ""
    for w in words:
        test = cur + " " + w if cur else w
        tw = d.textbbox((0, 0), test, font=font)[2]
        if tw <= max_w:
            cur = test
        else:
            lines.append(cur)
            cur = w
    if cur:
        lines.append(cur)
    lh = int(fh(d, "A", font) * 1.4)
    return len(lines) * lh

def draw_block(d, text, x, y, font, fill, max_w):
    words = text.split()
    lines = []
    cur = ""
    for w in words:
        test = cur + " " + w if cur else w
        tw = d.textbbox((0, 0), test, font=font)[2]
        if tw <= max_w:
            cur = test
        else:
            lines.append(cur)
            cur = w
    if cur:
        lines.append(cur)
    lh = int(fh(d, "A", font) * 1.4)
    for line in lines:
        d.text((x, y), line, font=font, fill=fill)
        y += lh
    return y

def divider(d, x, y, w):
    if not hasattr(divider, "is_biru"):
        divider.is_biru = True
    gap = 20
    cx = x + w // 2
    dash = 10
    t = cx - (w // 2) + (w % 2)
    while t < cx + (w // 2):
        e = min(t + dash, cx + (w // 2))
        d.line([(t, y), (e, y)], fill=WHITE_FG if divider.is_biru else BLUE_FG, width=2)
        t = e + gap

def header(d, page):
    d.text((M, M), "STUDIOSOFT", font=B36, fill=WHITE_FG if header.is_biru else BLUE_FG, anchor="la")
    tw = d.textbbox((0, 0), "STUDIOSOFT", font=B36)[2]
    d.text((M + tw + 10, M + 5), page, font=R20, fill=SOFT_BLUE if header.is_biru else SOFT_WHITE, anchor="la")
header.is_biru = True

def footer(d, left="www.studiosoft.id", right=""):
    fy = H - 130
    d.text((M, fy), left, font=R20, fill=WHITE_FG if footer.is_biru else BLUE_FG)
    if right:
        d.text((W - M, fy), right, font=R20, fill=WHITE_FG if footer.is_biru else BLUE_FG, anchor="rt")
footer.is_biru = True

def clean_edges(im):
    px = im.load()
    w, h = im.size
    bg = BLUE_BG if clean_edges.is_biru else WHITE_BG
    for y in range(1300, h):
        for x in range(w): px[x, y] = bg
    for y in range(h):
        for x in range(w - 3, w): px[x, y] = bg
clean_edges.is_biru = True

# === BANK KONTEN (15 tema) ===
CONTENT = [
    {
        "theme": "Kecepatan Website",
        "cover": ["WEB", "PERFORMANCE", "MATTERS"],
        "sub": "Kecepatan website = konversi tinggi",
        "desc": "53% pengunjung pergi jika loading lebih dari 3 detik.\nSetiap 1 detik lambat = 7% konversi hilang.\nOptimasi gambar + cache + hosting = solusinya.",
        "items": ["☑  Kompres gambar & gunakan WebP", "☑  Aktifkan browser caching", "☑  Pilih hosting berkualitas"],
        "kenalan": "Kecepatan website bukan bonus — ini kebutuhan dasar.\n\nGoogle juga memberi peringkat lebih tinggi untuk website yang cepat.\nLoading cepat = pengalaman pengguna yang baik.",
        "kenalan_items": ["☑  Gunakan CDN untuk akses global", "☑  Minimalisir CSS & JavaScript", "☑  Aktifkan GZIP compression"],
        "layanan": ["☑  Website Performance Audit", "☑  Speed Optimization", "☑  Hosting & CDN Setup", "☑  Core Web Vitals Improvement", "☑  Image Optimization Strategy"],
    },
    {
        "theme": "SEO Dasar",
        "cover": ["SEO", "BASIC", "GUIDE"],
        "sub": "Optimasi mesin pencari dari dasar",
        "desc": "SEO tidak sulit. Mulai dari riset kata kunci.\nOptimasi judul, meta description, dan heading.\nKonsisten, dan hasil akan terlihat.",
        "items": ["☑  Riset kata kunci relevan", "☑  Optimasi title & meta desc", "☑  Gunakan heading terstruktur"],
        "kenalan": "SEO adalah investasi jangka panjang.\nHasil tidak instan, tapi bertahan lama.\nMulai dari yang paling dasar dan konsisten.",
        "kenalan_items": ["☑  Internal linking yang baik", "☑  Kecepatan website = faktor SEO", "☑  Konten berkualitas & orisinal"],
        "layanan": ["☑  SEO Audit & Strategy", "☑  On-Page Optimization", "☑  Technical SEO", "☑  Content Strategy", "☑  Local SEO"],
    },
    {
        "theme": "Social Media Strategy",
        "cover": ["SOCIAL", "MEDIA", "STRATEGY"],
        "sub": "Bangun kehadiran sosial yang kuat",
        "desc": "Social media bukan cuma posting.\nButuh strategi: target audiens, konten plan.\nKonsistensi dan engagement adalah kunci.",
        "items": ["☑  Tentukan platform utama", "☑  Buat konten kalender", "☑  Konsisten posting & engage"],
        "kenalan": "Setiap platform punya karakteristik berbeda.\nInstagram untuk visual, LinkedIn untuk profesional.\nSesuaikan konten dengan platformnya.",
        "kenalan_items": ["☑  Analisis kompetitor", "☑  Gunakan data untuk keputusan", "☑  Evaluasi performa rutin"],
        "layanan": ["☑  Social Media Strategy", "☑  Content Planning & Calendar", "☑  Community Management", "☑  Ads Management", "☑  Performance Analytics"],
    },
    {
        "theme": "AI untuk Bisnis",
        "cover": ["AI FOR", "BUSINESS", "GROWTH"],
        "sub": "AI bukan masa depan — ini sekarang",
        "desc": "AI mengubah cara bisnis beroperasi.\nDari customer service hingga analisis data.\nAdopsi AI = efisiensi + competitive advantage.",
        "items": ["☑  Chatbot untuk customer service", "☑  AI untuk analisis data", "☑  Otomatisasi tugas repetitive"],
        "kenalan": "AI bukan untuk menggantikan manusia.\nAI untuk memperkuat kemampuan tim Anda.\nYang penting: tahu kapan dan bagaimana menggunakannya.",
        "kenalan_items": ["☑  AI Content Generation", "☑  Predictive Analytics", "☑  Personalization Engine"],
        "layanan": ["☑  AI Readiness Assessment", "☑  AI Chatbot Implementation", "☑  Automation Workflow", "☑  AI Content Strategy", "☑  Data Analytics & Insights"],
    },
    {
        "theme": "SEM & Google Ads",
        "cover": ["SEM &", "GOOGLE", "ADS"],
        "sub": "Iklan yang terukur & efektif",
        "desc": "SEM memberi hasil cepat dengan cost per click.\nDengan strategi yang tepat, ROI bisa optimal.\nMonitoring dan optimasi adalah kuncinya.",
        "items": ["☑  Riset kata kunci iklan", "☑  Optimasi quality score", "☑  A/B testing landing page"],
        "kenalan": "Google Ads bekerja dengan sistem lelang.\nBukan soal budget terbesar yang menang.\nTapi soal relevansi dan kualitas iklan.",
        "kenalan_items": ["☑  Target audiens yang tepat", "☑  Negative keywords penting", "☑  Pantau conversion rate"],
        "layanan": ["☑  Google Ads Strategy", "☑  Keyword & Audience Research", "☑  Campaign Optimization", "☑  Landing Page Optimization", "☑  ROAS Analysis & Reporting"],
    },
    {
        "theme": "Google Tips",
        "cover": ["GOOGLE", "TIPS", "& TRICKS"],
        "sub": "Optimasi tools Google untuk bisnis",
        "desc": "Google punya banyak tools gratis.\nGoogle Business Profile, Search Console, Analytics.\nManfaatkan maksimal untuk bisnis Anda.",
        "items": ["☑  Google Business Profile wajib", "☑  Pantau Search Console rutin", "☑  Google Analytics untuk insight"],
        "kenalan": "Google Business Profile meningkatkan visibilitas lokal.\n78% pengguna mencari bisnis lokal setiap hari.\nPastikan profil Anda lengkap dan terupdate.",
        "kenalan_items": ["☑  Google My Business optimasi", "☑  Google Tag Manager untuk tracking", "☑  Google Data Studio untuk laporan"],
        "layanan": ["☑  Google Business Optimization", "☑  Google Analytics Setup", "☑  Search Console Monitoring", "☑  Google Ads Management", "☑  Data Studio Dashboard"],
    },
    {
        "theme": "Meta (FB/IG) Tips",
        "cover": ["META", "ADS &", "STRATEGY"],
        "sub": "Optimasi Facebook & Instagram Ads",
        "desc": "Meta Ads adalah platform iklan terbesar.\nTarget audiens sangat detail dan presisi.\nDengan kreatif yang tepat, hasil bisa maksimal.",
        "items": ["☑  Pixel tracking harus terpasang", "☑  Audience targeting yang tepat", "☑  Kreatif visual yang menarik"],
        "kenalan": "Meta menggunakan algoritma machine learning.\nSemakin banyak data, semakin baik targeting.\nBerikan pixel waktu untuk belajar (learning phase).",
        "kenalan_items": ["☑  Uji berbagai creative", "☑  Retargeting untuk konversi", "☑  Pantau frequency & CPM"],
        "layanan": ["☑  Meta Ads Strategy", "☑  Creative Production", "☑  Audience Research & Targeting", "☑  Performance Optimization", "☑  ROAS Analysis"],
    },
    {
        "theme": "GEO (Generative Engine Optimization)",
        "cover": ["GEO", "OPTIMIZATION", "GUIDE"],
        "sub": "Optimasi untuk AI-generated search",
        "desc": "GEO adalah strategi optimasi untuk AI search.\nChatGPT, Gemini, dan Perplexity menjadi sumber.\nKonten harus terstruktur agar terbaca AI.",
        "items": ["☑  Structured data & schema markup", "☑  Konten Q&A yang terstruktur", "☑  Authoritative backlinks"],
        "kenalan": "AI search engine berbeda dari Google biasa.\nMereka merangkum dari berbagai sumber terpercaya.\nBrand Anda harus jadi sumber yang direferensikan.",
        "kenalan_items": ["☑  Bangun E-E-A-T yang kuat", "☑  Optimasi untuk featured snippets", "☑  Konten mendalam & terpercaya"],
        "layanan": ["☑  GEO Readiness Assessment", "☑  Structured Data Implementation", "☑  Authoritative Content Strategy", "☑  AI Search Optimization", "☑  Brand Authority Building"],
    },
    {
        "theme": "Content Marketing",
        "cover": ["CONTENT", "MARKETING", "STRATEGY"],
        "sub": "Konten adalah raja — tapi strategi adalah kerajaan",
        "desc": "Content marketing bukan cuma nulis blog.\nIni strategi jangka panjang untuk membangun otoritas.\nEdukasi audiens, bangun kepercayaan, lalu konversi.",
        "items": ["☑  Tentukan content pillar", "☑  Buat editorial calendar", "☑  Konsisten publish berkualitas"],
        "kenalan": "Setiap konten harus punya tujuan jelas.\nApakah untuk traffic, engagement, atau konversi?\nUkur hasilnya dan optimasi terus.",
        "kenalan_items": ["☑  Repurpose konten ke berbagai format", "☑  Distribusi konten ke channel tepat", "☑  Analisis performa konten"],
        "layanan": ["☑  Content Strategy Development", "☑  SEO Content Writing", "☑  Content Distribution Plan", "☑  Performance Analysis", "☑  Content Repurposing"],
    },
    {
        "theme": "Website Security",
        "cover": ["WEBSITE", "SECURITY", "ESSENTIALS"],
        "sub": "Amankan aset digital Anda",
        "desc": "Keamanan website bukan hanya masalah IT.\nIni masalah bisnis dan reputasi.\nSatu kebocoran data bisa menghancurkan brand.",
        "items": ["☑  HTTPS wajib — bukan opsional", "☑  Update CMS & plugin rutin", "☑  Backup data secara berkala"],
        "kenalan": "Banyak serangan memanfaatkan celah yang sudah diperbaiki.\nUpdate versi terbaru = tambal lubang keamanan.\nJangan tunda update, lakukan segera.",
        "kenalan_items": ["☑  Firewall & security plugin", "☑  Two-factor authentication", "☑  Monitoring aktivitas mencurigakan"],
        "layanan": ["☑  Security Audit", "☑  SSL/HTTPS Setup", "☑  Malware Removal", "☑  Backup Solution", "☑  Security Monitoring"],
    },
    {
        "theme": "Data Analytics",
        "cover": ["DATA", "ANALYTICS", "INSIGHTS"],
        "sub": "Keputusan berbasis data bukan feeling",
        "desc": "Tanpa data, Anda buta dalam bisnis.\nGoogle Analytics, Search Console, CRM data.\nSemua bercerita — Anda tinggal mendengarkan.",
        "items": ["☑  Pasang tracking dari awal", "☑  Tentukan KPI yang tepat", "☑  Pantau dashboard rutin"],
        "kenalan": "Data hanya berguna jika Anda bertindak.\nAnalisis → Ambil keputusan → Ukur hasil.\nSiklus ini yang membuat bisnis terus berkembang.",
        "kenalan_items": ["☑  Segmentasi pengunjung", "☑  Analisis conversion funnel", "☑  Identifikasi bottleneck"],
        "layanan": ["☑  Analytics Implementation", "☑  Dashboard & Reporting", "☑  Conversion Analysis", "☑  User Behavior Analysis", "☑  Data-Driven Strategy"],
    },
    {
        "theme": "Mobile First",
        "cover": ["MOBILE", "FIRST", "APPROACH"],
        "sub": "60%+ traffic dari smartphone",
        "desc": "Mayoritas pengguna mengakses dari HP.\nWebsite harus responsif di semua layar.\nGoogle juga mengutamakan versi mobile.",
        "items": ["☑  Desain responsif wajib", "☑  Tombol cukup besar untuk tap", "☑  Teks tidak perlu zoom"],
        "kenalan": "Mobile-first bukan tren — ini standar baru.\nGoogle menggunakan mobile-first indexing.\nJika website tidak mobile-friendly, peringkat turun.",
        "kenalan_items": ["☑  Navigasi mobile yang intuitif", "☑  Form mudah diisi di HP", "☑  Loading cepat di jaringan 4G"],
        "layanan": ["☑  Responsive Web Design", "☑  Mobile UX Optimization", "☑  AMP Implementation", "☑  PWA Development", "☑  Mobile Speed Optimization"],
    },
    {
        "theme": "Branding Digital",
        "cover": ["DIGITAL", "BRANDING", "MATTERS"],
        "sub": "Brand kuat = bisnis kuat",
        "desc": "Branding digital bukan cuma logo keren.\nKonsistensi warna, font, dan tone of voice.\nSetiap touchpoint adalah kesempatan membangun kesan.",
        "items": ["☑  Brand guidelines yang jelas", "☑  Konsistensi di semua platform", "☑  Visual identity yang kuat"],
        "kenalan": "Brand yang kuat membuat orang merekomendasikan.\nKepercayaan dibangun dari konsistensi.\nSetiap interaksi adalah investasi brand equity.",
        "kenalan_items": ["☑  Bangun brand narrative", "☑  Visual konsisten & profesional", "☑  Suara brand yang autentik"],
        "layanan": ["☑  Brand Strategy & Positioning", "☑  Visual Identity Design", "☑  Brand Guidelines", "☑  Digital Brand Presence", "☑  Brand Performance Tracking"],
    },
    {
        "theme": "Email Marketing",
        "cover": ["EMAIL", "MARKETING", "ROI"],
        "sub": "ROI tertinggi di antara channel digital",
        "desc": "Email marketing masih juara dalam ROI.\nSetiap Rp1 yang diinvestasikan bisa kembali Rp45.\nTapi harus dilakukan dengan strategi yang tepat.",
        "items": ["☑  Kumpulkan email sejak dini", "☑  Segmentasi berdasarkan perilaku", "☑  Personalisasi konten email"],
        "kenalan": "Subject line menentukan open rate.\nGunakan subject yang menarik dan relevan.\nJangan gunakan clickbait — itu merusak trust.",
        "kenalan_items": ["☑  A/B testing subject line", "☑  Automasi email sequence", "☑  Analisis open & click rate"],
        "layanan": ["☑  Email Marketing Strategy", "☑  Email Automation Setup", "☑  Newsletter Design", "☑  Segmentation & Personalization", "☑  Performance Analytics"],
    },
    {
        "theme": "UX Design",
        "cover": ["UX", "DESIGN", "PRINCIPLES"],
        "sub": "Pengalaman pengguna yang baik = konversi tinggi",
        "desc": "UX yang baik terasa natural dan intuitif.\nPengunjung bisa mencapai tujuan tanpa berpikir.\nNavigasi jelas, konten mudah dipindai.",
        "items": ["☑  Navigasi intuitif & sederhana", "☑  Gunakan whitespace yang cukup", "☑  CTA jelas & strategis"],
        "kenalan": "UX bukan biaya — ini investasi.\nSetiap perbaikan UX meningkatkan konversi.\nMulai dari perubahan kecil yang berdampak besar.",
        "kenalan_items": ["☑  User research & testing", "☑  Accessibility untuk semua", "☑  Mobile UX optimization"],
        "layanan": ["☑  UX Audit & Research", "☑  Information Architecture", "☑  Wireframe & Prototype", "☑  Usability Testing", "☑  Conversion Rate Optimization"],
    },
]

def generate_carousel(is_biru, theme_data):
    """Generate 3 slides carousel"""
    BG = BLUE_BG if is_biru else WHITE_BG
    FG = WHITE_FG if is_biru else BLUE_FG
    SUB = SOFT_BLUE if is_biru else SOFT_WHITE
    
    imgs = []
    
    for slide_idx in range(3):
        im = Image.new("RGB", (W, H), BG)
        d = ImageDraw.Draw(im)
        
        # --- SLIDE 1: COVER ---
        if slide_idx == 0:
            header(d, "01/03")
            
            t = theme_data
            titles = t["cover"]
            subtitle = t["sub"]
            desc = t["desc"]
            items = t["items"]
            
            total_h = 0
            for title_line in titles:
                total_h += int(fh(d, title_line, J100) * 1.15)
            total_h += 60 + 5 + 55  # separator 120px
            sub_h = block_h(d, subtitle, R28, CONTENT_W)
            total_h += sub_h + 20
            total_h += 15
            
            for item in items:
                total_h += int(fh(d, item, R28) * 1.3)
            
            hdr_h = int(fh(d, "STUDIOSOFT", B36)) + M
            usable = H - 2*M - hdr_h - 20
            start_y = M + hdr_h + 20 + (usable - total_h) // 2
            
            ty = start_y
            for title_line in titles:
                d.text((M, ty), title_line, font=J100, fill=FG)
                ty += int(fh(d, title_line, J100) * 1.15)
            
            ty += 60
            divider(d, M, ty, 400)
            ty += 55
            
            ty = draw_block(d, subtitle, M, ty, R28, SUB, CONTENT_W)
            ty += 10
            
            for item in items:
                d.text((M, ty), item, font=R28, fill=FG)
                ty += int(fh(d, item, R28) * 1.3)
            
            footer(d, "www.studiosoft.id", "Swipe →")
            clean_edges(im)
            im.save(f"{OUT}/01_cover.png")
            imgs.append(f"{OUT}/01_cover.png")
        
        # --- SLIDE 2: KENALAN ---
        elif slide_idx == 1:
            header(d, "02/03")
            
            desc = t["kenalan"]
            items = t["kenalan_items"]
            title = t["theme"].upper()
            
            j_h = int(fh(d, title, J100) * 1.15)
            desc_h = block_h(d, desc, R28, CONTENT_W)
            
            total_h = j_h + 60 + 5 + 55 + desc_h + 15
            for item in items:
                total_h += int(fh(d, item, R28) * 1.3)
            
            hdr_h = int(fh(d, "STUDIOSOFT", B36)) + M
            usable = H - 2*M - hdr_h - 20
            start_y = M + hdr_h + 20 + (usable - total_h) // 2
            
            ty = start_y
            d.text((M, ty), title, font=J100, fill=FG)
            ty += j_h
            
            ty += 60
            divider(d, M, ty, 300)
            ty += 55
            
            ty = draw_block(d, desc, M, ty, R28, FG, CONTENT_W)
            ty += 10
            
            for item in items:
                d.text((M, ty), item, font=R28, fill=FG)
                ty += int(fh(d, item, R28) * 1.3)
            
            footer(d, "www.studiosoft.id")
            clean_edges(im)
            im.save(f"{OUT}/02_kenalan.png")
            imgs.append(f"{OUT}/02_kenalan.png")
        
        # --- SLIDE 3: LAYANAN ---
        else:
            header(d, "03/03")
            
            titles = ["KAMI", "SIAP", "BANTU!"]
            items = t["layanan"]
            
            total_h = 0
            for t_line in titles:
                total_h += int(fh(d, t_line, J100) * 1.15)
            total_h += 60 + 5 + 55
            
            for item in items:
                total_h += int(fh(d, item, R28) * 1.3)
            
            hdr_h = int(fh(d, "STUDIOSOFT", B36)) + M
            usable = H - 2*M - hdr_h - 20
            start_y = M + hdr_h + 20 + (usable - total_h) // 2
            
            ty = start_y
            for t_line in titles:
                d.text((M, ty), t_line, font=J100, fill=FG)
                ty += int(fh(d, t_line, J100) * 1.15)
            
            ty += 60
            divider(d, M, ty, 300)
            ty += 55
            
            for item in items:
                d.text((M, ty), item, font=R28, fill=FG)
                ty += int(fh(d, item, R28) * 1.3)
            
            footer(d, "www.studiosoft.id")
            clean_edges(im)
            im.save(f"{OUT}/03_layanan.png")
            imgs.append(f"{OUT}/03_layanan.png")
    
    return imgs

def upload_to_wp(filepath, filename):
    """FIXED 21/08: semua image → server OpenClaw (mantapserver), NO WP, NO base64."""
    from repliz_client import upload_image_to_server
    return upload_image_to_server(filepath, filename)

def log(msg):
    with open(LOG_FILE, "a") as f:
        f.write(f"[{datetime.now(WIB).strftime('%Y-%m-%d %H:%M:%S')} WIB] {msg}\n")
    print(msg)

def get_theme_index():
    """Ambil index tema berikutnya dari state"""
    if os.path.exists(STATE_FILE):
        with open(STATE_FILE) as f:
            state = json.load(f)
        return state.get("theme_index", 0) + 1
    return 0

def save_state(theme_idx, bg_type):
    state = {
        "theme_index": theme_idx,
        "last_bg": bg_type,
        "last_post": datetime.now(WIB).strftime("%Y-%m-%d %H:%M")
    }
    with open(STATE_FILE, "w") as f:
        json.dump(state, f)

def run():
    """Main scheduler"""
    today = datetime.now(WIB)
    day = today.day
    
    # Bergantian: genap → biru, ganjil → putih
    is_biru = (day % 2 == 0)
    bg_name = "BIRU" if is_biru else "PUTIH"
    
    # Ambil tema berikutnya
    theme_idx = get_theme_index()
    if theme_idx >= len(CONTENT):
        theme_idx = 0  # loop
    
    theme_data = CONTENT[theme_idx]
    log(f"🎨 StudioSoft Carousel — BG {bg_name} | Tema: {theme_data['theme']}")
    
    # Set is_biru untuk fungsi2 global
    divider.is_biru = is_biru
    header.is_biru = is_biru
    footer.is_biru = is_biru
    clean_edges.is_biru = is_biru
    
    imgs = generate_carousel(is_biru, theme_data)
    log(f"✅ Carousel generated: 3 slides")
    
    # Upload ke WP
    wp_urls = []
    filenames = ["01_cover.png", "02_kenalan.png", "03_layanan.png"]
    for fp, fn in zip(imgs, filenames):
        try:
            url = upload_to_wp(fp, fn)
            wp_urls.append(url)
            log(f"📤 Uploaded: {url}")
        except Exception as e:
            log(f"❌ Upload failed {fn}: {e}")
            return False
    
    # Buat teks Threads
    t = theme_data
    
    # Cek apakah post sudah ada hari ini (cari di state)
    texts = [
        f"Halo! 👋\n\n{t['desc'].replace(chr(10), '. ') if chr(10) in t['desc'] else t['desc']}\n\n#StudioSoft #{t['theme'].replace(' ', '')}",
        f"{t['kenalan'].replace(chr(10), '. ') if chr(10) in t['kenalan'] else t['kenalan']}\n\n{chr(10).join(t['kenalan_items'][:3])}\n\n#StudioSoft #DigitalMarketing",
        f"Slide 3 — Kami Siap Bantu!\n\n{chr(10).join(t['layanan'][:5])}\n\nwww.studiosoft.id\n\n#StudioSoft #{t['theme'].replace(' ', '')}"
    ]
    
    for i in range(len(texts)):
        # VALIDASI KETAT (FIXED 5 Agustus 2026): max 500 karakter + link nyala. JANGAN dipotong.
        try:
            texts[i] = cek_teks_threads(texts[i], label=f"Slide {i+1}")
        except ThreadsTextError as e:
            print(f"  SKIP: {e}")
            texts[i] = None
    texts = [t for t in texts if t]
    if not texts:
        print("  Tidak ada teks yang lolos validasi — skip hari ini.")
        return
    
    # Post ke Repliz
    SLOT_HOUR = 10
    today_str = today.strftime("%Y-%m-%d")
    parent_id = None
    
    for i, (url, text) in enumerate(zip(wp_urls, texts)):
        iso = f"{today_str}T{SLOT_HOUR:02d}:{i:02d}:00+07:00"
        
        payload = {
            "title": "",
            "description": text,
            "topic": "",
            "type": "text",
            "medias": [{"url": url}],
            "meta": {"title": "", "description": "", "url": ""},
            "additionalInfo": {
                "isAiGenerated": False, "isDraft": False,
                "collaborators": [], "mentions": [],
                "music": {"id": "", "artist": "", "name": "", "thumbnail": ""},
                "products": [], "tags": []
            },
            "replies": [parent_id] if parent_id else [],
            "accountId": ACCOUNT_ID,
            "scheduleAt": iso,
        }
        
        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, timeout=15) as r:
                result = json.loads(r.read())
                sid = result.get("scheduleId", "?")
                log(f"✅ Post {i+1} → {sid} | {SLOT_HOUR:02d}:{i:02d} WIB")
                parent_id = sid
        except Exception as e:
            log(f"❌ Post {i+1}: {e}")
            return False
    
    save_state(theme_idx, bg_name)
    log(f"🎉 Selesai! BG {bg_name} — Tema {t['theme']} — Jam 10:00 WIB")
    return True

if __name__ == "__main__":
    # Set global untuk akses di fungsi
    _is_biru = True  # default, akan di-set di run()
    
    success = run()
    sys.exit(0 if success else 1)

