#!/usr/bin/env python3
"""
Publish 1 Artikel StudioSoft — Core Web Vitals 2026
SEO Playbook, ±1300 kata, tags, featured Pexels, Yoast hijau, WA Button.
Jadwal tayang: 2026-08-10 09:00 WIB (Senin).
"""
import json, os, base64, urllib.request, time, re, io, sys
import urllib.parse, urllib.error
from datetime import datetime, timedelta, timezone

DOMAIN = "https://studiosoft.id"
WP_USER = "bambangbot"
WP_APP_PASS = "q26r RePo BVy6 pwU2 F3z7 ouyl"
AUTH = base64.b64encode(f"{WP_USER}:{WP_APP_PASS}".encode()).decode()
HEADERS = {"Authorization": f"Basic {AUTH}", "Content-Type": "application/json", "User-Agent": "AtunBot/1.0"}

# WA Button
WA_NUMBER = "6281935000624"
WA_TEXT = "Halo StudioSoft! Saya ingin konsultasi tentang optimasi Core Web Vitals & kecepatan website bisnis saya."
WA_LINK = f"https://wa.me/{WA_NUMBER}?text={urllib.parse.quote(WA_TEXT)}"
CTA_TEXT = "Gratis Konsultasi — Hubungi Kami via WhatsApp"

# Kategori & tag
CAT_SEO = 330
CAT_DIGITAL_MARKETING = 329  # fallback bila 326 dll; lihat hasil: Digital Marketing id326? kami pakai yg valid dari fetch (330=SEO,326=Digital Marketing)
ASSET_DIR = "/home/mantapman/.hermes/profiles/atun/workspace/artikel_ss_corewebvitals_images"
os.makedirs(ASSET_DIR, exist_ok=True)

# Featured Pexels (dari pencarian valid: laptop/workspace)
FEATURED_URL = "https://images.pexels.com/photos/265101/pexels-photo-265101.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"

def wp_request(endpoint, method="GET", data=None):
    url = f"{DOMAIN}/wp-json/wp/v2/{endpoint}"
    body = json.dumps(data).encode() if data else None
    h = dict(HEADERS)
    req = urllib.request.Request(url, data=body, headers=h, method=method)
    try:
        with urllib.request.urlopen(req, timeout=40) as r:
            return json.loads(r.read())
    except urllib.error.HTTPError as e:
        print(f"  HTTP {e.code}: {e.read().decode()[:300]}")
        return None
    except Exception as e:
        print(f"  Error: {e}")
        return None

def ensure_tag(name):
    from urllib.error import HTTPError
    try:
        existing = json.loads(urllib.request.urlopen(
            f"{DOMAIN}/wp-json/wp/v2/tags?per_page=100&orderby=name",
            headers={"Authorization": f"Basic {AUTH}", "User-Agent":"Mozilla/5.0"}).read())
    except Exception:
        existing = []
    tag_map = {t["name"].lower(): t for t in existing}
    key = name.lower()
    if key in tag_map:
        print(f"   * Tag '{name}' exists (ID {tag_map[key]['id']})")
        return tag_map[key]["id"]
    r = wp_request("tags", method="POST", data={"name": name})
    if r and "id" in r:
        print(f"   + Tag '{name}' created (ID {r['id']})")
        return r["id"]
    print(f"   ! Gagal buat tag '{name}'")
    return None

