#!/usr/bin/env python3
"""GEO Carousel for StudioSoft Threads — dark blue, modern design.
Resolusi: 1080×1920 (9:16 portrait), JPG.
"""
from PIL import Image, ImageDraw, ImageFont
import base64, json, os, urllib.request, urllib.error
from repliz_client import HEADERS, BASE_URL

OUT_DIR = "/home/mantapman/.hermes/profiles/atun/workspace/studiosoft_geo_bg_biru"
os.makedirs(OUT_DIR, exist_ok=True)

W, H = 1080, 1920
M = 65
MX = W - 2*M

BLUE = "#0F2B5C"        # Darker navy
CARD_BG = "#152D5A"     # Card background
WHITE = "#FFFFFF"
ACCENT = "#93C5FD"      # Light blue accent
GOLD = "#FCD34D"        # Yellow accent for highlights
TEAL = "#2DD4BF"        # Teal accent
SOFT = "#BFDBFE"        # Soft blue
DIV = "#1E40AF"         # Divider blue

FD = "/home/mantapman/.fonts/poppins"

def ft(name, sz):
    return ImageFont.truetype(f"{FD}/Poppins-{name}.ttf", sz)

# Font sizes
B160 = ft("Bold", 160)
B120 = ft("Bold", 120)
B100 = ft("Bold", 100)
B90  = ft("Bold", 90)
B80  = ft("Bold", 80)
B70  = ft("Bold", 70)
B60  = ft("Bold", 60)
B50  = ft("Bold", 50)
B44  = ft("Bold", 44)
B40  = ft("Bold", 40)
SB50 = ft("SemiBold", 50)
SB45 = ft("SemiBold", 45)
SB40 = ft("SemiBold", 40)
SB36 = ft("SemiBold", 36)
SB32 = ft("SemiBold", 32)
R42  = ft("Regular", 42)
R38  = ft("Regular", 38)
R36  = ft("Regular", 36)
R34  = ft("Regular", 34)
R32  = ft("Regular", 32)
R28  = ft("Regular", 28)
R24  = ft("Regular", 24)
R20  = ft("Regular", 20)

def wrap(d, tx, fn, mw):
    ls = []
    for p in tx.split('\n'):
        if not p.strip():
            ls.append(('', fn))
            continue
        ws = p.split()
        c = ""
        for w in ws:
            if d.textlength(c + w + " ", font=fn) <= mw:
                c += w + " "
            else:
                if c: ls.append((c.rstrip(), fn))
                c = w + " "
        if c.strip(): ls.append((c.rstrip(), fn))
    return ls

def header_footer(draw, num, total=5, cover=False):
    draw.text((M, 35), "StudioSoft", fill=WHITE, font=R24)
    if not cover:
        draw.text((W-M, 35), f"{num}/{total}", fill=ACCENT, font=R24, anchor="ra")
    draw.text((M, H-45), "studiosoft.id", fill=ACCENT, font=R24)

def div(draw, y, color=DIV):
    draw.rounded_rectangle([(M, y), (W-M, y+3)], radius=2, fill=color)

def card(draw, x, y, w, h, title, items, title_color=WHITE):
    """Draw a bordered card with items."""
    draw.rounded_rectangle([(x, y), (x+w, y+h)], radius=18, fill=CARD_BG, outline=DIV, width=2)
    draw.text((x+30, y+25), title, fill=title_color, font=SB45)
    iy = y + 85
    for item in items:
        dot_color = GOLD if title == "SEO" else TEAL
        draw.ellipse([(x+30, iy+8), (x+44, iy+22)], fill=dot_color)
        draw.text((x+55, iy), item, fill=ACCENT, font=R32)
        iy += 40

