#!/usr/bin/env python3
"""GEO Carousel BG Biru StudioSoft — redesigned with better visual design."""
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 = W - 2*M

BLUE = "#1E40AF"
WHITE = "#FFFFFF"
ACCENT = "#DBEAFE"
DARK_BLUE = "#1A3599"

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

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

B160 = ft("Bold", 160)
B140 = ft("Bold", 140)
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)
SB55 = ft("SemiBold", 55)
SB45 = ft("SemiBold", 45)
SB40 = ft("SemiBold", 40)
SB35 = ft("SemiBold", 35)
R42  = ft("Regular", 42)
R38  = ft("Regular", 38)
R36  = ft("Regular", 36)
R32  = ft("Regular", 32)
R28  = ft("Regular", 28)
R24  = ft("Regular", 24)

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

# ─────────────── HELPERS ────────────────

def header(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")

def footer(draw):
    draw.text((M, H-45), "studiosoft.id", fill=ACCENT, font=R24)

def divider(draw, y):
    draw.rectangle([(M, y), (W-M, y+3)], fill=ACCENT)

def number_circle(draw, x, y, num, r=35):
    """Draw numbered circle."""
    draw.ellipse([(x-r, y-r), (x+r, y+r)], fill=ACCENT, outline=None)
    draw.text((x, y), str(num), fill=BLUE, font=ft("Bold", 40), anchor="mm")

def draw_content(img, num, title, subtitle, items, cta_text=None):
    """Standard content slide with visual hierarchy."""
    draw = ImageDraw.Draw(img)
    header(draw, num)
    footer(draw)
    
    # Title
    tw = draw.textlength(title, font=B80)
    draw.text((M, 140), title, fill=WHITE, font=B80)
    
    # Accent line under title
    divider(draw, 230)
    
    # Subtitle
    if subtitle:
        draw.text((M, 270), subtitle, fill=ACCENT, font=SB45)
    
    y = 350 if subtitle else 280
    
    for item in items:
        if item.get('icon'):
            # Icon circle with number
            num_text = item['icon']
            nd = draw.textlength(num_text, font=ft("Bold", 40))
            cx = M + nd//2 + 20
            number_circle(draw, cx, y + 25, num_text, r=28)
            
            text_x = M + 80
            # Title of item
            if item.get('title'):
                draw.text((text_x, y), item['title'], fill=WHITE, font=SB45)
                y += 50
            # Desc
            if item.get('desc'):
                lines = wrap(draw, item['desc'], R36, MX_W - 80)
                for lt, lf in lines:
                    if lt: draw.text((text_x, y), lt, fill=ACCENT, font=lf)
                    y += lf.size + 6
                y += 15
        elif item.get('type') == 'big':
            lines = wrap(draw, item['text'], item.get('font', B60), MX_W)
            for lt, lf in lines:
                if lt: draw.text((M, y), lt, fill=WHITE, font=lf)
                y += lf.size + 8
            y += 10
        elif item.get('type') == 'accent':
            lines = wrap(draw, item['text'], item.get('font', SB45), MX_W)
            for lt, lf in lines:
                if lt: draw.text((M, y), lt, fill=ACCENT, font=lf)
                y += lf.size + 8
            y += 10
        elif item.get('type') == 'data':
            # Large data number
            draw.text((M, y), item['number'], fill=WHITE, font=B70)
            y += 75
            lines = wrap(draw, item['label'], R36, MX_W)
            for lt, lf in lines:
                if lt: draw.text((M, y), lt, fill=ACCENT, font=lf)
                y += lf.size + 6
            y += 10
        else:
            lines = wrap(draw, item.get('text', ''), R36, MX_W)
            for lt, lf in lines:
                if lt: draw.text((M, y), lt, fill=ACCENT, font=lf)
                y += lf.size + 6
            y += 8
    
    # CTA at bottom
    if cta_text:
        draw.rounded_rectangle([(M, H-180), (W-M, H-120)], radius=12, fill=ACCENT)
        draw.text((W//2, H-150), cta_text, fill=BLUE, font=SB40, anchor="mm")
    
    return img


# ════════════ SLIDE 1 — COVER ════════════

def slide_cover():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header(draw, 1, cover=True)
    footer(draw)
    
    # Main title "GEO" large
    draw.text((M, 320), "GEO", fill=WHITE, font=B160)
    
    draw.text((M, 500), "Generative Engine Optimization", fill=ACCENT, font=SB45)
    
    # Divider
    divider(draw, 600)
    
    # Subtitle
    draw.text((M, 660), "Strategi Baru Biar Brandmu", fill=WHITE, font=B60)
    draw.text((M, 735), "Disebut di Jawaban AI", fill=WHITE, font=B60)
    
    # Description
    draw.text((M, 880), "Bukan Cuma SEO \u2014 Optimasi untuk Google,", fill=ACCENT, font=R36)
    draw.text((M, 925), "ChatGPT, Gemini, Perplexity & AI Lainnya", fill=ACCENT, font=R36)
    
    # Brand
    draw.text((M, H-280), "StudioSoft", fill=WHITE, font=B50)
    draw.text((M, H-210), "Partner Pertumbuhan Bisnis Berbasis Data", fill=ACCENT, font=R32)
    
    f = f"{OUT_DIR}/01_cover.jpg"
    img.save(f, quality=82)
    print(f"✅ 01_cover.jpg ({os.path.getsize(f)//1024}KB)")
    return f

# ════════ SLIDE 2 — APA ITU GEO ════════

def slide_2():
    img = Image.new("RGB", (W, H), BLUE)
    draw_content(img, 2, "Apa Itu GEO?", 
        "Generative Engine Optimization",
        [
            {'icon': '1', 'title': 'Optimasi untuk AI', 'desc': 'Strategi optimasi konten biar brand &\nwebsite muncul sebagai referensi di jawaban\nAI seperti ChatGPT, Gemini, Perplexity.'},
            {'icon': '2', 'title': 'Bukan SEO Biasa', 'desc': 'SEO fokus ranking di 10 link biru Google.\nGEO fokus bagaimana AI memahami, memilih,\ndan mengutip kontenmu.'},
            {'icon': '3', 'title': 'Kenapa Berbeda?', 'desc': 'AI nggak nampilin link \u2014 AI nyusun jawaban\ndari berbagai sumber. Kontenmu harus layak\njadi referensi, bukan cuma ranking.'},
        ])
    f = f"{OUT_DIR}/02_slide.jpg"
    img.save(f, quality=82)
    print(f"✅ 02_slide.jpg ({os.path.getsize(f)//1024}KB)")
    return f

# ════════ SLIDE 3 — KENAPA PENTING ════════

def slide_3():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header(draw, 3)
    footer(draw)
    
    draw.text((M, 140), "Kenapa GEO Penting?", fill=WHITE, font=B80)
    divider(draw, 230)
    draw.text((M, 270), "Data yang Wajib Kamu Tahu", fill=ACCENT, font=SB45)
    
    # Data cards
    data = [
        ("73%", "search intent masih\ndi Google (SparkToro)"),
        ("27%", "sisanya tersebar di\n40+ platform lain"),
        ("800%", "kenaikan referral AI/LLM\ndalam 3 bulan (Backlinko)"),
        ("6,5x", "AI lebih sering mengutip\nbrand dari pihak ke-3"),
    ]
    
    y = 380
    for i, (num, label) in enumerate(data):
        col_x = M if i % 2 == 0 else W//2 + 20
        if i % 2 == 0:
            row_y = y + (i//2) * 240
        else:
            row_y = y + (i//2) * 240
        
        # Number
        draw.text((col_x, row_y), num, fill=WHITE, font=B70)
        # Label
        lines = wrap(draw, label, R32, MX_W//2 - 40)
        ly = row_y + 80
        for lt, lf in lines:
            if lt:
                draw.text((col_x, ly), lt, fill=ACCENT, font=lf)
                ly += lf.size + 4
    
    # Bottom note
    draw.text((M, H-220), "Ini bukan tren \u2014 ini perubahan fundamental", fill=WHITE, font=SB45)
    draw.text((M, H-160), "cara orang mencari informasi.", fill=WHITE, font=SB45)
    
    f = f"{OUT_DIR}/03_slide.jpg"
    img.save(f, quality=82)
    print(f"✅ 03_slide.jpg ({os.path.getsize(f)//1024}KB)")
    return f

# ════════ SLIDE 4 — SEO vs GEO ════════

def slide_4():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header(draw, 4)
    footer(draw)
    
    draw.text((M, 140), "SEO vs GEO", fill=WHITE, font=B80)
    divider(draw, 230)
    draw.text((M, 270), "Pahami Bedanya, Kuasai Dua-duanya", fill=ACCENT, font=SB45)
    
    # Left column - SEO
    x_seo = M
    x_geo = W//2 + 20
    
    # SEO box
    draw.rounded_rectangle([(x_seo, 350), (x_geo-15, 700)], radius=15, fill=None, outline=ACCENT, width=2)
    draw.text((x_seo+30, 380), "SEO", fill=WHITE, font=B60)
    
    seo_items = [
        "Keyword + Backlink",
        "Ranking di Google SERP",
        "Fokus pada 10 link biru",
        "Traffic dari klik organik",
        "Algoritma Google",
    ]
    sy = 460
    for it in seo_items:
        draw.ellipse([(x_seo+30, sy+8), (x_seo+46, sy+24)], fill=ACCENT)
        draw.text((x_seo+60, sy), it, fill=ACCENT, font=R32)
        sy += 42
    
    # GEO box  
    draw.rounded_rectangle([(x_geo, 350), (W-M, 700)], radius=15, fill=None, outline=ACCENT, width=2)
    draw.text((x_geo+30, 380), "GEO", fill=WHITE, font=B60)
    
    geo_items = [
        "Konten Informatif + Authoritas",
        "Disebut di Jawaban AI",
        "Fokus pada Semua Platform",
        "Traffic dari ChatGPT, Gemini, dll",
        "Pemahaman & Relevansi AI",
    ]
    gy = 460
    for it in geo_items:
        draw.ellipse([(x_geo+30, gy+8), (x_geo+46, gy+24)], fill=ACCENT)
        draw.text((x_geo+60, gy), it, fill=ACCENT, font=R32)
        gy += 42
    
    # Bottom message
    draw.text((M, 780), "Keduanya saling melengkapi", fill=WHITE, font=B50)
    draw.text((M, 845), "Jangan pilih salah satu \u2014 kuasai dua-duanya.", fill=ACCENT, font=SB45)
    
    # Neil Patel quote
    draw.text((M, 960), "\u201cSEO dulu soal ranking.", fill=ACCENT, font=R36)
    draw.text((M, 1005), "Sekarang soal relevance dan trust", fill=ACCENT, font=R36)
    draw.text((M, 1050), "di tiap platform.\u201d", fill=ACCENT, font=R36)
    draw.text((M, 1110), "\u2014 Neil Patel", fill=ACCENT, font=SB35)
    
    f = f"{OUT_DIR}/04_slide.jpg"
    img.save(f, quality=82)
    print(f"✅ 04_slide.jpg ({os.path.getsize(f)//1024}KB)")
    return f

# ════════ SLIDE 5 — CTA ════════

def slide_5():
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)
    header(draw, 5)
    footer(draw)
    
    draw.text((M, 140), "Siap Mulai GEO?", fill=WHITE, font=B80)
    divider(draw, 230)
    draw.text((M, 270), "3 Langkah Awal", fill=ACCENT, font=SB45)
    
    steps = [
        ("1", "Audit", "Di mana audiensmu mencari\ninformasi? Google? ChatGPT?\nYouTube? Reddit?"),
        ("2", "Optimasi", "Website, Google Business Profile,\nsosmed, YouTube \u2014 pastikan\nsemua rapi dan konsisten."),
        ("3", "Otoritas", "Guest post, ulasan, publikasi\nindustri. AI 6,5x lebih suka\nsumber pihak ketiga."),
    ]
    
    y = 360
    for num, title, desc in steps:
        # Circle number
        number_circle(draw, M+25, y+30, num, r=30)
        # Title
        draw.text((M+80, y), title, fill=WHITE, font=B60)
        y += 70
        # Desc
        lines = wrap(draw, desc, R36, MX_W - 80)
        for lt, lf in lines:
            if lt:
                draw.text((M+80, y), lt, fill=ACCENT, font=lf)
                y += lf.size + 6
        y += 40
    
    # Big closing
    draw.text((M, y+20), "Yang adaptasi sekarang,", fill=WHITE, font=B80)
    draw.text((M, y+105), "yang menang di 2027.", fill=WHITE, font=B80)
    
    # CTA Button
    y_cta = H - 200
    draw.rounded_rectangle([(M, y_cta), (W-M, y_cta+65)], radius=12, 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 ({os.path.getsize(f)//1024}KB)")
    return f

# ════════════ GENERATE ════════════
print("=" * 50)
print("GENERATING SLIDES")
print("=" * 50)
slide_cover()
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]}

medias = []
for fname in 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 Generative Engine Optimization",
    })

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: referral dari AI/LLM 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 pintu gerbang pertama "
    "konsumen sebelum ke website.",

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

payload = {
    "title": "",
    "description": caption,
    "topic": "GEO, Generative Engine Optimization, SEO",
    "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")
