#!/usr/bin/env python3
"""
Generator PIN PINTEREST (Lapis 3) — StudioSoft.id
=================================================
Bikin gambar pin vertikal 1000x1500 (rasio wajib Pinterest 2:3) dari daftar
artikel studiosoft.id yang masih FRESH (belum pernah dipakai di akun mana pun).

Output: pin_pinterest/pin_<slug>.jpg  +  pin_pinterest/manifest.json
        (manifest = siap dipakai buat upload manual Bos ATAU Pinterest API v5)

Jalankan: python3 gen_pin_pinterest.py            # 10 pin
          python3 gen_pin_pinterest.py --all      # semua artikel di stok
"""
import os, sys, json, re

from PIL import Image, ImageDraw, ImageFont

WS = os.path.dirname(os.path.abspath(__file__))
OUT = os.path.join(WS, 'pin_pinterest')
FRESH = '/tmp/ss_articles_fresh.json'

# ---- brand StudioSoft (dipakai konsisten dengan materi lain) -------------
NAVY = (13, 71, 97)
SKY = (56, 189, 248)
WHITE = (255, 255, 255)
INK = (10, 37, 51)

W, H = 1000, 1500

FONT_CANDIDATES = [
    '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf',
    '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',
]

# slug -> (kicker kecil di atas, judul besar di pin, deskripsi pin)
PINS = [
    ("jasa-seo-sidoarjo", "SEO LOKAL",
     "Jasa SEO Sidoarjo: Biar Bisnis Muncul\ndi Halaman 1 Google",
     "Bisnis lokal Sidoarjo kok susah muncul di Google? Ini cara kerjanya, "
     "dari riset kata kunci sampai konten yang bikin Google percaya. "
     "Panduan lengkapnya di sini 👉"),
    ("jasa-seo-malang", "SEO LOKAL",
     "Jasa SEO Malang: Peluang Bisnis\nLokal yang Masih Terbuka",
     "Malang masih punya banyak kata kunci yang belum digarap. "
     "Baca peluang + strategi SEO lokalnya di artikel ini."),
    ("digital-marketing-sidoarjo", "UMKM & KLINIK",
     "Digital Marketing Sidoarjo:\nPanduan untuk UMKM & Klinik",
     "Panduan praktis digital marketing untuk usaha jasa, UMKM, dan klinik "
     "di Sidoarjo — biar pelanggan datang sendiri, bukan nunggu viral."),
    ("konsultan-ai-surabaya", "AI UNTUK BISNIS",
     "Konsultan AI Surabaya:\nKapan Bisnis Butuh & Cara Memilih",
     "Jangan beli AI cuma karena lagi ramai. Ini tanda bisnis Anda memang "
     "butuh konsultan AI — dan cara memilih yang tidak buang-buang budget."),
    ("implementasi-ai-untuk-umkm", "AI UNTUK BISNIS",
     "Implementasi AI untuk UMKM:\nPanduan Mulai dari Nol (2026)",
     "Belum pernah pakai AI sama sekali? Mulai dari sini. Langkah pertama "
     "yang realistis untuk UMKM, tanpa tim IT."),
    ("jasa-chatbot-whatsapp-bisnis", "AI UNTUK BISNIS",
     "Chatbot WhatsApp:\nBiar Chat Masuk Nggak Numpuk Lagi",
     "Chat pelanggan numpuk tiap malam dan tidak sempat dibalas? Ini cara "
     "chatbot WA ngangkat beban admin Anda — tanpa pelanggan sadar dibalas bot."),
    ("jasa-automasi-marketing", "AI UNTUK BISNIS",
     "5 Tugas Marketing yang\nBisa Diserahkan ke AI",
     "5 tugas marketing yang paling cepat dipindah ke AI — plus mana yang "
     "TETAP harus dipegang manusia. Baca dulu sebelum otomasi."),
    ("branding-agency-surabaya", "BRANDING",
     "Branding Agency Surabaya:\nTanda Bahayanya & Cara Memilih",
     "Ciri branding agency yang bikin brand Anda stagnan — dan pertanyaan "
     "yang wajib Anda tanyakan sebelum tanda tangan kontrak."),
    ("branding-visual-surabaya", "BRANDING",
     "Branding Visual:\nElemen yang Bikin Brand Mudah Diingat",
     "Brand yang diingat bukan yang paling bagus, tapi yang paling "
     "KONSISTEN. Ini elemen visual yang harus diulang terus."),
    ("retainer-digital-marketing", "STRATEGI",
     "Retainer Digital Marketing:\nKapan Butuh & Cara Hitung Nilainya",
     "Retainer bukan cuma langganan jasa. Ini cara menghitung apakah "
     "retainer Anda menghasilkan atau cuma jadi biaya rutin."),
]


