#!/usr/bin/env python3
"""TSC #1908: ganti isi artikel dari daftar klaim -> panduan jujur yang tetap menjual.
Menghapus: janji permanen/tanpa risiko, harga & promo, rating & jumlah review, persentase keberhasilan,
garansi uang kembali, klaim sertifikasi (BPOM/Halal MUI/Kemenkes), gelar keliru (SpKK), klaim 24/7.
Mempertahankan: topik & slug (sudah terindeks), FAQ + schema, tautan internal, CTA WhatsApp.
Jalankan --apply untuk menulis."""
import base64, html, json, os, re, sys, time, urllib.request, urllib.error, importlib.util
from xml.sax.saxutils import escape

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
spec = importlib.util.spec_from_file_location("cfg_tsc", f"{WS}/cfg_tsc.py")
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
DOM, USER, PASS = m.CFG["domain"], m.CFG["user"], m.CFG["pass"]
AUTH = base64.b64encode(f"{USER}:{PASS}".encode()).decode()
UA = {"User-Agent": "Mozilla/5.0"}
BACKUP = f"{WS}/tsc_pemulihan/salinan_tipis"
os.makedirs(BACKUP, exist_ok=True)
PID = 1908

JUDUL_BARU = "Klinik Dokter Kulit di Krian: Panduan Memilih yang Tepat"
SEO_BARU = "Klinik Dokter Kulit Krian: Panduan Memilih"
META_BARU = ("Cara memilih klinik dokter kulit di Krian: siapa yang memeriksa, apakah tindakan didahului "
             "diagnosis, dan apa yang perlu ditanyakan sebelum memutuskan.")
FOKUS = "klinik dokter kulit krian terpercaya"

