#!/usr/bin/env python3
"""
StudioSoft — GEO Carousel (5 Slides)
Template persis studiosoft_bg_biru.py
Margin 50px rata • Konten vertical-middle
Judul 100px Poppins Bold • Body 28px Poppins Regular
1080x1350 (4:5) • BG Biru #1E40AF
"""

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_fix"
os.makedirs(OUT_DIR, exist_ok=True)

W, H = 1080, 1350
BG = (30, 64, 175)
WHITE = (255, 255, 255)
SOFT = (180, 200, 240)
M = 50
CW = W - 2*M  # 980

FD = os.path.expanduser("~/.fonts")

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

def fw(d, text, font):
    return d.textbbox((0,0), text, font=font)[2]

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

def wrap(d, text, font, mx):
    lines = []
    for p in text.split("\n"):
        ws = p.split()
        cur = ""
        for w in ws:
            t = (cur + " " + w) if cur else w
            if fw(d, t, font) > mx and cur:
                lines.append(cur)
                cur = w
            else:
                cur = t
        if cur: lines.append(cur)
    return lines

def block_h(d, content, font, mx, ls=1.35):
    lines = wrap(d, content, font, mx)
    total = 0
    for line in lines:
        total += int(fh(d, line, font) * ls)
    return total

def draw_block(d, text, x, y, font, fill, mx, ls=1.35):
    for line in wrap(d, text, font, mx):
        lh = fh(d, line, font)
        d.text((x, y), line, font=font, fill=fill)
        y += int(lh * ls)
    return y

def header(d, page):
    d.text((M, M), "STUDIOSOFT", font=B36, fill=WHITE)
    d.text((W-M, M), page, font=R22, fill=WHITE, anchor="rt")

def divider(d, x, y, w=300):
    dx = x
    while dx < x + w:
        e = min(dx + 14, x + w)
        d.line([(dx, y), (e, y)], fill=WHITE, width=2)
        dx += 24

def footer(d, left="www.studiosoft.id", right=""):
    d.text((M, H-130), left, font=R20, fill=WHITE)
    if right:
        d.text((W-M, H-130), right, font=R20, fill=WHITE, anchor="rt")

def clean_edges(im):
    px = im.load()
    for y in range(H):
        for x in range(3): px[x,y] = BG
        for x in range(W-3, W): px[x,y] = BG
    for y in range(H-5, H):
        for x in range(W): px[x,y] = BG
    for x in range(W):
        for y in range(3): px[x,y] = BG

# ==========================================
# SLIDE 1 — COVER
# ==========================================
im = Image.new("RGB", (W, H), BG)
d = ImageDraw.Draw(im)
header(d, "01/05")

hdr_h = fh(d, "STUDIOSOFT", B36)
total_h = 0

# Title
for t in ["GEO", "GENERATIVE ENGINE", "OPTIMIZATION"]:
    total_h += int(fh(d, t, J100) * 1.15)

# Divider
divider_w = 300
total_h += 60 + 5 + 55

# Subtitle
sub_h = block_h(d, "Strategi Baru Biar Brandmu Disebut di Jawaban AI", R28, CW)
total_h += sub_h + 20

# Description
desc_h = block_h(d, "Bukan cuma SEO \u2014 optimasi untuk Google, ChatGPT,", R28, CW)
desc_h2 = block_h(d, "Gemini, Perplexity & AI Lainnya", R28, CW)
total_h += desc_h + desc_h2 + 15

# Check items
check_h = 0
for item in ["\u2611  Optimasi untuk Generatif AI",
             "\u2611  Bukan SEO Biasa",
             "\u2611  Semua Platform"]:
    check_h += int(fh(d, item, R28) * 1.3)
total_h += check_h

usable = H - 2*M - hdr_h - 20
start_y = M + hdr_h + 20 + (usable - total_h) // 2

ty = start_y
for t in ["GEO", "GENERATIVE ENGINE", "OPTIMIZATION"]:
    d.text((M, ty), t, font=J100, fill=WHITE)
    ty += int(fh(d, t, J100) * 1.15)

ty += 30
divider(d, M, ty, divider_w)
ty += 25

ty = draw_block(d, "Strategi Baru Biar Brandmu Disebut di Jawaban AI", M, ty, R28, SOFT, CW)
ty += 15

ty = draw_block(d, "Bukan cuma SEO \u2014 optimasi untuk Google, ChatGPT,", M, ty, R28, SOFT, CW)
ty = draw_block(d, "Gemini, Perplexity & AI Lainnya", M, ty, R28, SOFT, CW)
ty += 10

for item in ["\u2611  Optimasi untuk Generatif AI",
             "\u2611  Bukan SEO Biasa",
             "\u2611  Semua Platform"]:
    d.text((M, ty), item, font=R28, fill=WHITE)
    ty += int(fh(d, item, R28) * 1.3)