def upload_image(url, filename):
    print(f"   Downloading featured: {url}")
    try:
        req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
        with urllib.request.urlopen(req, timeout=40) as r:
            img_bytes = r.read()
        from PIL import Image
        img = Image.open(io.BytesIO(img_bytes))
        target_w, target_h = 1000, 567
        img_w, img_h = img.size
        ratio = target_w / target_h
        if img_w / img_h > ratio:
            new_h, new_w = img_h, int(img_h * ratio)
        else:
            new_w, new_h = img_w, int(img_w / ratio)
        img2 = img.resize((new_w, new_h), Image.LANCZOS)
        left = (new_w - target_w)//2; top = (new_h - target_h)//2
        img2 = img2.crop((left, top, left+target_w, top+target_h))
        buf = io.BytesIO()
        img2.save(buf, "JPEG", quality=90)
        img_bytes = buf.getvalue()
        local = os.path.join(ASSET_DIR, filename)
        with open(local, "wb") as f: f.write(img_bytes)
        print(f"   Image prepared 1000x567 ({len(img_bytes)/1024:.0f}KB)")
        upload_url = f"{DOMAIN}/wp-json/wp/v2/media"
        h = {"Authorization": f"Basic {AUTH}",
             "Content-Disposition": f'attachment; filename="{filename}"',
             "Content-Type": "image/jpeg"}
        req2 = urllib.request.Request(upload_url, data=img_bytes, headers=h, method="POST")
        with urllib.request.urlopen(req2, timeout=60) as r2:
            res = json.loads(r2.read())
        print(f"   Uploaded (ID {res['id']})")
        return res["id"], res["source_url"]
    except Exception as e:
        print(f"   Image error: {e}")
        return None, None

# ===== ARTIKEL =====
JUDUL = "Core Web Vitals: Kunci Kecepatan Website agar Naik Peringkat di Google 2026"
SLUG = "core-web-vitals-kecepatan-website-2026"
META_DESC = "Panduan lengkap Core Web Vitals 2026: LCP, INP, CLS, cara ukur di PageSpeed Insights, dan langkah optimasi agar website cepat naik peringkat Google."
FOCUS_KW = "core web vitals kecepatan website 2026"
CTA_TITLE = "Siap Optimasi Kecepatan & SEO Website Anda?"
CTA_DESC = "StudioSoft — Pakar SEO & Digital Marketing Specialist siap membantu website Anda tampil super cepat, hijau di Core Web Vitals, dan naik peringkat Google. Konsultasi gratis tanpa biaya."