ISI = """<p>Mencari klinik dokter kulit di Krian sebaiknya tidak dimulai dari janji hasil, melainkan dari cara kerjanya. Ada klinik yang memeriksa lebih dulu lalu menyusun rencana perawatan, ada juga yang langsung menawarkan paket tindakan. Perbedaan urutan ini yang menentukan apakah kulit Anda ditangani sesuai kondisinya atau sekadar mengikuti daftar layanan.</p>
<p>Artikel ini merangkum hal-hal yang layak diperiksa saat memilih klinik kulit di Krian dan sekitarnya, sekaligus menjelaskan bagaimana layanan di The Skin Code Clinic Krian dijalankan.</p>

<h2>1. Siapa yang memeriksa Anda</h2>
<p>Pertanyaan pertama bukan soal harga atau alat, melainkan siapa yang memeriksa. Yang perlu dipastikan adalah dokter spesialis kulit dan kelamin dengan gelar Sp.DVE — bidang yang menangani penyakit kulit, rambut, kuku, dan penyakit menular seksual. Di The Skin Code Clinic Krian, layanan dipimpin dr. Avril Novianto, Sp.DVE.</p>
<p>Alasannya sederhana: keluhan kulit yang tampak serupa bisa memiliki penyebab yang berbeda. Ruam yang mirip alergi bisa jadi infeksi jamur, dan jerawat yang tampak biasa bisa memerlukan pemeriksaan lebih dalam. Penanganan yang tepat bergantung pada siapa yang menegakkan diagnosisnya.</p>

<h2>2. Tindakan didahului pemeriksaan, bukan sebaliknya</h2>
<p>Urutan kerja yang sehat adalah anamnesis, pemeriksaan, diagnosis, baru rencana perawatan. Praktik yang melewatkan pemeriksaan biasanya langsung menawarkan tindakan seperti facial, peeling, atau laser. Untuk kulit sehat hal itu mungkin tidak menimbulkan masalah, tetapi pada kulit yang sedang meradang atau terinfeksi, tindakan yang dipilih tanpa diagnosis berisiko memperburuk kondisi.</p>

<h2>3. Keluhan yang ditangani</h2>
<p>Klinik kulit yang menangani ragam keluhan biasanya lebih siap menghadapi kondisi yang tidak sesuai dengan paket umum. Di The Skin Code Clinic Krian, layanan mencakup konsultasi dan penanganan keluhan kulit seperti jerawat dan bekasnya, eksim serta dermatitis, alergi kulit, infeksi jamur, dan pigmentasi; keluhan pada area kelamin; serta tindakan estetika medis yang diberikan sesuai indikasi.</p>

<h2>4. Kejelasan biaya sebelum tindakan</h2>
<p>Biaya layanan kulit berbeda-beda tergantung jenis pemeriksaan, tindakan yang dipilih, dan jumlah kunjungan. Karena itu, minta penjelasan rincian sebelum tindakan dilakukan: apa yang termasuk, apa yang dihitung terpisah, dan berapa perkiraan jumlah kunjungannya. Klinik yang jelas tidak keberatan menjelaskan hal ini lebih dulu.</p>
<p>Yang perlu diwaspadai justru sebaliknya: diskon yang menekan Anda memutuskan saat itu juga, atau paket yang ditawarkan sebelum kulit Anda diperiksa.</p>

<h2>5. Cara hasil perawatan dievaluasi</h2>
<p>Perawatan kulit jarang selesai dalam satu kunjungan, sehingga jadwal kontrol menjadi bagian penting. Pada kunjungan evaluasi, dokter menilai apakah keluhan membaik, memerlukan penyesuaian obat, atau perlu tindakan lanjutan. Sebagai gambaran umum, infeksi jamur biasanya dievaluasi dalam dua sampai empat minggu, sementara jerawat dinilai setelah enam sampai delapan minggu karena mengikuti siklus pergantian kulit.</p>
<p>Perlu dipahami: hasil tindakan tidak sama pada setiap orang dan tidak ada tindakan medis yang bebas risiko sepenuhnya. Klinik yang baik menjelaskan peluang hasil, kemungkinan efek samping seperti kemerahan atau bengkak sementara, dan langkah yang diambil bila hasilnya belum sesuai harapan.</p>

<h2>6. Perawatan setelah tindakan</h2>
<p>Hasil di klinik bertahan lebih lama bila perawatan harian ikut dijaga. Bersihkan kulit dengan pembersih lembut dua kali sehari, gunakan pelembap untuk menjaga lapisan pelindung kulit, dan pakai tabir surya setiap hari, terutama setelah tindakan seperti peeling atau laser. Hindari produk dengan scrub kasar selama masa pemulihan dan selesaikan obat sesuai anjuran meski gejala sudah membaik.</p>

<h2>7. Lokasi dan akses</h2>
<p>The Skin Code Clinic berada di Krian, Sidoarjo — dapat dijangkau dari Krian, Wonoayu, Balongbendo, Tarik, hingga area Sidoarjo kota dan Surabaya barat. Untuk jam praktik dan ketersediaan dokter, konfirmasi melalui kontak resmi klinik sebelum datang agar kunjungan Anda tidak menunggu.</p>

<h2>8. Bentuk layanan yang tersedia</h2>
<p>Klinik kulit umumnya menyediakan tiga bentuk layanan: konsultasi untuk menegakkan diagnosis, penanganan medis dengan obat atau tindakan, dan tindakan estetika medis. Ketiganya tidak selalu diperlukan sekaligus. Pasien dengan keluhan ringan sering cukup ditangani dengan obat dan penyesuaian perawatan harian.</p>

<h2>9. Pertanyaan soal alat dan keamanan</h2>
<p>Jika tindakan akan dilakukan, tanyakan alat apa yang dipakai, siapa yang mengoperasikannya, dan bagaimana alat disterilkan. Pertanyaan ini wajar dan tidak perlu sungkan diajukan. Klinik yang bekerja sesuai standar akan menjelaskan prosedurnya, termasuk perawatan yang harus Anda lakukan setelah tindakan selesai.</p>

<h2>10. Lima pertanyaan sebelum memutuskan</h2>
<ul>
<li>Apa diagnosisnya, dan bagaimana dokter memastikannya?</li>
<li>Apakah ada pilihan selain tindakan yang ditawarkan?</li>
<li>Apa risikonya untuk jenis kulit saya?</li>
<li>Apa yang perlu saya lakukan setelah tindakan?</li>
<li>Kapan hasilnya dievaluasi, dan apa yang terjadi bila hasilnya kurang sesuai?</li>
</ul>
<p>Klinik yang baik tidak keberatan menjawab kelimanya. Jika jawabannya berputar atau menekan Anda untuk segera memutuskan, itu tanda untuk mencari pendapat lain.</p>

<h2>Tanda yang perlu diwaspadai</h2>
<p>Beberapa hal berikut layak membuat Anda berhati-hati saat memilih klinik: menjanjikan hasil permanen tanpa risiko untuk semua kondisi kulit, menawarkan paket sebelum kulit diperiksa, menekan keputusan dengan batas waktu, tidak bersedia menyebut siapa yang akan melakukan tindakan, atau tidak memberi penjelasan tertulis mengenai perawatan setelah tindakan.</p>

<h2>Kesimpulan</h2>
<p>Memilih klinik dokter kulit di Krian pada dasarnya adalah memilih cara kerja: siapa yang memeriksa, apakah diagnosis mendahului tindakan, dan seberapa jelas biaya serta evaluasinya dijelaskan. Dengan empat hal itu, keputusan Anda tidak bergantung pada janji, tetapi pada proses yang bisa diperiksa.</p>
<p>Kalau Anda ingin menilai langsung, mulai dari konsultasi. Sampaikan keluhan Anda, tanyakan rencananya, dan putuskan setelah penjelasannya jelas.</p>
"""


