#!/usr/bin/env python3
"""Gelombang 3 klaster serbuk Yasma: pilar #3420 (cara memulai bisnis minuman serbuk),
gabung 4 artikel 'memulai' + buang 1 duplikat judul (#4551). GUARD: hanya post."""
import base64, html, importlib.util, json, os, re, sys, time, urllib.request, urllib.error

S = "https://yasmanatura.co.id"
AUTH = base64.b64encode(b"bambangbot:LFp4 LXBh kMYG 84qC 2DDc 5bLc").decode()
PILAR = 3420
BUANG = [3464, 3585, 2831, 3351, 4551]
TAUT = [3693, 3695, 3253, 3237, 3031, 4310]
PILAR_GEL2 = "https://yasmanatura.co.id/maklon-minuman-serbuk-indonesia-yasma-natura-partner-maklon-nasional-untuk-produk-minuman-kesehatan/"

JUDUL = "Cara Memulai Bisnis Minuman Serbuk: Panduan Lengkap untuk Pemula"
FK = "cara memulai bisnis minuman serbuk"
META = ("Cara memulai bisnis minuman serbuk dari nol: menentukan segmen, menyusun formula, mengurus legalitas, "
        "menghitung MOQ dan harga jual sampai penjualan pertama.")

WA = """
<style>
.ss-cta-wa{display:inline-flex;align-items:center;gap:10px;background-color:#6878d6;color:#ffffff !important;
font-family:'Open Sans',sans-serif;font-weight:600;font-size:17px;padding:15px 30px;border-radius:8px;
text-decoration:none !important;line-height:1.2;box-shadow:0 2px 8px rgba(104,120,214,.35)}}
.ss-cta-wa:hover{background-color:#4d61d6;color:#ffffff !important}
</style>
<p style="text-align:center;margin:34px 0 6px">
<a class="ss-cta-wa" href="https://wa.me/6281939119209?text=Halo%20Yasma%20Natura%2C%20saya%20ingin%20memulai%20brand%20minuman%20serbuk" target="_blank" rel="noopener" role="button">WhatsApp: Konsultasi Gratis</a>
</p>
<p style="text-align:center;font-size:14px;color:#5b5b6b;margin:0 0 26px">Ceritakan rencana produk Anda, tim kami bantu menaksir biaya dan waktu produksinya.</p>
"""

