#!/usr/bin/env python3
"""Usulan konten viral 3 platform (Threads + Facebook + LinkedIn), 30 Sep 2026.

Threads  : 12 caption dari usulan_konten_threads_20260930.py (sudah divalidasi)
Facebook : 6 caption (StudioSoft, TS Law, TSC)  -> replies=[] WAJIB
LinkedIn : 6 caption (StudioSoft, Uky personal, TSC) -> replies=[] WAJIB, text-only
Semua caption: link artikel (sudah tervalidasi ada + fresh), hashtag huruf kecil,
ada ajakan diskusi, tanpa mention, tanpa karakter CJK.
"""
import json, re, os

CJK = re.compile(r"[\u3000-\u303f\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uac00-\ud7af]")
MENTION = re.compile(r"@\w+")
URL = re.compile(r"https?://\S+")
CTA = re.compile(r"komentar|diskusi|pendapat|menurut (anda|kamu|kalian)|share|bagikan|cara kerja orang lain|ingin tahu", re.I)

FB = [
    dict(akun="StudioSoft (Facebook)", sudut="praktis untuk pemilik bisnis",
         pemicu="Audit internal kami sendiri: 290 artikel dicek",
         link="https://studiosoft.id/audit-290-artikel-halaman-yatim/",
         body=(
            "Kami baru selesai mengaudit 290 artikel di puluhan website bisnis. Hasilnya bikin kami ikut kaget: "
            "86% halaman tidak punya satu pun tautan masuk dari halaman lain di website itu sendiri.\n\n"
            "Artinya apa? Google menemukan halaman itu jauh lebih lambat, dan pembaca tidak punya jalan lanjut "
            "setelah selesai membaca. Halaman yang isinya bagus pun jadi sepi.\n\n"
            "Cara cek cepat untuk website Anda: buka Google Search Console, lihat daftar halaman yang terindeks, "
            "lalu bandingkan dengan jumlah artikel yang Anda tulis. Selisihnya biasanya di situ.\n\n"
            "Website Anda sudah pernah diaudit seperti ini? Cerita di komentar."),
         tags="#seo #websitebisnis #umkm"),
    dict(akun="StudioSoft (Facebook)", sudut="praktis untuk pemilik bisnis",
         pemicu="Pertanyaan yang paling sering masuk soal biaya website",
         link="https://studiosoft.id/berapa-biaya-jasa-pembuatan-website/",
         body=(
            "Pertanyaan yang paling sering masuk ke kami: bikin website itu berapa?\n\n"
            "Jawabannya tidak bisa satu angka, karena yang menentukan bukan jumlah halaman, tapi tiga hal: "
            "siapa yang menyiapkan isinya, apakah perlu integrasi seperti pembayaran atau booking, "
            "dan seberapa serius rencana promosi setelah websitenya jadi.\n\n"
            "Yang sering terjadi, website murah dibiarkan tanpa diurus, lalu diulang dua tahun kemudian. "
            "Totalnya jadi lebih mahal daripada membuat sekali dengan benar.\n\n"
            "Menurut Anda, bagian mana yang paling sering bikin anggaran membengkak? Tulis di komentar."),
         tags="#website #umkm #digitalmarketing"),
    dict(akun="Tito Supriyanto Law Firm (Facebook)", sudut="bahasa awam untuk masyarakat luas",
         pemicu="Perkara perceraian publik dan pertanyaan soal hak asuh anak",
         link="https://www.tslaw.id/7-hal-penting-tentang-hak-asuh-anak-setelah-perceraian-yang-wajib-orang-tua-tahu/",
         body=(
            "Perkara orang tuanya berhenti, tapi perkara anak baru mulai saat itu.\n\n"
            "Dalam perceraian, hak asuh umumnya jatuh ke ibu, kecuali ada alasan kuat untuk sebaliknya. "
            "Yang perlu dipahami orang tua, hak asuh bukan soal siapa yang menang, tapi siapa yang benar-benar "
            "menjalankan kewajiban merawat. Pengadilan menilai kesiapan itu dari hal praktis: tempat tinggal, "
            "penghasilan, dan kedekatan dengan anak.\n\n"
            "Satu hal yang sering terlewat: ayah tetap wajib menanggung nafkah anak, meski hak asuhnya ke ibu.\n\n"
            "Menurut Anda, apa bagian paling berat dari pengaturan hak asuh di Indonesia? Tulis di komentar."),
         tags="#hakasuhanak #perceraian #hukumkeluarga"),
    dict(akun="Tito Supriyanto Law Firm (Facebook)", sudut="bahasa awam untuk masyarakat luas",
         pemicu="Usaha kuliner tumbuh, legalitas sering menyusul belakangan",
         link="https://www.tslaw.id/legalitas-usaha-makanan-minuman-pirt-bpom-halal-nib/",
         body=(
            "Banyak usaha makanan tumbuh dulu, legalitasnya menyusul. Cara itu bisa jalan, sampai datang satu masalah.\n\n"
            "Urutan yang paling aman: NIB dulu, lanjut sertifikat halal, lalu izin PIRT atau edar BPOM, "
            "tergantung skala dan jenis produknya. Ini bukan sekadar urusan administrasi. Saat ada pemeriksaan "
            "atau tawaran kerja sama dengan ritel, yang diminta pertama justru dokumennya.\n\n"
            "Kesalahan yang paling mahal: kemasan dicetak ribuan buah lebih dulu, baru ketahuan labelnya "
            "belum memenuhi ketentuan.\n\n"
            "Anda pebisnis kuliner? Sudah sampai tahap mana legalitasnya? Tulis di komentar."),
         tags="#umkm #legalitasusaha #hukum",
         ),
    dict(akun="The Skin Code Clinic (Facebook)", sudut="edukasi pasien, ramah",
         pemicu="Marak keluhan tindakan kecantikan oleh bukan tenaga medis",
         link="https://www.theskincodeclinic.com/klinik-kulit-vs-salon-kecantikan-mojokerto/",
         body=(
            "Bedanya klinik kulit dan salon kecantikan bukan di harga, tapi di siapa yang menangani.\n\n"
            "Tindakan seperti peeling dengan bahan medis, injeksi, dan laser hanya boleh dikerjakan dokter "
            "beserta tenaga medis terlatih. Di salon, perawatan yang aman sebatas kosmetik dan relaksasi, "
            "tanpa tindakan yang menembus kulit.\n\n"
            "Kenapa ini penting? Komplikasi dari tindakan yang bukan porsinya sering baru muncul beberapa minggu "
            "kemudian, dan biaya penanganannya jauh lebih besar daripada perawatan awalnya.\n\n"
            "Sebelum memilih tempat perawatan, Anda biasanya mengecek apa dulu? Share di komentar."),
         tags="#kulitsehat #klinikkecantikan #dokterkulitkrian"),
    dict(akun="The Skin Code Clinic (Facebook)", sudut="edukasi pasien, ramah",
         pemicu="Pasien baru sering bertanya bagaimana alur perawatan di dokter kulit",
         link="https://www.theskincodeclinic.com/proses-perawatan-dokter-kulit-krian/",
         body=(
            "Pasien baru sering bertanya, perawatan di dokter kulit itu alurnya seperti apa?\n\n"
            "Kami selalu mulai dari konsultasi dan pemeriksaan kulit. Dari situ baru ditentukan tindakannya, "
            "apakah cukup perawatan topikal di rumah atau perlu prosedur di klinik. Setelah tindakan ada kontrol "
            "untuk menilai hasil, dan rencananya disesuaikan lagi.\n\n"
            "Yang perlu diketahui sejak awal: perawatan kulit jarang selesai dalam sekali datang. "
            "Hasil yang bagus datangnya bertahap.\n\n"
            "Anda tipe yang rajin kontrol, atau baru datang kalau ada keluhan? Cerita di komentar."),
         tags="#kulitsehat #perawatankulit #dokterkulitkrian"),
]