def clean(s):
    """buang HTML entity dari title.rendered WP."""
    s = re.sub(r'&#8216;|&#8217;', "'", s)
    s = re.sub(r'&#8220;|&#8221;', '"', s)
    s = s.replace('&#038;', '&').replace('&amp;', '&')
    s = re.sub(r'&#\d+;', '', s)
    return re.sub(r'\s+', ' ', s).strip()


def font(size, path_idx=0):
    for p in FONT_CANDIDATES[path_idx:]:
        try:
            return ImageFont.truetype(p, size)
        except Exception:
            continue
    return ImageFont.load_default()


def wrap(draw, text, fnt, max_w):
    """wrap manual, hormati \n yang sudah ditulis."""
    lines = []
    for para in text.split('\n'):
        words, cur = para.split(), ''
        for w in words:
            trial = (cur + ' ' + w).strip()
            if draw.textlength(trial, font=fnt) <= max_w:
                cur = trial
            else:
                if cur:
                    lines.append(cur)
                cur = w
        lines.append(cur)
    return lines


def make_pin(slug, kicker, title, desc, link, idx):
    img = Image.new('RGB', (W, H), NAVY)
    d = ImageDraw.Draw(img)

    # aksen diagonal lembut (sky) di kanan atas
    d.polygon([(W, 0), (W, 380), (W - 430, 0)], fill=(17, 88, 118))
    d.rectangle([0, 0, 22, H], fill=SKY)              # bar kiri
    d.rectangle([0, H - 250, W, H], fill=INK)          # blok bawah

    # kicker
    f_kick = font(38)
    d.text((80, 100), kicker, font=f_kick, fill=SKY)

    # judul besar (auto-fit)
    size = 92
    while size > 46:
        f_title = font(size)
        lines = wrap(d, title, f_title, W - 190)
        total_h = len(lines) * int(size * 1.28)
        if len(lines) <= 6 and total_h <= 780:
            break
        size -= 4
    y = 210
    for ln in lines:
        d.text((80, y), ln, font=f_title, fill=WHITE)
        y += int(size * 1.28)

    # nomor pin + brand
    f_small = font(34)
    d.text((80, H - 175), f"StudioSoft.id  •  {idx:02d}", font=f_small, fill=WHITE)
    d.text((80, H - 120), link.replace('https://', ''), font=f_small, fill=SKY)

    # tandai kalau deskripsi panjang (tidak dicetak ke gambar, hanya di manifest)
    path = os.path.join(OUT, f"pin_{idx:02d}_{slug}.jpg")
    img.save(path, 'JPEG', quality=88, optimize=True)
    return path


def main():
    os.makedirs(OUT, exist_ok=True)
    fresh = json.load(open(FRESH)) if os.path.exists(FRESH) else []
    by_slug = {a['slug']: a for a in fresh}
    want = PINS if '--all' not in sys.argv else [
        (a['slug'], 'STUDIOSOFT.ID', clean(a['title']['rendered']), '', a['link'])
        for a in fresh
    ]

    manifest = []
    for i, (slug, kicker, title, desc) in enumerate(want, 1):
        art = by_slug.get(slug)
        link = art['link'] if art else f"https://studiosoft.id/{slug}/"
        path = make_pin(slug, kicker, title, desc, link, i)
        manifest.append({
            'no': i, 'slug': slug, 'image': os.path.basename(path),
            'pin_title': clean(title.replace('\n', ' ')),
            'pin_description': clean(desc) + ' ' + link,
            'link': link,
            'board_usul': kicker,
        })
        print(f"[{i:02d}] {os.path.basename(path)}  ({os.path.getsize(path)//1024} KB)")

    mf = os.path.join(OUT, 'manifest.json')
    json.dump(manifest, open(mf, 'w'), indent=1, ensure_ascii=False)
    print(f"\nmanifest: {mf} ({len(manifest)} pin)")


if __name__ == '__main__':
    main()