ISI = """
<p>Memulai bisnis minuman serbuk jauh lebih terjangkau daripada yang dibayangkan banyak orang, karena Anda tidak perlu membangun pabrik. Yang dibutuhkan adalah keputusan yang jelas di awal: produk untuk siapa, manfaat apa, kemasan seperti apa, dan berapa jumlah produksi pertama. Panduan ini menyusun langkahnya secara berurutan, dari memilih segmen sampai penjualan pertama.</p>

<h2>Kenapa kategori serbuk cocok untuk pemula</h2>
<p>Tiga alasan. Pertama, biaya produksi pertamanya lebih kecil dibanding minuman siap minum, karena tidak memerlukan pengisian cair dan rantai dingin. Kedua, masa simpannya panjang sehingga risiko stok rusak rendah. Ketiga, formulasinya bisa dikembangkan menjadi beberapa varian tanpa mengganti lini produksi. Tiga hal ini yang membuat kategori serbuk sering jadi pilihan pertama pemilik brand baru.</p>

<h2>Langkah 1 — Tentukan segmen dan satu manfaat utama</h2>
<p>Jangan membuat produk untuk semua orang. Pilih satu segmen (misalnya pekerja kantoran, ibu menyusui, atau penggemar olahraga) dan satu manfaat utama yang paling dibutuhkan segmen itu. Produk yang mencoba menyampaikan tiga manfaat sekaligus biasanya tidak diingat untuk satu pun. Dari keputusan ini, arah rasa, kemasan, dan cara promosinya jadi lebih mudah ditentukan.</p>

<h2>Langkah 2 — Susun formula bersama penyedia maklon</h2>
<p>Kalau Anda sudah punya resep, bawa ke penyedia maklon untuk ditinjau; kalau belum, mereka membantu menyusunnya. Tahap penting di sini adalah uji sampel: produk dibuat dalam jumlah kecil, diuji rasa oleh Anda dan calon pembeli, lalu diperbaiki sebelum masuk produksi penuh. Melewati tahap ini adalah penyebab paling umum produk gagal di pasaran.</p>

<h2>Langkah 3 — Tentukan kemasan dan identitas brand</h2>
<p>Kemasan harus menjawab kebiasaan segmen Anda: sachet untuk konsumsi harian, kemasan lebih besar untuk pemakaian keluarga, atau box untuk positioning premium. Selain desain, perhatikan informasi wajib yang harus tercetak. Menentukan kemasan lebih awal juga membantu karena kemasan yang banyak tersedia di pasaran menekan biaya produksi.</p>

<h2>Langkah 4 — Urus legalitas sejak awal</h2>
<p>Untuk produk kesehatan, izin edar dan sertifikasi Halal adalah syarat agar produk bisa dijual resmi. Mengurusnya belakangan justru menambah biaya karena bisa memaksa perubahan kemasan atau formula. Karena itu, proses legalitas sebaiknya dimulai bersamaan dengan penyusunan formula, bukan setelah produk jadi.</p>

<h2>Langkah 5 — Tentukan MOQ dan jumlah produksi pertama</h2>
<p>Jumlah produksi minimum atau MOQ berbeda per jenis produk dan ukuran kemasan. Untuk produksi pertama, pilih jumlah yang cukup untuk menguji pasar tanpa mengikat modal terlalu besar. Setelah respon pembeli jelas, baru tambah jumlahnya. Kesalahan umum di tahap ini adalah memesan banyak karena tergiur harga per unit yang lebih murah, padahal permintaannya belum terbukti.</p>

<h2>Langkah 6 — Hitung harga jual</h2>
<p>Harga jual dibentuk dari biaya produksi per unit, biaya kemasan, biaya distribusi, dan margin. Hitung totalnya, lalu bandingkan dengan harga produk sejenis di segmen Anda. Kalau terasa terlalu tinggi, perbaiki dari sisi jumlah produksi atau pilihan kemasan — bukan dengan menurunkan mutu bahan.</p>

<h2>Langkah 7 — Jalur penjualan pertama</h2>
<p>Dua jalur yang paling cepat untuk brand baru: penjualan langsung ke komunitas segmen, dan kerja sama dengan reseller kecil. Penjualan langsung memberi umpan balik soal rasa dan kemasan; reseller menambah jangkauan tanpa biaya iklan besar. Siapkan konten edukasi tentang manfaat bahan sejak awal, karena pembeli produk kesehatan mencari informasi sebelum membeli.</p>

<h2>Kesalahan yang paling sering terjadi</h2>
<p>Menunda uji sampel karena ingin cepat. Membuat produk untuk semua orang. Memesan jumlah besar sejak awal. Mengurus legalitas paling akhir. Dan menentukan harga jual hanya dari biaya produksi, tanpa menghitung distribusi dan margin.</p>

<h2>Berapa lama sampai produk bisa dijual</h2>
<p>Hitungan waktu dimulai sejak segmen dan formula disepakati. Tahap yang biasanya paling lama adalah legalitas, karena bergantung pada kelengkapan dokumen dan jadwal pemeriksaan. Menyiapkan identitas brand, desain kemasan, dan keterangan bahan sejak awal akan memangkas waktu tunggu secara nyata.</p>

<h2>Pertanyaan yang sering muncul</h2>
<h3>Berapa modal awal untuk memulai bisnis minuman serbuk?</h3><p>Bergantung pada jumlah produksi minimum dan jenis kemasan yang dipilih. Banyak brand memulai dari jumlah kecil untuk menguji pasar, lalu menambah setelah responnya jelas.</p>
<h3>Apakah harus punya resep sendiri?</h3><p>Tidak wajib. Kalau belum punya, penyedia maklon membantu menyusun formula awal. Kalau sudah punya, resep itu ditinjau agar stabil saat diproduksi dalam jumlah besar.</p>
<h3>Berapa lama proses sampai produk bisa dijual?</h3><p>Tergantung kecepatan persetujuan formula dan proses legalitas. Uji sampel dan izin edar adalah dua tahap yang paling menentukan lama waktunya.</p>
<h3>Apakah bisa mulai dari usaha rumahan?</h3><p>Bisa. Karena produksinya ditangani penyedia maklon, Anda tidak perlu ruang produksi sendiri — cukup tempat penyimpanan yang kering dan pengelolaan pesanan yang rapi.</p>
<h3>Kesalahan apa yang paling merugikan pemula?</h3><p>Produksi dalam jumlah besar sebelum produk terbukti disukai pasar. Mulailah kecil, uji rasa dan respon pembeli, baru tingkatkan jumlah produksinya.</p>
"""



# tambahan isi pilar (dari ys_serbuk_tambahan3.py)
_spec = importlib.util.spec_from_file_location("_ysb3", os.path.join(os.path.dirname(os.path.abspath(__file__)), "ys_serbuk_tambahan3.py"))
_modb3 = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(_modb3)
ISI = ISI.replace('<h2>Pertanyaan yang sering muncul</h2>', _modb3.TAMBAHAN + "\n<h2>Pertanyaan yang sering muncul</h2>")

