#!/usr/bin/env python3
"""TSC — perapian klaster "klinik kecantikan krian".

Kanonik : #9102 /rekomendasi-6-klinik-kecantikan-di-krian-sidoarjo/ (198 tayangan, 9 klik)
Digabung: 12 halaman sejenis yang tayangannya 0-14 (duplikasi)
  - isi uniknya diangkat ke kanonik sebagai bagian baru (ditulis ulang)
  - halaman kembarnya dinonaktifkan dari hasil pencarian (noindex) supaya berhenti bersaing,
    tanpa menghapus halaman (jadi tidak ada 404 dan tidak butuh plugin pengalihan)

Pakai --go untuk menjalankan.
"""
import base64, importlib.util, json, os, re, sys, time, urllib.error, urllib.request

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

KANONIK = 9102
GABUNG = [8831, 9053, 9057, 9069, 8858, 2014, 9061, 9100, 9051, 9093, 1633, 1569]

TAMBAHAN = """
<h2>Cara Menilai Klinik Kecantikan yang Berstandar Medis</h2>
<p>Harga dan promosi biasanya jadi hal pertama yang dilihat, padahal yang menentukan hasil justru lima hal
berikut. Semuanya bisa Anda tanyakan langsung sebelum memutuskan.</p>

<ol>
<li><strong>Izin dan tenaga medisnya.</strong> Pastikan tindakan dilakukan dokter, bukan hanya terapis,
dan kliniknya punya izin operasional yang jelas.</li>
<li><strong>Diagnosis sebelum tindakan.</strong> Klinik yang baik memeriksa kondisi kulit Anda lebih dulu.
Kalau sejak awal langsung ditawari paket, itu tanda kurang bagus.</li>
<li><strong>Alat dan bahan yang dipakai.</strong> Tanyakan jenis alatnya dan apakah bahannya sekali pakai.
Ini bukan pertanyaan yang menyusahkan, ini pertanyaan yang wajar.</li>
<li><strong>Kejelasan biaya.</strong> Rincian harga sebaiknya disampaikan sebelum tindakan, termasuk apa
yang tidak termasuk di dalamnya.</li>
<li><strong>Kontrol setelah tindakan.</strong> Perawatan kulit jarang selesai sekali datang. Klinik yang
menyediakan jadwal kontrol berarti perawatannya dipantau, bukan sekadar dijual.</li>
</ol>

<h2>Facial Medis dan Bedanya dengan Facial Biasa</h2>
<p>Facial di salon dan facial medis sama-sama menenangkan kulit, tetapi tujuannya berbeda. Facial biasa
berfokus pada kebersihan dan relaksasi. Facial medis dilakukan setelah kulit diperiksa, dengan bahan dan
alat yang disesuaikan kondisi, misalnya untuk komedo, kulit kusam, atau tekstur yang tidak rata.</p>

<p>Karena itu rangkaian facial medis bisa berbeda antara satu pasien dan pasien lain. Kalau kulit Anda
sedang berjerawat aktif atau sensitif, jenis perawatannya perlu dipilih dokter agar tidak memperburuk
peradangan.</p>

<h2>Perawatan yang Umum di Klinik Kecantikan Krian</h2>
<ul>
<li><strong>Perawatan jerawat dan bekas jerawat.</strong> Penanganan jerawat aktif sampai penanganan bekas
berupa flek, kemerahan, dan tekstur kasar.</li>
<li><strong>Chemical peeling.</strong> Mengangkat sel kulit mati dengan asam, tingkatannya disesuaikan
jenis kulit.</li>
<li><strong>Microneedling atau dermapen.</strong> Merangsang pembentukan kolagen, sering dipakai untuk
bekas jerawat dan pori yang membesar.</li>
<li><strong>Laser dan radiofrequency.</strong> Untuk bekas jerawat, kemerahan, dan kekencangan kulit.</li>
<li><strong>Anti aging dan perawatan kulit berminyak.</strong> Termasuk penanganan garis halus serta
perawatan rutin untuk kulit yang mudah berjerawat.</li>
</ul>

<p>Yang menentukan bukan jumlah perawatan yang diambil, tetapi apakah jenisnya cocok dengan kondisi kulit
Anda saat ini.</p>

<h2>Yang Sebaiknya Membuat Anda Berhati-hati</h2>
<ul>
<li>Menjanjikan hasil pasti dalam hitungan hari, terutama untuk bekas jerawat atau flek.</li>
<li>Tidak bersedia menjelaskan bahan atau alat yang dipakai.</li>
<li>Menawarkan paket besar di kunjungan pertama, sebelum kulit diperiksa.</li>
<li>Tidak ada jadwal kontrol, atau kontrol hanya dibahas saat Anda menanyakan.</li>
</ul>
"""


def rest(path, 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}{path}", data=body, headers=h, method=method)
    for i in range(4):
        try:
            with urllib.request.urlopen(r, timeout=180) as x:
                return x.status, json.loads(x.read())
        except urllib.error.HTTPError as e:
            if e.code in (429, 404):
                time.sleep(4 * (i + 1))
                continue
            return e.code, e.read().decode()[:200]
        except Exception:
            time.sleep(4)
    return 0, "gagal"


go = "--go" in sys.argv
st, kan = rest(f"/wp-json/wp/v2/posts/{KANONIK}?context=edit&_fields=id,slug,content,link")
if not isinstance(kan, dict):
    sys.exit(f"gagal baca kanonik: {st}")
raw = kan["content"]["raw"]
baru = raw.rstrip() + "\n" + TAMBAHAN
print(f"kanonik #{KANONIK} /{kan['slug']}")
print(f"   panjang: {len(re.sub(r'<[^>]+>', ' ', raw).split())} → {len(re.sub(r'<[^>]+>', ' ', baru).split())} kata")

if go:
    open(f"{BACKUP}/post_{KANONIK}_sebelum.txt", "w").write(raw)
    st2, _ = rest(f"/wp-json/wp/v2/posts/{KANONIK}", "POST", {"content": baru})
    time.sleep(2)
    _, cek = rest(f"/wp-json/wp/v2/posts/{KANONIK}?context=edit&_fields=content")
    ok = "Cara Menilai Klinik Kecantikan yang Berstandar Medis" in (cek.get("content", {}).get("raw", ""))
    print(f"   tulis: HTTP {st2} · bagian baru {'masuk ✅' if ok else 'GAGAL ❌'}")

print(f"\nhalaman kembar yang dinonaktifkan dari pencarian ({len(GABUNG)}):")
for pid in GABUNG:
    st3, o = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=id,slug,link,meta")
    if not isinstance(o, dict):
        print(f"   #{pid} gagal dibaca ({st3})")
        continue
    print(f"   #{pid:<5} /{o['slug'][:58]}")
    if go:
        open(f"{BACKUP}/meta_{pid}_sebelum.json", "w").write(json.dumps(o.get("meta") or {}, ensure_ascii=False))
        st4, _ = rest(f"/wp-json/wp/v2/posts/{pid}", "POST", {
            "meta": {"_yoast_wpseo_meta-robots-noindex": "1"}})
        time.sleep(1)
        _, c2 = rest(f"/wp-json/wp/v2/posts/{pid}?context=edit&_fields=meta")
        nilai = (c2.get("meta") or {}).get("_yoast_wpseo_meta-robots-noindex")
        print(f"        noindex: HTTP {st4} · nilai tersimpan {nilai}")
    time.sleep(0.4)

if not go:
    print("\n(dry run — pakai --go)")