LI = [
    dict(akun="StudioSoft (LinkedIn)", sudut="keputusan dan proses kerja (B2B)",
         pemicu="Adopsi AI di bisnis: mana yang layak diserahkan lebih dulu",
         link="https://studiosoft.id/otomasi-bisnis-dengan-ai/",
         body=(
            "Di banyak bisnis, AI masuk bukan lewat proyek besar, tapi lewat satu dua pekerjaan yang jelas batasnya.\n\n"
            "Dari pengalaman kami mendampingi klien, pekerjaan yang paling cepat memberi hasil: merangkum "
            "percakapan pelanggan, menyusun draf konten, dan menyiapkan laporan rutin. Yang kami tahan dulu: "
            "apa pun yang menyentuh uang dan data pribadi.\n\n"
            "Alasannya bukan soal kemampuan teknologinya. Pekerjaan berulang mudah diperiksa hasilnya, "
            "sedangkan keputusan berisiko tinggi butuh jejak audit. Urutan inilah yang membuat adopsi AI "
            "tidak berhenti di tahap uji coba.\n\n"
            "Di tim Anda, proses mana yang sudah diserahkan ke AI, dan mana yang masih Anda tahan? "
            "Saya ingin tahu pendapat rekan-rekan di sini."),
         tags="#ai #otomasi #digitalmarketing"),
    dict(akun="StudioSoft (LinkedIn)", sudut="keputusan dan proses kerja (B2B)",
         pemicu="Cara orang mencari jasa mulai bergeser ke asisten AI",
         link="https://studiosoft.id/apa-itu-geo-generative-engine-optimization/",
         body=(
            "SEO masih penting, tapi pertanyaan yang dijawabnya sudah bergeser.\n\n"
            "Kalau calon klien bertanya ke AI, jawabannya disusun dari sumber yang dikutip. Yang menentukan "
            "bukan siapa paling rajin menulis, tapi siapa yang datanya bisa diperiksa: nama layanan jelas, "
            "wilayah kerja jelas, rentang harga terbuka, dan halaman yang benar-benar menjawab satu pertanyaan.\n\n"
            "Kami menyebutnya GEO. Prinsipnya sederhana juga: kalau mesin tidak bisa memastikan siapa Anda, "
            "ia akan mengutip sumber lain.\n\n"
            "Menurut Anda, bisnis jasa di Indonesia sudah siap dengan cara pencarian seperti ini?"),
         tags="#seo #geo #strategidigital"),
    dict(akun="Uky Yanuhandoko (LinkedIn)", sudut="pengalaman pemilik agensi",
         pemicu="Brief dari AI yang isinya data tanpa sumber",
         link="https://studiosoft.id/bikin-konten-pakai-ai-boleh-asal-tahu-batasnya/",
         body=(
            "Beberapa kali kami menerima brief yang jelas hasil AI, lengkap sampai angka statistik yang "
            "tidak ada sumbernya. Kejadian seperti itu yang bikin saya hati-hati.\n\n"
            "Pendapat saya begini: AI boleh untuk menyusun kerangka, merapikan kalimat, dan mencari pola. "
            "Yang tidak boleh diserahkan: fakta, angka, dan janji ke pelanggan. Semua itu tetap diverifikasi "
            "manusia, karena yang menanggung risikonya nama bisnis Anda, bukan alatnya.\n\n"
            "Di tim Anda, sudah ada aturan tertulis soal batas pemakaian AI? Saya ingin tahu cara kerja "
            "orang lain di sini."),
         tags="#ai #digitalmarketing #manajemen"),
    dict(akun="Uky Yanuhandoko (LinkedIn)", sudut="pengalaman pemilik agensi",
         pemicu="Peran tim digital marketing bergeser karena AI",
         link="https://studiosoft.id/ai-dan-pekerjaan-digital-marketer-apa-yang-berubah/",
         body=(
            "Pekerjaan digital marketing berubah bukan karena AI menggantikan orangnya, tapi karena bagian "
            "yang membosankan akhirnya bisa diotomasi.\n\n"
            "Yang justru makin dihargai ada dua: kemampuan membaca data penjualan, dan keberanian bilang ke "
            "klien bahwa permintaannya keliru. Dua hal itu belum bisa diambilkan mesin.\n\n"
            "Yang saya lihat hilang lebih cepat: menyalin laporan ke spreadsheet dan menyusun caption seragam "
            "untuk semua channel.\n\n"
            "Menurut Anda, peran mana di tim marketing yang paling cepat berubah tahun ini?"),
         tags="#digitalmarketing #ai #karier"),
    dict(akun="The Skin Code Clinic (LinkedIn)", sudut="standar medis dan kepercayaan",
         pemicu="Pasien makin teliti menilai klinik, bukan sekadar lihat tampilan",
         link="https://www.theskincodeclinic.com/5-klinik-kecantikan-di-krian-sidoarjo-standar-medis/",
         body=(
            "Di layanan kesehatan, standar bukan formalitas. Standar itu yang membedakan klinik dari usaha "
            "kecantikan biasa.\n\n"
            "Isinya mencakup izin operasional, dokter penanggung jawab, ruang tindakan yang sesuai, dan prosedur "
            "penanganan komplikasi. Bagi pasien, indikator paling mudah dilihat: apakah tindakan dilakukan "
            "setelah pemeriksaan, dan apakah ada rencana kontrol setelahnya.\n\n"
            "Kami menuliskannya terbuka karena banyak pasien baru menyadari hal ini setelah mengalami masalah.\n\n"
            "Menurut Anda, informasi apa yang seharusnya dibuka klinik kepada calon pasiennya?"),
         tags="#klinikkecantikan #standarmedis #layanankesehatan"),
    dict(akun="The Skin Code Clinic (LinkedIn)", sudut="standar medis dan kepercayaan",
         pemicu="Banyak pasien memilih perawatan dari tampilan media sosial",
         link="https://www.theskincodeclinic.com/ciri-ciri-dokter-kecantikan-krian-terpercaya/",
         body=(
            "Banyak pasien memilih tempat perawatan dari tampilan media sosialnya. Saya paham, itu yang paling "
            "terlihat lebih dulu.\n\n"
            "Ada tanda yang lebih bisa dipercaya: dokter yang mau menjelaskan alasan satu tindakan dipilih, "
            "berani bilang kalau harapan pasien tidak realistis, dan tidak menjanjikan hasil dalam sekali datang.\n\n"
            "Untuk kerja sama dengan perusahaan, pertimbangannya bergeser: alur rujukan, jadwal yang mengikuti "
            "jam kerja, dan kerahasiaan data pasien.\n\n"
            "Menurut Anda, kriteria apa yang paling menentukan saat memilih klinik?"),
         tags="#klinikkecantikan #dokterkulit #layanankesehatan"),
]