def api(path, data=None, method=None):
    method = method or ("POST" if data is not None else "GET")
    h = {"Authorization": f"Basic {AUTH}", "User-Agent": "Mozilla/5.0"}
    body = None
    if data is not None:
        body = json.dumps(data).encode(); h["Content-Type"] = "application/json"
    err = None
    r = urllib.request.Request(S + path, data=body, headers=h, method=method)
    for _ in range(3):
        try:
            with urllib.request.urlopen(r, timeout=220) as x:
                return x.status, json.loads(x.read())
        except urllib.error.HTTPError as e:
            if e.code in (404, 410, 500, 502, 503, 504):
                time.sleep(4); continue
            return e.code, e.read().decode()[:200]
        except Exception as e:
            err = e; time.sleep(4)
    return 0, str(err)[:150] if err else "gagal"


print("=== GUARD tipe post ===")
for pid in [PILAR] + BUANG + TAUT:
    st, d = api(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=type,status")
    t = d.get("type") if isinstance(d, dict) else f"gagal({st})"
    if t != "post":
        print(f"  #{pid} tipe={t} ⛔ bukan post — dibatalkan"); sys.exit(1)
print(f"  semua {len([PILAR]+BUANG+TAUT)} sasaran = post ✅")

kata = len(html.unescape(re.sub(r"<[^>]+>", " ", ISI)).split())
print(f"\npilar #{PILAR}: {JUDUL}\n  {kata} kata | meta {len(META)} char | fk di awal: {META.lower().startswith(FK.lower())}")

if "--apply" not in sys.argv:
    print(f"\n  5 dipensiunkan: {BUANG}  (termasuk duplikat judul #4551)\n  6 ditautkan   : {TAUT}")
    sys.exit(0)

pasangan = [(re.sub(r"<[^>]+>", " ", m.group(1)).strip(), re.sub(r"\s+", " ", re.sub(r"<[^>]+>", " ", m.group(2))).strip())
            for m in re.finditer(r"<h3[^>]*>(.*?)</h3>\s*<p>(.*?)</p>", ISI, re.S)]
schema = ('<script type="application/ld+json">' + json.dumps({
    "@context": "https://schema.org", "@type": "FAQPage",
    "mainEntity": [{"@type": "Question", "name": q, "acceptedAnswer": {"@type": "Answer", "text": a}} for q, a in pasangan]},
    ensure_ascii=False) + "</script>")
konten = ISI + f'\n<h2>Baca juga</h2>\n<p>Untuk sisi produksinya, baca <a href="{PILAR_GEL2}">maklon minuman serbuk</a> dan <a href="https://yasmanatura.co.id/jasa-maklon-minuman-herbal/">jasa maklon herbal Sidoarjo</a>.</p>\n' + schema + "\n" + WA

st, _ = api(f"/wp-json/wp/v2/posts/{PILAR}", {
    "title": JUDUL, "content": konten,
    "meta": {"_yoast_wpseo_focuskw": FK, "_yoast_wpseo_title": JUDUL, "_yoast_wpseo_metadesc": META}})
_, chk = api(f"/wp-json/wp/v2/posts/{PILAR}?context=edit&_fields=content,meta")
raw = chk["content"]["raw"]
print(f"\nPILAR #{PILAR} POST {st} | {len(html.unescape(re.sub(r'<[^>]+>', ' ', raw)).split())} kata | FAQ {raw.count('<h3>')} Q | meta {len(chk['meta'].get('_yoast_wpseo_metadesc',''))}")

print("\nmenautkan ke pilar:")
for pid in TAUT:
    st2, p = api(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=content,type")
    if p.get("type") != "post":
        print(f"  #{pid} bukan post — dilewati"); continue
    r2 = p["content"]["raw"]
    if "10-cara-buat-brand-minuman-serbuk" in r2:
        print(f"  #{pid} sudah menautkan"); continue
    blok = ('\n<h2>Baca juga</h2>\n<p>Langkah lengkapnya ada di '
            '<a href="https://yasmanatura.co.id/10-cara-buat-brand-minuman-serbuk-sendiri-lewat-jasa-maklon/">cara memulai bisnis minuman serbuk</a> — '
            'dari segmen sampai penjualan pertama.</p>\n')
    m = re.search(r"\n<h2[^>]*>\s*(Pertanyaan|FAQ|Kesimpulan|Baca juga)", r2, re.I)
    baru = (r2[:m.start()] + blok + r2[m.start():]) if m else (r2.rstrip() + "\n" + blok)
    st3, _ = api(f"/wp-json/wp/v2/posts/{pid}", {"content": baru})
    print(f"  #{pid} POST {st3}")

print("\nmemindahkan ke trash:")
for pid in BUANG:
    st4, _ = api(f"/wp-json/wp/v2/posts/{pid}", method="DELETE")
    _, c2 = api(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=status")
    print(f"  #{pid} DELETE {st4} | status: {c2.get('status') if isinstance(c2, dict) else c2}")