PAR = "paragraf"; SUB = "subjudul"; LIS = "list_poin"
KONTEN = [
 (PAR, "Kecepatan website bukan lagi sekadar kenyamanan — di tahun 2026, kecepatan adalah salah satu penentu utama apakah bisnis Anda muncul di halaman pertama Google atau tenggelam di halaman berikutnya. Google menjadikan pengalaman pengguna sebagai prioritas, dan salah satu tolok ukurnya adalah Core Web Vitals. Artikel ini akan membahas apa itu Core Web Vitals, mengapa sangat penting, dan langkah praktis cara mengoptimasi nilai-nilainya agar website bisnis Anda hijau dan naik peringkat."),
 (PAR, "Banyak pemilik bisnis di Surabaya, Sidoarjo, dan sekitarnya mengira website lambat hanya soal tampilan. Padahal kenyataannya jauh lebih dalam. Website yang lambat membuat pengunjung kabur, menurunkan konversi, dan memberi sinyal negatif ke algoritma Google. Dengan memahami Core Web Vitals, Anda bisa mengubah website dari sekadar etalase menjadi mesin pemasaran yang benar-benar bekerja."),
 (SUB, "Apa Itu Core Web Vitals?"),
 (PAR, "Core Web Vitals adalah serangkaian metrik yang diukur Google untuk menilai kesehatan dan kenyamanan sebuah halaman website. Metrik ini menjadi bagian dari sinyal ranking sejak pertama kali diperkenalkan, dan terus diperbarui agar semakin relevan dengan perilaku pengguna di dunia nyata. Sederhananya, Core Web Vitals menjawab pertanyaan: seberapa cepat dan nyaman halaman Anda saat dibuka oleh pengguna sungguhan?"),
 (PAR, "Google tidak hanya melihat kecepatan server. Mereka mengukur pengalaman nyata saat halaman dimuat di perangkat pengguna. Karena itu, metrik ini dinamai 'vitals' — vital alias sangat penting — karena berdampak langsung pada kepuasan pengunjung. Website yang memenuhi standar ini lebih disukai Google karena dinilai memberikan pengalaman yang baik."),
 (SUB, "Tiga Metrik Utama Core Web Vitals 2026"),
 (PAR, "Hingga 2026, Core Web Vitals berfokus pada tiga metrik utama yang terus menjadi standar penilaian Google. Memahami ketiganya adalah langkah pertama menuju optimasi yang benar."),
 (LIS, [
   "<strong>Largest Contentful Paint (LCP)</strong> — mengukur waktu yang dibutuhkan elemen konten terbesar (seperti gambar hero atau teks besar) untuk tampil. Target ideal di bawah 2,5 detik.",
   "<strong>Interaction to Next Paint (INP)</strong> — mengukur responsivitas halaman terhadap interaksi pengguna, seperti klik atau ketukan. Ini pengganti FID dan lebih akurat. Target di bawah 200 milidetik.",
   "<strong>Cumulative Layout Shift (CLS)</strong> — mengukur seberapa banyak elemen halaman bergeser secara tiba-tiba saat dimuat. Target skor di bawah 0,1.",
 ]),
 (PAR, "Ketiga metrik ini tidak berdiri sendiri. Google menilai halaman 'good' hanya jika semuanya hijau. Jika salah satu merah atau kuning di sebagian besar kunjungan, peluang website menempati peringkat terbaik akan berkurang."),
 (SUB, "Mengapa Core Web Vitals Penting untuk Bisnis?"),
 (PAR, "Dampak Core Web Vitals jauh melampaui sekadar angka di laporan teknis. Bagi sebuah bisnis, kecepatan berkorelasi langsung dengan hasil. Studi menunjukkan setiap detik keterlambatan loading dapat menurunkan konversi secara signifikan. Pengunjung kini bersabar kurang dari tiga detik sebelum pindah ke tempat lain."),
 (PAR, "Selain itu, Google terus memperkuat sinyal pengalaman halaman sebagai bagian dari evaluasi ranking. Website yang cepat dan stabil cenderung lebih disukai, terutama untuk kata kunci dengan persaingan ketat. Untuk UMKM yang bergantung pada pelanggan lokal di sekitarnya, kecepatan adalah cara efektif mengungguli kompetitor yang mengabaikan aspek teknis ini."),
 (SUB, "Cara Mengukur Core Web Vitals"),
 (PAR, "Anda tidak perlu menebak-nebak. Google menyediakan alat gratis yang mudah digunakan untuk mengukur kinerja website Anda."),
 (LIS, [
   "<strong>PageSpeed Insights</strong> — cukup masukkan URL, dan Anda langsung mendapat skor LCP, INP, CLS beserta rekomendasi perbaikannya.",
   "<strong>Google Search Console</strong> — terdapat laporan Core Web Vitals yang memakai data pengguna nyata dari seluruh pengunjung Anda.",
   "<strong>Chrome DevTools</strong> — untuk analisis mendalam langsung di browser, cocok bagi pengembang website.",
 ]),
 (PAR, "Gunakan PageSpeed Insights untuk cek cepat, lalu kombinasikan dengan laporan Search Console agar Anda melihat performa sebenarnya berdasarkan data pengunjung, bukan hanya data simulasi lab."),
 (SUB, "Langkah Praktis Membuat LCP di Bawah 2,5 Detik"),
 (PAR, "LCP yang lambat sering kali berasal dari gambar besar atau server yang lambat merespons. Berikut langkah yang bisa langsung diterapkan:"),
 (LIS, [
   "Optimasi dan kompresi gambar ke format modern seperti WebP.",
   "Terapkan lazy loading agar gambar di bawah layar tidak langsung dimuat.",
   "Gunakan preconnect dan preload untuk sumber daya penting.",
   "Percepat waktu respons server dengan hosting andal atau CDN.",
   "Hindari blockir rendering oleh JavaScript dan CSS yang tidak penting.",
 ]),
 (SUB, "Mengoptimalkan INP agar Responsif"),
 (PAR, "INP yang buruk bikin website terasa 'lemot' saat diklik atau di-scroll. Langkah utamanya adalah mengurangi beban kerja pada thread utama browser:"),
 (LIS, [
   "Kurangi JavaScript pihak ketiga yang berukuran besar.",
   "Percepat waktu interaksi dengan memecah tugas (task) menjadi bagian lebih kecil.",
   "Hindari layout thrashing — jangan baca lalu tulis DOM secara berulang tanpa henti.",
   "Gunakan teknik debounce pada event yang sering dipicu pengguna.",
 ]),
 (SUB, "Menghilangkan Pergeseran Layout (CLS)"),
 (PAR, "Pernah membuka halaman lalu elemen tiba-tiba melompat saat Anda hendak mengklik? Itulah CLS yang buruk. Untuk memperbaikinya, pastikan setiap elemen diberi ruang yang jelas:"),
 (LIS, [
   "Tentukan ukuran (width & height) untuk gambar dan video agar tidak 'loncat' saat dimuat.",
   "Hindari menyisipkan konten di atas konten lain setelah halaman tampil.",
   "Gunakan space yang sudah disiapkan untuk iklan atau banner agar tidak menekan konten.",
   "Simpan preferensi pengguna (seperti tema) agar tidak memicu pergeseran.",
 ]),
 (SUB, "Kesalahan Umum yang Membuat Core Web Vitals Merah"),
 (PAR, "Banyak website gagal hijau bukan karena kurang usaha, tapi karena kesalahan yang sama terulang. Beberapa yang paling sering kami temui:"),
 (LIS, [
   "Memakai gambar asli berukuran sangat besar tanpa kompresi.",
   "Memuat plugin atau script pihak ketiga berlebihan.",
   "Mengabaikan laporan Search Console hingga masalah menumpuk.",
   "Mengandalkan hosting murah yang lambat untuk traffic besar.",
 ]),
 (SUB, "Tips Khusus untuk Bisnis Lokal"),
 (PAR, "Untuk bisnis lokal seperti klinik, bengkel, restoran, atau toko di Surabaya dan sekitarnya, setiap detik kecepatan menentukan apakah calon pelanggan menelepon atau membuka kompetitor. Pastikan halaman layanan dan kontak paling cepat dimuat, karena dari sanalah keputusan berkunjung dibuat."),
 (PAR, "Optimasi Core Web Vitals bukan pekerjaan sekali jadi. Algoritma Google terus berkembang, dan perilaku pengguna berubah. Karena itu, audit rutin dan pemantauan berkala adalah kunci agar website Anda tetap konsisten hijau dan unggul di hasil pencarian."),
]

