#!/usr/bin/env python3
"""Generate & schedule GEO carousel BG BIRU for StudioSoft Threads (1080x1350, 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_carousel"
os.makedirs(OUT_DIR, exist_ok=True)

W, H = 1080, 1350
MARGIN = 65
MAX_W = W - 2 * MARGIN

BLUE = "#1E40AF"
WHITE = "#FFFFFF"
LIGHT_BLUE = "#DBEAFE"
ACCENT_WHITE = "#E0E7FF"

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

def get_font(name, size):
    return ImageFont.truetype(os.path.join(FONT_DIR, f"Poppins-{name}.ttf"), size)

B128 = get_font("Bold", 128)
B110 = get_font("Bold", 110)
B90 = get_font("Bold", 90)
B80 = get_font("Bold", 80)
B70 = get_font("Bold", 70)
SB60 = get_font("SemiBold", 60)
SB50 = get_font("SemiBold", 50)
SB42 = get_font("SemiBold", 42)
R40 = get_font("Regular", 40)
R36 = get_font("Regular", 36)
R32 = get_font("Regular", 32)
R28 = get_font("Regular", 28)
R24 = get_font("Regular", 24)


def wrap_lines(draw, text, font, max_w):
    lines = []
    for para in text.split('\n'):
        if not para.strip():
            lines.append(('', font))
            continue
        words = para.split()
        cur = ""
        for w in words:
            test = cur + w + " "
            if draw.textlength(test, font=font) <= max_w:
                cur = test
            else:
                if cur:
                    lines.append((cur.rstrip(), font))
                cur = w + " "
        if cur.strip():
            lines.append((cur.rstrip(), font))
    return lines


def header_footer(draw, num, total=5, cover=False):
    """Draw header & footer on blue bg."""
    # Header
    draw.text((MARGIN, 30), "StudioSoft", fill=WHITE, font=R28)
    if not cover:
        draw.text((W - MARGIN, 30), f"{num}/{total}", fill=ACCENT_WHITE, font=R28, anchor="ra")
    # Footer
    draw.text((MARGIN, H - 50), "studiosoft.id", fill=ACCENT_WHITE, font=R28)
    draw.text((W - MARGIN, H - 50), "#GEO #SearchEverywhere", fill=ACCENT_WHITE, font=R28, anchor="ra")


def slide(num, content_blocks, cover=False):
    img = Image.new("RGB", (W, H), BLUE)
    draw = ImageDraw.Draw(img)

    header_footer(draw, num, cover=cover)

    y = 130 if not cover else 280
    for text, font_ov in content_blocks:
        font = font_ov if font_ov else R36
        lines = wrap_lines(draw, text, font, MAX_W)
        for lt, lf in lines:
            if lt:
                draw.text((MARGIN, y), lt, fill=WHITE, font=lf)
                y += lf.size + 8
        y += 10

    fname = f"{num:02d}_{'cover' if cover else 'slide'}.jpg"
    # Resize to 70% to reduce size
    nw, nh = int(W * 0.7), int(H * 0.7)
    img_small = img.resize((nw, nh), Image.LANCZOS)
    img_small.save(os.path.join(OUT_DIR, fname), quality=80, optimize=True)
    print(f"✅ {fname}")
    return os.path.join(OUT_DIR, fname)


# ── SLIDES ──

# Slide 1 — Cover
slide(1, [
    ("GEO: Generatif\nEngine\nOptimization", B110),
    ("", None),
    ("Strategi Baru Biar Brandmu", SB50),
    ("Disebut di Jawaban AI", SB50),
    ("", None),
    ("StudioSoft", SB42),
], cover=True)

# Slide 2 — Apa itu GEO?
slide(2, [
    ("Apa Itu GEO?", B90),
    ("", None),
    ("GEO (Generative Engine Optimization) adalah strategi\noptimasi konten biar brand & websitemu muncul\nsebagai referensi di jawaban AI seperti ChatGPT,\nGemini, Perplexity, dan Google AI Overviews.", R36),
    ("", None),
    ("Berbeda dari SEO yang fokus ranking di 10 link biru,\nGEO fokus pada bagaimana AI memahami, memilih,\ndan mengutip kontenmu.", R36),
])

# Slide 3 — Kenapa GEO penting?
slide(3, [
    ("Kenapa GEO Penting?", B90),
    ("", None),
    ("\u2022  73% search intent masih di Google\n   (SparkToro, 2025)", R36),
    ("", None),
    ("\u2022  27% sisanya tersebar di 40+ platform:\n   ChatGPT, YouTube, Reddit, TikTok, Amazon", R36),
    ("", None),
    ("\u2022  Referral dari AI/LLM naik 800%\n   dalam 3 bulan (Backlinko)", R36),
    ("", None),
    ("\u2022  AI 6,5x lebih sering mengutip brand\n   dari sumber pihak ketiga (Kevin Indig)", R36),
])

# Slide 4 — SEO vs GEO
slide(4, [
    ("SEO vs GEO", B90),
    ("", None),
    ("SEO", B70),
    ("Keyword + backlink + ranking\nGoogle SERP", R36),
    ("", None),
    ("GEO", B70),
    ("Konten informatif + otoritas\npihak ketiga + disebut AI", R36),
    ("", None),
    ("Keduanya saling melengkapi.\nJangan pilih salah satu \u2014 kuasai dua-duanya.", SB50),
])

# Slide 5 — CTA
slide(5, [
    ("Siap Mulai GEO?", B90),
    ("", None),
    ("3 langkah awal:", SB50),
    ("", None),
    ("1. Audit \u2014 di mana audiensmu\n   mencari informasi?", R36),
    ("", None),
    ("2. Optimasi platform \u2014 website,\n   GBP, sosmed, YouTube", R36),
    ("", None),
    ("3. Bangun otoritas \u2014 guest post,\n   ulasan, publikasi industri", R36),
    ("", None),
    ("Yang adaptasi sekarang,\nyang menang di 2027.", B80),
    ("", None),
    ("Konsultasi: wa.me/6281935000624", SB42),
])

print(f"\nSemua slide tersimpan di {OUT_DIR}/")

# ── SCHEDULE TO THREADS ──

SLOT = "2026-07-25T13:00:00.000Z"  # 20:00 WIB
FILES = [f"{i:02d}_{'cover' if i==1 else 'slide'}.jpg" for i in range(1, 6)]
ACCOUNT = "6a335b9ec5ff4ce3a3225c2a"  # StudioSoft Threads

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()
            if resp.status == 204:
                return {"success": True}
            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": fname.replace(".jpg", "").replace("_", " "),
    })

caption = (
    "GEO (Generative Engine Optimization) adalah strategi baru "
    "yang nggak bisa diabaikan di 2026.\n\n"
    "Sementara 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 kehilangan traffic besar.\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 influenced (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" + "=" * 60)
print("SCHEDULING TO STUDIOSOFT THREADS")
print(f"Slot: {SLOT} (20:00 WIB)")
print("=" * 60)

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")