def rest(p, method="GET", data=None):
    h = {"Authorization": f"Basic {AUTH}", **UA}
    body = None
    if data is not None:
        body = json.dumps(data).encode(); h["Content-Type"] = "application/json"
    r = urllib.request.Request(f"https://{DOM}{p}", data=body, headers=h, method=method)
    for _ in range(3):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return json.loads(x.read())
        except urllib.error.HTTPError as e:
            return {"__err": e.code}
        except Exception:
            time.sleep(4)
    return {}


def rpc(method, params=()):
    def val(v):
        if isinstance(v, int):
            return f"<value><int>{v}</int></value>"
        if isinstance(v, list):
            return "<value><array><data>" + "".join(val(x) for x in v) + "</data></array></value>"
        if isinstance(v, dict):
            return "<value><struct>" + "".join(f"<member><name>{escape(str(k))}</name>{val(x)}</member>"
                                               for k, x in v.items()) + "</struct></value>"
        return f"<value><string>{escape(str(v))}</string></value>"
    body = ("<?xml version=\"1.0\"?><methodCall><methodName>" + method + "</methodName><params>" +
            "".join(f"<param>{val(p)}</param>" for p in params) + "</params></methodCall>").encode()
    r = urllib.request.Request(f"https://www.{DOM}/xmlrpc.php", data=body,
                               headers={"Content-Type": "text/xml", "User-Agent": "Mozilla/5.0",
                                        "Authorization": f"Basic {AUTH}"}, method="POST")
    time.sleep(0.5)
    try:
        with urllib.request.urlopen(r, timeout=150) as x:
            return x.read().decode("utf-8", "replace")
    except Exception as e:
        return f"ERR {str(e)[:80]}"


def hitung(t):
    h = html.unescape(re.sub(r"<[^>]+>", " ", re.sub(r"<script.*?</script>", " ", t, flags=re.S)))
    return len([w for w in re.split(r"\s+", h) if w])


d = rest(f"/wp-json/wp/v2/posts/{PID}?context=edit&_fields=id,slug,title,content")
raw = d["content"]["raw"]
print(f"=== sebelum ===")
print(f"   judul: {html.unescape(d['title']['raw'])}")
print(f"   {hitung(raw)} kata")
for pola in ("permanen", "tanpa risiko", "Rp", "4.8", "4.9", "98%", "85%", "70%", "garansi", "refund",
             "BPOM", "Halal", "MUI", "Kemenkes", "SpKK", "24/7", "malpractice"):
    n = len(re.findall(pola, raw, re.I))
    if n:
        print(f"   klaim '{pola}': {n}x")
print(f"\n=== sesudah (rencana) ===")
print(f"   judul: {JUDUL_BARU}")
print(f"   {hitung(ISI)} kata | FAQ & tautan lama dipertahankan")