footer(d, "studiosoft.id", "Swipe \u2192")
clean_edges(im)
f = f"{OUT_DIR}/01_cover.jpg"
im.save(f, quality=88)
print(f"✅ 01_cover.jpg ({0}KB)")

# ==========================================
# SLIDE 2 — APA ITU GEO
# ==========================================
im = Image.new("RGB", (W, H), BG)
d = ImageDraw.Draw(im)
header(d, "02/05")

total_h = 0
for t in ["APA ITU", "GEO?"]:
    total_h += int(fh(d, t, J100) * 1.15)
total_h += 60 + 5 + 55

# Desc
d1 = block_h(d, "GEO (Generative Engine Optimization) adalah strategi", R28, CW)
d2 = block_h(d, "optimasi konten biar brand dan websitemu muncul", R28, CW)
d3 = block_h(d, "sebagai referensi di jawaban AI seperti ChatGPT,", R28, CW)
d4 = block_h(d, "Gemini, Perplexity, dan Google AI Overviews.", R28, CW)
total_h += d1 + d2 + d3 + d4 + 15

# Items
for item in ["\u2611  SEO \u2192 ranking di 10 link biru Google",
             "\u2611  GEO \u2192 AI memahami, memilih & mengutip kontenmu"]:
    total_h += int(fh(d, item, R28) * 1.3)

usable = H - 2*M - hdr_h - 20
start_y = M + hdr_h + 20 + (usable - total_h) // 2

ty = start_y
for t in ["APA ITU", "GEO?"]:
    d.text((M, ty), t, font=J100, fill=WHITE)
    ty += int(fh(d, t, J100) * 1.15)

ty += 30
divider(d, M, ty, 300)
ty += 25

ty = draw_block(d, "GEO (Generative Engine Optimization) adalah strategi", M, ty, R28, SOFT, CW)
ty = draw_block(d, "optimasi konten biar brand dan websitemu muncul", M, ty, R28, SOFT, CW)
ty = draw_block(d, "sebagai referensi di jawaban AI seperti ChatGPT,", M, ty, R28, SOFT, CW)
ty = draw_block(d, "Gemini, Perplexity, dan Google AI Overviews.", M, ty, R28, SOFT, CW)
ty += 15

for item in ["\u2611  SEO \u2192 ranking di 10 link biru Google",
             "\u2611  GEO \u2192 AI memahami, memilih & mengutip kontenmu"]:
    d.text((M, ty), item, font=R28, fill=WHITE)
    ty += int(fh(d, item, R28) * 1.3)

footer(d, "studiosoft.id")
clean_edges(im)
f = f"{OUT_DIR}/02_slide.jpg"
im.save(f, quality=88)
print(f"✅ 02_slide.jpg ({0}KB)")

# ==========================================
# SLIDE 3 — KENAPA GEO PENTING
# ==========================================
im = Image.new("RGB", (W, H), BG)
d = ImageDraw.Draw(im)
header(d, "03/05")

total_h = 0
for t in ["KENAPA GEO", "PENTING?"]:
    total_h += int(fh(d, t, J100) * 1.15)
total_h += 60 + 5 + 55

# Data points
for item in ["\u2611  73% search intent masih di Google (SparkToro)",
             "\u2611  27% tersebar di 40+ platform lain",
             "\u2611  800% kenaikan referral AI/LLM (Backlinko)",
             "\u2611  6,5x AI lebih sering mengutip pihak ke-3"]:
    total_h += int(fh(d, item, R28) * 1.3)

total_h += 20
last = block_h(d, "Ini bukan tren \u2014 ini perubahan fundamental cara", R28, CW)
last2 = block_h(d, "orang mencari informasi.", R28, CW)
total_h += last + last2

usable = H - 2*M - hdr_h - 20
start_y = M + hdr_h + 20 + (usable - total_h) // 2

ty = start_y
for t in ["KENAPA GEO", "PENTING?"]:
    d.text((M, ty), t, font=J100, fill=WHITE)
    ty += int(fh(d, t, J100) * 1.15)

ty += 30
divider(d, M, ty, 300)
ty += 25

for item in ["\u2611  73% search intent masih di Google (SparkToro)",
             "\u2611  27% tersebar di 40+ platform lain",
             "\u2611  800% kenaikan referral AI/LLM (Backlinko)",
             "\u2611  6,5x AI lebih sering mengutip pihak ke-3"]:
    d.text((M, ty), item, font=R28, fill=WHITE)
    ty += int(fh(d, item, R28) * 1.3)

ty += 15
ty = draw_block(d, "Ini bukan tren \u2014 ini perubahan fundamental cara", M, ty, R28, SOFT, CW)
ty = draw_block(d, "orang mencari informasi.", M, ty, R28, SOFT, CW)

