#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""PILOT 12 Okt 2026 — slot 05:00 WIB StudioSoft Threads diubah dari post ber-link
(templat seri manufaktur) menjadi post PERCAKAPAN tanpa link.

Alasan (data, lihat references/views-dan-statistik-repliz.md):
- 05:00 adalah slot ber-link paling lemah; hari dengan >=3 post ber-link rata-rata
  24 views vs <3 link 160 views (uky, 22 hari).
- Caption seri manufaktur + balasan templat ("Kata kunci yang biasanya dibidik...")
  diulang puluhan kali = penyebab jangkauan jatuh (pelajaran 4 Okt).

Mode:
  python3 pilot_ss_0500_percakapan.py            # dry run (lihat rencana + contoh)
  python3 pilot_ss_0500_percakapan.py --run      # eksekusi (backup dulu ke json)
  python3 pilot_ss_0500_percakapan.py --balikkan <file.json>   # pulihkan caption lama
"""
import argparse
import datetime
import json
import os
import sys

WS = "/home/mantapman/.hermes/profiles/atun/workspace"
sys.path.insert(0, WS)
from repliz_client import ReplizClient  # noqa: E402

WIB = datetime.timezone(datetime.timedelta(hours=7))
SS = "6a335b9ec5ff4ce3a3225c2a"
TGL_MULAI = "2026-10-13"
TGL_AKHIR = "2026-10-19"
BACKUP = f"{WS}/pilot_ss_0500_backup_20261012.json"

# (tanggal, topik/label, caption utama, balasan sendiri)
BANK = [
    ("2026-10-13", "Laporan Klien & Relasi", (
        "Tiga tahun lalu kami hampir kehilangan klien besar karena satu hal sepele: laporan bulanan isinya angka semua, "
        "tanpa cerita apa pun.\n\nPadahal yang dibaca pemilik bisnis bukan grafik. Yang dia mau tahu cuma dua: apa yang "
        "berubah, dan apa yang perlu dia lakukan pekan depan.\n\nSejak itu tiap laporan kami buka dengan satu paragraf "
        "bahasa manusia sebelum masuk tabel.\n\nLaporan klienmu mulai dari angka atau dari cerita? Tulis di komentar ya."
    ), "Tambahan: klien yang paham konteks biasanya lebih sabar saat hasilnya belum kelihatan. Itu untung buat dua pihak."),
    ("2026-10-14", "Iklan atau SEO untuk UMKM", (
        "Sering ditanya: uang terbatas, mending iklan atau SEO dulu?\n\nJawaban gampangnya: iklan buat yang butuh cepat, "
        "SEO buat yang mau tenang di tahun kedua.\n\nYang jarang dibahas: iklan numpang di halaman orang, SEO bikin halaman "
        "kamu sendiri yang kerja. Kalau iklan distop, hilang. Kalau SEO dirawat, masih ada.\n\nKalau budget kamu cuma cukup "
        "satu, kamu pilih mana? Cerita alasannya di komentar."
    ), "Catatan kecil: dua-duanya lebih murah kalau websitenya sudah beres dulu. Halaman lambat bikin iklan mahal dan SEO lambat naik."),
    ("2026-10-15", "Kepercayaan ke Penyedia Jasa", (
        "Sebelum percaya ke penyedia jasa, kamu paling dulu lihat yang mana?\n\nPortofolio, harga, atau cara dia menjawab "
        "pertanyaan kamu?\n\nDari pengalaman kami, yang bikin orang akhirnya deal biasanya hal ketiga. Bukan karena jawabannya "
        "hebat, tapi karena dia jujur soal apa yang belum bisa dijanjikan.\n\nKalau kamu jadi pembeli jasa, apa yang bikin "
        "kamu yakin? Tulis di komentar ya, kami baca satu-satu."
    ), "Kalau penjual jasa menjawab semua pertanyaanmu dengan \"bisa\", itu justru alarm. Yang bagus berani bilang tidak untuk sebagian permintaan."),
    ("2026-10-16", "Cara Memilih Klien", (
        "Kami pernah menerima klien yang sebenarnya tidak cocok, dan itu pelajaran mahal.\n\nSekarang ada tiga hal yang kami "
        "cek dulu sebelum mulai: dia mau buka data, dia mau ikut rapat, dan dia punya orang di dalam yang bisa memutuskan.\n\n"
        "Kalau satu saja tidak ada, proyek sebagus apa pun biasanya berhenti di tengah.\n\nBuat kamu yang jalan di jasa: "
        "apa syarat wajib kamu sebelum menerima klien? Tulis di komentar ya."
    ), "Bukan soal sombong. Proyek yang salah orang itu bukan cuma rugi biaya, tapi ngabisin energi tim yang seharusnya dipakai di tempat lain."),
    ("2026-10-17", "Website & Kecepatan Halaman", (
        "Banyak yang masih mikir \"website saya sudah bagus\" karena tampilannya rapi.\n\nPadahal yang dilihat Google dan "
        "pengunjung pertama kali lain: seberapa cepat halaman terbuka di HP.\n\nCoba tes sendiri sekarang. Buka satu halaman "
        "di HP pakai data seluler, hitung sampai halaman penuh terbuka. Lewat 3 detik, itu masalah yang bikin iklan mahal dan "
        "pengunjung kabur.\n\nHasil tesnya berapa? Tulis di komentar, biar kami kasih pandangan."
    ), "Paling sering biangnya cuma ukuran foto yang tidak diperkecil. Kami pernah temui folder gambar yang bikin hosting mahal bertahun-tahun."),
    ("2026-10-18", "Tips Cek Website Sendiri", (
        "Cek website sendiri tanpa perlu bantuan siapa pun, lakukan tiga ini:\n\n1. Buka di HP pakai data seluler, tidak pakai "
        "wifi kantor. 2. Cari satu kata yang biasanya dipakai calon pembeli, lihat apakah halaman kamu muncul. 3. Isi formulir "
        "kontak sendiri, rasakan dari sisi pembeli.\n\nSelesai lima menit, dan biasanya sudah ketemu masalahnya di mana.\n\n"
        "Sudah pernah coba? Tulis di komentar, bagian mana yang paling bikin kaget."
    ), "Langkah ketiga paling sering terlewat. Formulir yang error itu diam-diam, tidak ada yang memberitahu sampai ada calon pembeli yang mengeluh."),
    ("2026-10-19", "Budget Marketing UMKM", (
        "Pertanyaan yang jarang dijawab jujur: berapa sebenarnya anggaran marketing yang wajar buat usaha kecil?\n\nTidak ada "
        "angka ajaib. Yang ada tiga kebiasaan: sisihkan rutin walau kecil, ukur satu hal saja per bulan, dan jangan pindah "
        "strategi tiap dua minggu.\n\nYang bikin budget habis bukan jumlahnya kecil, tapi pindah-pindah tanpa diselesaikan.\n\n"
        "Berapa persen omzet yang kamu sisihkan buat marketing? Cerita di komentar ya."
    ), "Kalau belum ada anggaran sama sekali, mulai dari satu hal yang bisa diukur. Satu kampanye kecil selesai lebih berguna daripada lima yang gagal di tengah."),
]


def semua(path, maks=40):
    c = ReplizClient()
    docs, page = [], 1
    while page <= maks:
        r = None
        for _ in range(10):
            try:
                r = c.get(f"{path}?page={page}&limit=100")
                break
            except Exception:
                r = None
        if r is None:
            break
        d = r.get("docs") or []
        docs += d
        if not d or page * 100 >= (r.get("totalDocs") or 0):
            break
        page += 1
    return docs


def cari_slot(c):
    hasil = {}
    for s in semua("/public/schedule"):
        if (s.get("account") or {}).get("_id") != SS:
            continue
        try:
            dt = datetime.datetime.fromisoformat((s.get("scheduleAt") or "").replace("Z", "+00:00")).astimezone(WIB)
        except ValueError:
            continue
        if dt.hour != 5 or dt.minute != 0:
            continue
        d = dt.date().isoformat()
        if TGL_MULAI <= d <= TGL_AKHIR and s.get("status") == "pending":
            hasil[d] = s
    return hasil


def validasi(teks, balas):
    pesan = []
    if len(teks) > 480:
        pesan.append(f"caption {len(teks)} char (>480)")
    if "http" in teks:
        pesan.append("caption masih memuat link")
    if "Anda" in teks or " anda " in teks:
        pesan.append("pakai 'Anda' (sosmed harus 'kamu')")
    tail = teks[-120:].lower()
    if not any(k in tail for k in ("komentar", "cerita", "tulis", "pendapat", "pilih")):
        pesan.append("CTA komentar tidak ada di 120 char terakhir")
    if "@" in teks:
        pesan.append("ada mention")
    if any(ch > "\u2fff" for ch in teks):
        pesan.append("ada karakter CJK")
    for tag in [w for w in teks.split() if w.startswith("#")]:
        if tag != tag.lower():
            pesan.append(f"hashtag besar: {tag}")
    if len(balas) > 400:
        pesan.append(f"balasan {len(balas)} char (>400)")
    return pesan


def main():
    p = argparse.ArgumentParser()
    p.add_argument("--run", action="store_true")
    p.add_argument("--balikkan", metavar="FILE")
    a = p.parse_args()
    c = ReplizClient()

    if a.balikkan:
        data = json.load(open(a.balikkan))
        ok = 0
        for sid, lama in data.items():
            try:
                c.update_schedule(sid, lama["payload"])
                baca = c.get_schedule(sid)
                cocok = (baca.get("description") or "") == (lama["payload"].get("description") or "")
                print(f"{'✅' if cocok else '⚠️'} {sid} dipulihkan={cocok}")
                ok += 1 if cocok else 0
            except Exception as e:
                print(f"❌ {sid}: {str(e)[:120]}")
        print(f"\n{ok}/{len(data)} jadwal dipulihkan ke caption lama")
        return

    slot = cari_slot(c)
    print(f"slot 05:00 WIB {TGL_MULAI}..{TGL_AKHIR} yang ketemu: {len(slot)}")
    rencana, cadangan = [], {}
    for tgl, topik, teks, balas in BANK:
        s = slot.get(tgl)
        if not s:
            print(f"  ⚠️ {tgl}: slot tidak ada (dilewati)")
            continue
        masalah = validasi(teks, balas)
        print(f"\n{tgl} | {s['_id']} | {topik}")
        print(f"   caption lama ({len(s.get('description') or '')} char): {(s.get('description') or '')[:90]}...")
        print(f"   caption baru ({len(teks)} char): {teks[:90]}...")
        print(f"   validasi: {'✅ bersih' if not masalah else '❌ ' + '; '.join(masalah)}")
        if masalah:
            continue
        rencana.append((s, tgl, topik, teks, balas))
        cadangan[s["_id"]] = {
            "payload": {
                "accountId": SS,
                "title": s.get("title"),
                "description": s.get("description"),
                "topic": s.get("topic"),
                "type": s.get("type"),
                "medias": s.get("medias") or [],
                "replies": s.get("replies") or [],
                "scheduleAt": s.get("scheduleAt"),
            },
            "tanggal": tgl,
        }

    if not a.run:
        print(f"\nDRY RUN — {len(rencana)} jadwal siap diubah. Jalankan ulang dengan --run untuk eksekusi.")
        return

    json.dump(cadangan, open(BACKUP, "w"), ensure_ascii=False, indent=1)
    print(f"\nbackup caption lama → {BACKUP}")
    sukses = 0
    for s, tgl, topik, teks, balas in rencana:
        payload = {
            "accountId": SS,
            "title": f"StudioSoft — Percakapan {tgl}",
            "description": teks,
            "topic": topik,
            "type": "text",
            "medias": [],
            "replies": [{"text": balas, "username": "", "status": "pending"}],
            "scheduleAt": s.get("scheduleAt"),
        }
        try:
            c.update_schedule(s["_id"], payload)
        except Exception as e:
            print(f"❌ {tgl}: {str(e)[:140]}")
            continue
        baca = c.get_schedule(s["_id"])
        ok = ((baca.get("description") or "") == teks
              and baca.get("status") == "pending"
              and not (baca.get("medias") or [])
              and len(baca.get("replies") or []) == 1)
        print(f"{'✅' if ok else '⚠️'} {tgl} {s['_id']} | status={baca.get('status')} "
              f"len={len(baca.get('description') or '')} media={len(baca.get('medias') or [])} "
              f"replies={len(baca.get('replies') or [])} topic={baca.get('topic')}")
        sukses += 1 if ok else 0
    print(f"\n{sukses}/{len(rencana)} terpasang & terverifikasi baca-balik")


if __name__ == "__main__":
    main()