# CTA diterapkan di akhir
def build_html(konten):
    parts = []
    for item in konten:
        tipe = item[0]
        if tipe == "paragraf":
            parts.append(f'<p>{item[1]}</p>')
        elif tipe == "subjudul":
            parts.append(f'<h2 class="wp-block-heading">{item[1]}</h2>')
        elif tipe == "list_poin":
            items = "".join(f'<li>{p}</li>' for p in item[1])
            parts.append(f'<ul>{items}</ul>')
    cta = f'''
<!-- wp:separator --><hr class="wp-block-separator has-alpha-channel-opacity"/><!-- /wp:separator -->
<!-- wp:heading {{"textAlign":"center"}} --><h2 class="wp-block-heading has-text-align-center">{CTA_TITLE}</h2><!-- /wp:heading -->
<!-- wp:paragraph {{"align":"center"}} --><p class="has-text-align-center">{CTA_DESC}</p><!-- /wp:paragraph -->
<!-- wp:buttons {{"layout":{{"type":"flex","justifyContent":"center"}}}} -->
<div class="wp-block-buttons">
<!-- wp:button {{"backgroundColor":"#1E40AF","textColor":"white","className":"is-style-fill"}} -->
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-white-color has-text-color has-background has-link-decoration wp-element-button" href="{WA_LINK}" style="background-color:#1E40AF;" target="_blank" rel="noreferrer noopener"><strong>💬 {CTA_TEXT}</strong></a></div>
<!-- /wp:button -->
</div>
<!-- /wp:buttons -->
<!-- wp:paragraph {{"align":"center"}} --><p class="has-text-align-center">Atau kunjungi <strong><a href="https://studiosoft.id">studiosoft.id</a></strong> untuk info lebih lanjut</p><!-- /wp:paragraph -->
'''
    parts.append(cta)
    return "\n".join(parts)