footer(d, "studiosoft.id")
clean_edges(im)
f = f"{OUT_DIR}/03_slide.jpg"
im.save(f, quality=88)
print(f"✅ 03_slide.jpg ({0}KB)")

# ==========================================
# SLIDE 4 — SEO vs GEO
# ==========================================
im = Image.new("RGB", (W, H), BG)
d = ImageDraw.Draw(im)
header(d, "04/05")

total_h = 0
for t in ["SEO", "VS", "GEO"]:
    total_h += int(fh(d, t, J100) * 1.15)
total_h += 60 + 5 + 55

for item in ["\u2611  SEO: keyword, backlink, ranking Google SERP",
             "\u2611  GEO: konten informatif, disebut jawaban AI",
             "\u2611  Keduanya saling melengkapi"]:
    total_h += int(fh(d, item, R28) * 1.3)

total_h += 20
qt = block_h(d, "\u201cSEO dulu soal ranking. Sekarang soal", R28, CW)
qt2 = block_h(d, "relevance dan trust di tiap platform.\u201d", R28, CW)
qt3 = block_h(d, "\u2014 Neil Patel", R28, CW)
total_h += qt + qt2 + qt3

usable = H - 2*M - hdr_h - 20
start_y = M + hdr_h + 20 + (usable - total_h) // 2

ty = start_y
for t in ["SEO", "VS", "GEO"]:
    d.text((M, ty), t, font=J100, fill=WHITE)
    ty += int(fh(d, t, J100) * 1.15)

ty += 30
divider(d, M, ty, 300)
ty += 25

for item in ["\u2611  SEO: keyword, backlink, ranking Google SERP",
             "\u2611  GEO: konten informatif, disebut jawaban AI",
             "\u2611  Keduanya saling melengkapi"]:
    d.text((M, ty), item, font=R28, fill=WHITE)
    ty += int(fh(d, item, R28) * 1.3)

ty += 15
ty = draw_block(d, "\u201cSEO dulu soal ranking. Sekarang soal", M, ty, R28, SOFT, CW)
ty = draw_block(d, "relevance dan trust di tiap platform.\u201d", M, ty, R28, SOFT, CW)
ty = draw_block(d, "\u2014 Neil Patel", M, ty, R28, SOFT, CW)

footer(d, "studiosoft.id")
clean_edges(im)
f = f"{OUT_DIR}/04_slide.jpg"
im.save(f, quality=88)
print(f"✅ 04_slide.jpg ({0}KB)")

# ==========================================
# SLIDE 5 — SIAP MULAI
# ==========================================
im = Image.new("RGB", (W, H), BG)
d = ImageDraw.Draw(im)
header(d, "05/05")

total_h = 0
for t in ["SIAP MULAI", "GEO?"]:
    total_h += int(fh(d, t, J100) * 1.15)
total_h += 60 + 5 + 55

for item in ["\u2611  Audit \u2014 di mana audiensmu mencari?",
             "\u2611  Optimasi \u2014 website, GBP, sosmed",
             "\u2611  Otoritas \u2014 guest post, ulasan"]:
    total_h += int(fh(d, item, R28) * 1.3)

total_h += 20
ct = block_h(d, "Yang adaptasi sekarang, yang menang di 2027.", R28, CW)
total_h += ct
total_h += 20
cta = block_h(d, "Konsultasi: 0819-3500-0624", R28, CW)
total_h += cta

usable = H - 2*M - hdr_h - 20
start_y = M + hdr_h + 20 + (usable - total_h) // 2

ty = start_y
for t in ["SIAP MULAI", "GEO?"]:
    d.text((M, ty), t, font=J100, fill=WHITE)
    ty += int(fh(d, t, J100) * 1.15)

ty += 30
divider(d, M, ty, 300)
ty += 25

for item in ["\u2611  Audit \u2014 di mana audiensmu mencari?",
             "\u2611  Optimasi \u2014 website, GBP, sosmed",
             "\u2611  Otoritas \u2014 guest post, ulasan"]:
    d.text((M, ty), item, font=R28, fill=WHITE)
    ty += int(fh(d, item, R28) * 1.3)

ty += 15
ty = draw_block(d, "Yang adaptasi sekarang, yang menang di 2027.", M, ty, R28, SOFT, CW)
ty += 15
ty = draw_block(d, "Konsultasi: 0819-3500-0624", M, ty, R28, WHITE, CW)

footer(d, "studiosoft.id")
clean_edges(im)
f = f"{OUT_DIR}/05_slide.jpg"
im.save(f, quality=88)
print(f"✅ 05_slide.jpg ({0}KB)")

print("\n✅ Selesai! 5 slides.")

# ════════════ 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 Exception as e:
        return {"error": str(e)}

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

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"
    "Yang nggak siap sekarang, 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 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']}")
else:
    print(f"SUCCESS! ID: {r.get('scheduleId','?')}")
print("\nDONE")