if "--apply" not in sys.argv:
    print("\n(dry run — pakai --apply)")
    sys.exit(0)

# simpan salinan
open(f"{BACKUP}/post_{PID}_sebelum_tulis_ulang.txt", "w").write(raw)

# pertahankan blok FAQ + schema yang sudah ada
m_faq = re.search(r"<h2[^>]*>\s*FAQ\s*</h2>.*?(?=<h2[^>]*>\s*(?:Baca juga|Kesimpulan)\s*</h2>|\Z)", raw, re.S)
m_schema = re.search(r'<script type="application/ld\+json">.*?</script>', raw, re.S)
m_baca = re.search(r"<h2[^>]*>\s*Baca juga\s*</h2>.*?(?=\Z)", raw, re.S)
blok_faq = m_faq.group(0) if m_faq else ""
blok_schema = m_schema.group(0) if m_schema else ""
blok_baca = m_baca.group(0) if m_baca else ""
# buang Baca juga dari blok FAQ kalau ikut terbawa
blok_faq = re.split(r"<h2[^>]*>\s*Baca juga\s*</h2>", blok_faq)[0]

baru = ISI + "\n" + blok_faq + "\n" + blok_baca + "\n" + blok_schema
rest(f"/wp-json/wp/v2/posts/{PID}", "POST", {"content": baru, "title": JUDUL_BARU})

# meta Yoast
isi_rpc = rpc("wp.getPost", [1, USER, PASS, PID])
baris = {}
for kunci in ("_yoast_wpseo_title", "_yoast_wpseo_metadesc", "_yoast_wpseo_focuskw"):
    baris[kunci] = re.findall(r"<member><name>id</name><value><string>(\d+)</string></value></member>\s*"
                              r"<member><name>key</name><value><string>" + re.escape(kunci) +
                              r"</string></value></member>\s*<member><name>value</name><value><string>(.*?)</string>", isi_rpc, re.S)
for kunci, nilai in (("_yoast_wpseo_title", SEO_BARU), ("_yoast_wpseo_metadesc", META_BARU),
                     ("_yoast_wpseo_focuskw", FOKUS)):
    if not baris[kunci]:
        rpc("wp.editPost", [1, USER, PASS, PID, {"custom_fields": [{"key": kunci, "value": nilai}]}])
    for mid, _ in baris[kunci]:
        rpc("wp.editPost", [1, USER, PASS, PID, {"custom_fields": [{"id": int(mid), "key": kunci, "value": nilai}]}])
print("\n   meta Yoast diperbarui.")

print("\n=== verifikasi ===")
time.sleep(4)
cek = rest(f"/wp-json/wp/v2/posts/{PID}?context=edit&_fields=content,title,link")
raw2 = cek.get("content", {}).get("raw", "")
print(f"   judul: {html.unescape(cek.get('title', {}).get('raw', ''))}")
print(f"   {hitung(raw2)} kata | FAQPage: {'ada' if 'FAQPage' in raw2 else 'tidak'}")
sisa = [p for p in ("permanen", "tanpa risiko", "Rp", "4.8", "98%", "garansi", "BPOM", "Halal", "MUI",
                    "Kemenkes", "SpKK", "24/7", "malpractice") if re.search(p, raw2, re.I)]
print(f"   klaim yang masih tersisa: {sisa if sisa else 'tidak ada'}")
hh = urllib.request.urlopen(urllib.request.Request(cek["link"] + f"?v={int(time.time())}", headers=UA), timeout=90).read().decode("utf-8", "replace")
t = re.search(r"<title>(.*?)</title>", hh, re.S)
md = re.search(r'<meta name="description" content="([^"]*)"', hh)
print(f"   live judul: {t.group(1).strip() if t else '-'}")
print(f"   live meta : ({len(md.group(1)) if md else 0} char) {md.group(1)[:80] if md else '-'}")
print(f"   live sisa klaim: {[p for p in ('permanen','Rp800','4.8','garansi','BPOM') if p.lower() in hh.lower()] or 'bersih'}")