def caption_of(it):
    return f"{it['body']}\n\n{it['link']}\n{it['tags']}"


def validasi(t, platform):
    tags = re.findall(r"#(\w+)", t)
    bad = [x for x in tags if x != x.lower()]
    err = []
    maks = 800 if platform == "facebook" else 1200
    if len(t) > maks:
        err.append(f"{len(t)} char (> {maks})")
    if not URL.search(t):
        err.append("tanpa link")
    if MENTION.search(t):
        err.append("ada mention")
    if CJK.search(t):
        err.append("ada CJK")
    if not CTA.search(t):
        err.append("tanpa ajakan diskusi")
    if bad:
        err.append(f"hashtag huruf besar: {bad}")
    return err


print("=" * 86)
print("VALIDASI KONTEN FACEBOOK")
print("=" * 86)
gagal = 0
for it in FB:
    t = caption_of(it)
    err = validasi(t, "facebook")
    gagal += bool(err)
    print(f"{'OK   ' if not err else 'GAGAL'} {it['akun'][:34]:34s} {len(t):5d} char  {err or ''}")
print()
print("=" * 86)
print("VALIDASI KONTEN LINKEDIN")
print("=" * 86)
for it in LI:
    t = caption_of(it)
    err = validasi(t, "linkedin")
    gagal += bool(err)
    print(f"{'OK   ' if not err else 'GAGAL'} {it['akun'][:34]:34s} {len(t):5d} char  {err or ''}")
print()
print("SEMUA VALID" if gagal == 0 else f"{gagal} caption perlu dipangkas")

json.dump([{**it, "platform": "facebook", "caption": caption_of(it)} for it in FB] +
          [{**it, "platform": "linkedin", "caption": caption_of(it)} for it in LI],
          open("usulan_caption_fb_li_20260930.json", "w"), ensure_ascii=False, indent=1)
print("JSON: usulan_caption_fb_li_20260930.json")