# ════════════ SLIDE 1 — COVER ════════════
def slide_1():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header_footer(draw, 1, cover=True)
    
    # Big GEO
    draw.text((M, 250), "GEO", fill=WHITE, font=B120)
    draw.text((M, 390), "Generative Engine", fill=ACCENT, font=SB50)
    draw.text((M, 450), "Optimization", fill=ACCENT, font=SB50)
    
    div(draw, 530)
    
    # Sub
    draw.text((M, 600), "Strategi Baru Biar Brandmu", fill=WHITE, font=B70)
    draw.text((M, 680), "Disebut di Jawaban AI", fill=WHITE, font=B70)
    
    # Desc
    draw.text((M, 820), "Optimasi untuk Google, ChatGPT, Gemini,", fill=SOFT, font=R36)
    draw.text((M, 870), "Perplexity & AI Lainnya", fill=SOFT, font=R36)
    
    # Divider middle
    div(draw, H//2 + 100)
    
    # Bottom brand
    draw.text((M, H-300), "StudioSoft", fill=WHITE, font=B60)
    draw.text((M, H-220), "Partner Pertumbuhan Bisnis Berbasis Data", fill=SOFT, font=R32)
    
    # StudioSoft logo/icon rectangle
    draw.rounded_rectangle([(M, H-170), (W-M, H-115)], radius=10, fill=DIV)
    draw.text((W//2, H-142), "studiosoft.id", fill=WHITE, font=SB36, anchor="mm")
    
    f = f"{OUT_DIR}/01_cover.jpg"
    img.save(f, quality=82)
    print(f"✅ 01_cover.jpg")
    return f

# ════════ SLIDE 2 — APA ITU GEO ════════
def slide_2():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header_footer(draw, 2)
    
    draw.text((M, 140), "Apa Itu GEO?", fill=WHITE, font=B90)
    div(draw, 240)
    draw.text((M, 280), "Generative Engine Optimization", fill=ACCENT, font=SB45)
    
    # Step 1
    y = 400
    draw.rounded_rectangle([(M, y), (W-M, y+160)], radius=15, fill=CARD_BG)
    draw.text((M+30, y+25), "1", fill=GOLD, font=B60)
    draw.text((M+100, y+22), "Optimasi untuk AI", fill=WHITE, font=SB45)
    lines = wrap(draw, "Strategi optimasi konten biar brand & website muncul\nsebagai referensi di jawaban AI generatif.", R34, MX-100)
    ly = y + 80
    for lt, lf in lines:
        draw.text((M+100, ly), lt, fill=ACCENT, font=lf)
        ly += lf.size + 4
    
    # Step 2
    y = 600
    draw.rounded_rectangle([(M, y), (W-M, y+160)], radius=15, fill=CARD_BG)
    draw.text((M+30, y+25), "2", fill=GOLD, font=B60)
    draw.text((M+100, y+22), "Bukan SEO Biasa", fill=WHITE, font=SB45)
    lines = wrap(draw, "SEO fokus ranking di 10 link biru Google.\nGEO fokus bagaimana AI memahami, memilih,\ndan mengutip kontenmu.", R34, MX-100)
    ly = y + 80
    for lt, lf in lines:
        draw.text((M+100, ly), lt, fill=ACCENT, font=lf)
        ly += lf.size + 4
    
    # Step 3
    y = 800
    draw.rounded_rectangle([(M, y), (W-M, y+160)], radius=15, fill=CARD_BG)
    draw.text((M+30, y+25), "3", fill=GOLD, font=B60)
    draw.text((M+100, y+22), "Kenapa Berbeda?", fill=WHITE, font=SB45)
    lines = wrap(draw, "AI nggak nampilin link \u2014 AI nyusun jawaban dari\nberbagai sumber. Kontenmu harus layak jadi referensi,\nbukan cuma ranking.", R34, MX-100)
    ly = y + 80
    for lt, lf in lines:
        draw.text((M+100, ly), lt, fill=ACCENT, font=lf)
        ly += lf.size + 4
    
    f = f"{OUT_DIR}/02_slide.jpg"
    img.save(f, quality=82)
    print(f"✅ 02_slide.jpg")
    return f

# ════════ SLIDE 3 — DATA ════════
def slide_3():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header_footer(draw, 3)
    
    draw.text((M, 140), "Kenapa GEO Penting?", fill=WHITE, font=B80)
    div(draw, 235)
    draw.text((M, 275), "Data yang Wajib Kamu Tahu", fill=ACCENT, font=SB45)
    
    # Data cards in 2x2 grid
    data = [
        ("73%", "search intent masih\ndi Google", "(SparkToro, 2025)"),
        ("27%", "tersebar di 40+\nplatform lain", "(ChatGPT, YouTube,\nReddit, TikTok, Amazon)"),
        ("800%", "kenaikan referral dari\nAI & LLM dalam 3 bulan", "(Backlinko)"),
        ("6,5x", "AI lebih sering mengutip\nbrand dari pihak ke-3", "(Kevin Indig)"),
    ]
    
    cw = (MX - 20) // 2  # card width
    ch = 210
    
    for i, (num, label, source) in enumerate(data):
        col = i % 2
        row = i // 2
        cx = M + col * (cw + 20)
        cy = 340 + row * (ch + 20)
        
        draw.rounded_rectangle([(cx, cy), (cx+cw, cy+ch)], radius=15, fill=CARD_BG)
        
        # Big number
        draw.text((cx+20, cy+15), num, fill=GOLD, font=B70)
        
        # Label
        lines = wrap(draw, label, R32, cw-40)
        ly = cy + 90
        for lt, lf in lines:
            draw.text((cx+20, ly), lt, fill=WHITE, font=lf)
            ly += lf.size + 4
        
        # Source
        lines = wrap(draw, source, R24, cw-40)
        ly = cy + ch - 35
        for lt, lf in lines:
            draw.text((cx+20, ly), lt, fill=SOFT, font=lf)
            ly += lf.size + 2
    
    # Bottom
    draw.text((M, H-230), "Ini bukan tren \u2014 ini perubahan fundamental", fill=WHITE, font=SB50)
    draw.text((M, H-170), "cara orang mencari informasi.", fill=WHITE, font=SB50)
    
    f = f"{OUT_DIR}/03_slide.jpg"
    img.save(f, quality=82)
    print(f"✅ 03_slide.jpg")
    return f

# ════════ SLIDE 4 — SEO vs GEO ════════
def slide_4():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header_footer(draw, 4)
    
    draw.text((M, 140), "SEO vs GEO", fill=WHITE, font=B80)
    div(draw, 235)
    draw.text((M, 280), "Pahami Bedanya, Kuasai Dua-duanya", fill=ACCENT, font=SB45)
    
    cw = (MX - 20) // 2
    
    # SEO Card
    seo_items = [
        "Keyword & Backlink",
        "Ranking di Google SERP",
        "10 Link Biru",
        "Traffic dari Klik Organik",
        "Algoritma Google",
    ]
    card(draw, M, 380, cw, 400, "SEO", seo_items, GOLD)
    
    # GEO Card
    geo_items = [
        "Konten Informatif",
        "Disebut di Jawaban AI",
        "Semua Platform",
        "Traffic dari AI Chat",
        "Pemahaman & Relevansi",
    ]
    card(draw, M+cw+20, 380, cw, 400, "GEO", geo_items, TEAL)
    
    # Bottom
    draw.text((M, 830), "Keduanya saling melengkapi", fill=WHITE, font=B50)
    draw.text((M, 890), "Jangan pilih salah satu \u2014 kuasai dua-duanya.", fill=ACCENT, font=SB45)
    
    # Quote
    draw.text((M, 1020), "\u201cSEO dulu soal ranking. Sekarang soal", fill=SOFT, font=R34)
    draw.text((M, 1065), "relevance dan trust di tiap platform.\u201d", fill=SOFT, font=R34)
    draw.text((M, 1125), "\u2014 Neil Patel", fill=SOFT, font=SB36)
    
    f = f"{OUT_DIR}/04_slide.jpg"
    img.save(f, quality=82)
    print(f"✅ 04_slide.jpg")
    return f

# ════════ SLIDE 5 — CTA ════════
def slide_5():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header_footer(draw, 5)
    
    draw.text((M, 140), "Siap Mulai GEO?", fill=WHITE, font=B80)
    div(draw, 235)
    draw.text((M, 280), "3 Langkah Awal", fill=ACCENT, font=SB45)
    
    steps = [
        ("01", "Audit", "Di mana audiensmu mencari informasi?\nGoogle? ChatGPT? YouTube? Reddit?"),
        ("02", "Optimasi", "Website, Google Business Profile, sosmed,\nYouTube \u2014 pastikan semuanya rapi."),
        ("03", "Otoritas", "Guest post, ulasan, publikasi industri.\nAI 6,5x lebih suka sumber pihak ke-3."),
    ]
    
    y = 360
    for num, title, desc in steps:
        draw.rounded_rectangle([(M, y), (W-M, y+150)], radius=15, fill=CARD_BG)
        # Number
        draw.text((M+30, y+20), num, fill=GOLD, font=B44)
        # Title
        draw.text((M+110, y+22), title, fill=WHITE, font=SB45)
        # Desc
        lines = wrap(draw, desc, R34, MX-140)
        dy = y + 80
        for lt, lf in lines:
            draw.text((M+110, dy), lt, fill=ACCENT, font=lf)
            dy += lf.size + 4
        y += 180
    
    # Big closing
    draw.text((M, y+20), "Yang adaptasi sekarang,", fill=WHITE, font=B70)
    draw.text((M, y+95), "yang menang di 2027.", fill=WHITE, font=B70)
    
    # CTA
    y_cta = H - 190
    draw.rounded_rectangle([(M, y_cta), (W-M, y_cta+65)], radius=15, fill=ACCENT)
    draw.text((W//2, y_cta+33), "Konsultasi GRATIS \u2192 0819-3500-0624", fill=BLUE, font=SB40, anchor="mm")
    
    f = f"{OUT_DIR}/05_slide.jpg"
    img.save(f, quality=82)
    print(f"✅ 05_slide.jpg")
    return f

# ════════════ GENERATE ════════════
print("=" * 50)
print("GENERATING GEO CAROUSEL v3")
print("=" * 50)
slide_1()
slide_2()
slide_3()
slide_4()
slide_5()
print("\n✅ Semua slide selesai!")

# ════════════ SCHEDULE ════════════
SLOT = "2026-07-25T13:00:00.000Z"
FILES = sorted([f for f in os.listdir(OUT_DIR) if f.endswith('.jpg')])
ACCOUNT = "6a335b9ec5ff4ce3a3225c2a"

def api_call(method, endpoint, data=None):
    url = f"{BASE_URL}{endpoint}"
    body = json.dumps(data).encode() if data else None
    req = urllib.request.Request(url, data=body, headers=HEADERS, method=method)
    try:
        with urllib.request.urlopen(req) as resp:
            raw = resp.read()
            return json.loads(raw) if raw else {"success": True}
    except urllib.error.HTTPError as e:
        raw = e.read().decode()
        return {"error": e.code, "body": json.loads(raw) if raw.startswith('{') else raw[:500]}

# Hapus jadwal lama
print("\n⏳ Membersihkan jadwal lama...")
r = api_call("GET", f"/public/schedule?accountId={ACCOUNT}&limit=50")
for item in r.get('items', []):
    sid = item.get('id','')
    if sid:
        api_call("DELETE", f"/public/schedule/{sid}")

medias = []
for fname in sorted(FILES):
    fpath = os.path.join(OUT_DIR, fname)
    with open(fpath, "rb") as f:
        b64 = base64.b64encode(f.read()).decode()
    medias.append({"url": f"data:image/jpeg;base64,{b64}", "type": "image", "alt": "GEO carousel"})

caption = (
    "GEO (Generative Engine Optimization) adalah strategi baru "
    "yang nggak bisa diabaikan di 2026.\n\n"
    "SEO bikin brandmu ranking di Google. GEO bikin "
    "brandmu disebut di jawaban AI \u2014 ChatGPT, Gemini, "
    "Perplexity, dan Google AI Overviews.\n\n"
    "Data terbaru: AI referral naik 800% dalam 3 bulan. "
    "Yang nggak siap, bakal ketinggalan.\n\n"
    "Slide by StudioSoft"
    "\nstudiosoft.id"
)

replies = [
    "SEO vs GEO:\n"
    "SEO = ranking keyword + backlink\n"
    "GEO = konten informatif + disebut AI\n\n"
    "Keduanya penting. Tapi ke depannya, "
    "AI makin sering jadi gerbang pertama konsumen.",

    "3 Langkah Awal:\n"
    "1. Audit \u2014 di mana audiens cari info?\n"
    "2. Optimasi platform (web, GBP, sosmed)\n"
    "3. Bangun otoritas (publikasi industri)\n\n"
    "Yang adaptasi sekarang, yang menang di 2027.\nstudiosoft.id",
]

payload = {
    "title": "", "description": caption,
    "topic": "GEO, Generative Engine Optimization",
    "type": "album", "medias": medias,
    "meta": {"title": "", "description": "", "url": ""},
    "additionalInfo": {"isAiGenerated": False, "isDraft": False,
        "collaborators": [], "mentions": [],
        "music": {"id":"","artist":"","name":"","thumbnail":""},
        "products": [], "tags": []},
    "replies": [{"text": r, "username": ""} for r in replies],
    "accountId": ACCOUNT, "scheduleAt": SLOT,
}

print("\n" + "=" * 50)
print("SCHEDULING TO STUDIOSOFT THREADS")
print(f"Slot: {SLOT} (20:00 WIB)")
print("=" * 50)

r = api_call("POST", "/public/schedule", payload)
if "error" in r:
    print(f"ERROR: {r['error']} - {r.get('body','')}")
else:
    print(f"SUCCESS! Schedule ID: {r.get('scheduleId','?')}")

print("\nDONE")