# Cek dulu ID kategori Digital Marketing yang valid (fallback otomatis)
def get_cat_id(name):
    try:
        existing = json.loads(urllib.request.urlopen(
            f"{DOMAIN}/wp-json/wp/v2/categories?per_page=100&_fields=id,name",
            headers={"Authorization": f"Basic {AUTH}","User-Agent":"Mozilla/5.0"}).read())
        for c in existing:
            if c["name"].lower() == name.lower():
                return c["id"]
    except Exception:
        pass
    return None

def main():
    print("=== Publish: Core Web Vitals ===")
    cat_seo = get_cat_id("SEO") or CAT_SEO
    cat_dm = get_cat_id("Digital Marketing") or None
    cat_ids = [cat_seo] + ([cat_dm] if cat_dm else [])
    print(f"   Kategori: {cat_ids}")

    # tags
    tags = [t for t in [
        ensure_tag("Core Web Vitals"),
        ensure_tag("Kecepatan Website"),
        ensure_tag("SEO Teknis"),
        ensure_tag("PageSpeed Insights"),
    ] if t]
    print(f"   Tags: {tags}")

    img_id, img_url = upload_image(FEATURED_URL, "core-web-vitals-2026.jpg")

    content = build_html(KONTEN)
    wc = len(re.sub(r'<[^>]+>','',content).split())
    print(f"   ~{wc} kata (isi)")

    # Jadwal tayang: 2026-08-10 09:00 WIB = 02:00 UTC
    # WP menerima date (lokal) & date_gmt. Set tanggal lokal WIB = UTC+7.
    local_now = datetime.now(timezone.utc) + timedelta(hours=7)
    sched_local = datetime(2026, 8, 10, 9, 0, 0)
    sched_gmt = sched_local - timedelta(hours=7)  # 02:00 UTC
    date_local_s = sched_local.strftime("%Y-%m-%dT%H:%M:%S")
    date_gmt_s = sched_gmt.strftime("%Y-%m-%dT%H:%M:%S")
    print(f"   Jadwal: {date_local_s} WIB (GMT {date_gmt_s})")

    post_data = {
        "title": JUDUL, "slug": SLUG, "content": content,
        "status": "future", "date": date_local_s, "date_gmt": date_gmt_s,
        "categories": cat_ids, "tags": tags,
        "meta": {
            "_yoast_wpseo_title": f"{JUDUL} | StudioSoft Surabaya",
            "_yoast_wpseo_metadesc": META_DESC,
            "_yoast_wpseo_focuskw": FOCUS_KW,
            "_yoast_wpseo_meta-robots-noindex": "0",
            "_yoast_wpseo_meta-robots-nofollow": "0",
            "_yoast_wpseo_opengraph-title": JUDUL,
            "_yoast_wpseo_opengraph-description": META_DESC,
        },
    }
    if img_id: post_data["featured_media"] = img_id

    res = wp_request("posts", method="POST", data=post_data)
    if res and "id" in res:
        print("\n   ✅ BERHASIL")
        print(f"   ID: {res['id']}")
        print(f"   Status: {res.get('status')}")
        print(f"   Link: {res.get('link')}")
        print(f"   Date: {res.get('date')}")
        json.dump(res, open("/tmp/ss_corewebvitals_result.json","w"), ensure_ascii=False, indent=1)
    else:
        print("\n   ❌ GAGAL")

if __name__ == "__main__":
    main()
