#!/usr/bin/env python3
"""
Threads Mention Autoreply v2 — SEMUA akun Threads di Repliz
Balas komentar/mention yang MASUK ke semua akun Threads kita dengan bahasa humanis & sambutan positif.

Akun yang dicover (8):
- @ukyhandoko        (6a334e89c5ff4ce3a3225a48)
- @studiosoft.id     (6a335b9ec5ff4ce3a3225c2a)
- @leitsurabaya      (6a5f4af462caae1e04e8b9a6)
- @tslaw             (6a35f8b7c5ff4ce3a322b2ed)
- @dniclinic_krian   (6a4bbc5920e4f4f195e52960)  TSC
- @das_bengkel       (6a39e461c5ff4ce3a3233e09)  DAS
- DMark Threads      (6a3574c6c5ff4ce3a3228d70)
- EveryBe Threads    (6a44ed1920e4f4f195d8ecf7)

Aturan (FIXED 4 Agustus 2026):
- Balas SEMUA komentar pending, termasuk komentar dari sesama akun kita (saling mention).
- Bahasa humanis, sambutan positif, pakai "saya" (bukan "gue").
- Maks 480 karakter per balasan.
- Jalan via cron tiap 30 menit; max 10 reply/run, jeda 60 detik biar natural.
- Tracker global biar gak balas 2x; error non-400 dicoba ulang di run berikutnya.

UPDATE (17 Agustus 2026):
- STOP reply komentar yang berasal dari / menyebut @rsiakendangsari (RSIA Kendangsari).
  Komentar tersebut di-SKIP tanpa dibalas (jangan di-track sebagai failed, cukup dilewati).
"""
import sys, json, os, time, random
import urllib.request, urllib.error
sys.path.insert(0, "/home/mantapman/.hermes/profiles/atun/workspace")
from repliz_client import HEADERS, BASE
from threads_text_check import cek_teks_threads, ThreadsTextError

# ── SEMUA akun Threads yang ada di Repliz ──
THREADS_ACCOUNTS = [
    {"id": "6a334e89c5ff4ce3a3225a48", "name": "@ukyhandoko"},
    {"id": "6a335b9ec5ff4ce3a3225c2a", "name": "@studiosoft.id"},
    # {"id": "6a5f4af462caae1e04e8b9a6", "name": "@leitsurabaya"},  # LEIT DIKELUARKAN 24 Agu 2026: hanya posting caption, TIDAK ikut reply/diskusi/comment
    {"id": "6a35f8b7c5ff4ce3a322b2ed", "name": "@tslaw"},
    {"id": "6a4bbc5920e4f4f195e52960", "name": "@dniclinic_krian"},
    {"id": "6a39e461c5ff4ce3a3233e09", "name": "@das_bengkel"},
    {"id": "6a3574c6c5ff4ce3a3228d70", "name": "DMark Threads"},
    {"id": "6a44ed1920e4f4f195d8ecf7", "name": "EveryBe Threads"},
]

TRACKER = "/home/mantapman/.hermes/profiles/atun/workspace/.threads_mention_tracker.json"
MAX_PER_RUN = 10
DELAY_SECONDS = 60
MAX_REPLY_CHARS = 480

# Tidak ada filter "sesama kita" — semua komentar dibalas (instruksi Bos 4 Agustus 2026).


def load_tracker():
    if os.path.exists(TRACKER):
        try:
            with open(TRACKER) as f:
                return json.load(f)
        except Exception:
            return {}
    return {}


def save_tracker(t):
    with open(TRACKER, "w") as f:
        json.dump(t, f, indent=2)


def http_get(path):
    req = urllib.request.Request(BASE + path, headers=HEADERS)
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.loads(r.read())


def post_reply(doc_id, text):
    """Balas komentar via POST /public/comment/{doc_id} body {text}"""
    req = urllib.request.Request(
        BASE + f"/public/comment/{doc_id}",
        data=json.dumps({"text": text}).encode(),
        headers={**HEADERS, "Content-Type": "application/json"},
        method="POST",
    )
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.loads(r.read())


def fetch_pending_all():
    """Ambil semua komentar pending untuk SEMUA akun Threads kita."""
    docs = []
    for page in range(1, 8):
        d = http_get(f"/public/comment?page={page}&limit=50")
        batch = d.get("docs", [])
        docs += batch
        if len(batch) < 50:
            break
    valid_ids = {a["id"] for a in THREADS_ACCOUNTS}
    out = []
    for x in docs:
        if x.get("accountId") not in valid_ids:
            continue
        if x.get("status") not in ("pending",):
            continue
        c = x.get("comment") or {}
        owner = c.get("owner") or {}
        text = (c.get("text") or "").strip()
        if not text:
            continue
        acc_name = next((a["name"] for a in THREADS_ACCOUNTS if a["id"] == x.get("accountId")), x.get("accountId"))
        out.append({
            "doc_id": x.get("_id"),
            "comment_id": c.get("id"),
            "owner": owner.get("name") or "?",
            "account": acc_name,
            "text": text,
            "created": x.get("createdAt", ""),
        })
    out.sort(key=lambda r: r["created"], reverse=True)
    return out


def _is_rsia(owner: str, text: str) -> bool:
    """Deteksi apakah komentar berasal dari @rsiakendangsari / RSIA Kendangsari."""
    o = (owner or "").lower()
    t = (text or "").lower()
    blob = o + " " + t
    return any(k in blob for k in
               ["kendangsari", "rsiakendangsari", "rsia kendangsari", "@rsiakendangsari"])


def _rsia_reply(comment_text: str) -> str:
    """Balasan humble & sesuai konteks jawaban dari @rsiakendangsari.
    Khusus: TIDAK bahas AI/hal teknis di luar konteks, cukup humble + say thanks."""
    t = comment_text.lower()

    # ── konteks: penjelasan medis/kondisi bayi & anak ──
    if any(k in t for k in ["gumoh", "muntah", "asi", "menyusui", "imunisasi", "vaksin",
                            "demam", "mencret", "diare", "madiput", "refluks"]):
        return random.choice([
            "Terima kasih banyak penjelasannya, Dok! \U0001F64F Sekarang saya lebih tenang memahami kondisi si kecil. Senang bisa berdiskusi di sini. Semoga sehat selalu ya, Dok!",
            "Wah, terima kasih sudah dijelaskan dengan sabar, Dok. Ini sangat membantu orang tua baru seperti saya. Senang diskusi di sini. Semoga RSIA Kendangsari selalu diberi kesehatan \u263A",
        ])

    # ── konteks: tumbuh kembang / milestone / perkembangan anak ──
    if any(k in t for k in ["tumbuh kembang", "milestone", "merangkak", "berjalan", "bicara",
                            "perkembangan", "telat", "keterlambatan", "berat badan", "tinggi"]):
        return random.choice([
            "Terima kasih banyak atas jawabannya, Dok! \U0001F64F Penjelasannya menenangkan dan jelas. Senang bisa berdiskusi di sini. Semoga sehat selalu ya, Dok!",
            "Semoga sehat selalu, Dok! Terima kasih sudah meluangkan waktu menjawab. Ini sangat bermanfaat untuk kami orang tua. Senang sekali bisa bertanya di @rsiakendangsari ❤\ufe0f",
        ])

    # ── konteks: nutrisi / makanan / suplemen ──
    if any(k in t for k in ["nutrisi", "makanan", "mpasi", "suplemen", "vitamin", "gizi",
                            "susu", "alergi", "makan"]):
        return random.choice([
            "Terima kasih penjelasannya, Dok! \U0001F64F Panduannya jelas banget buat kami. Senang bisa berdiskusi di sini. Semoga sehat selalu ya, Dok!",
            "Makasih banyak, Dok! Info nutrisinya lengkap dan mudah dipahami. Hormat dari saya, semoga RSIA Kendangsari selalu sehat \u2764\ufe0f",
        ])

    # ── konteks: kehamilan / persalinan / menyusui ibu ──
    if any(k in t for k in ["kehamilan", "hamil", "persalinan", "melahirkan", "bidan",
                            "kandungan", "usg", "kia"]):
        return random.choice([
            "Terima kasih banyak, Dok! \U0001F64F Jawabannya menenangkan calon ibu seperti saya. Senang bisa berdiskusi di sini. Semoga sehat selalu ya, Dok!",
            "Semoga sehat selalu, Dok! Terima kasih sudah menjawab dengan ramah. Berdiskusi di @rsiakendangsari bikin kami makin percaya ❤\ufe0f",
        ])

    # ── konteks: umum / sapaan & apresiasi RSIA ──
    if any(k in t for k in ["terima kasih", "sama sama", "makasih", "silakan", "informasi",
                            "review", "followers", "instagram", "rating", "selalu siap"]):
        return random.choice([
            "Terima kasih ya, Dok! \U0001F64F Senang bisa berdiskusi di sini. Semoga sehat selalu!",
            "Aamiin, terima kasih banyak! \U0001F60A Senang rasanya bisa berdiskusi dengan @rsiakendangsari. Semoga sehat selalu, Dok!",
        ])

    # ── default humble untuk jawaban RSIA (sesuai konteks apapun) ──
    return random.choice([
        "Terima kasih ya, Dok! \U0001F64F Senang bisa berdiskusi di sini. Semoga sehat selalu!",
        "Makasih banyak atas jawabannya, Dok! \U0001F60A Jawaban ini sangat membantu. Senang berdiskusi di @rsiakendangsari. Semoga sehat selalu!",
        "Terima kasih sudah meluangkan waktu, Dok. \U0001F64C Senang bisa berdiskusi di sini. Semoga sehat selalu ya!",
    ])


def generate_reply(comment_text: str, owner: str) -> str:
    """Bikin balasan humanis & positif sesuai isi komentar."""
    t = comment_text.lower()

    # ── KHUSUS @rsiakendangsari (STOP — 17 Agustus 2026) ──
    # Instruksi Bos: JANGAN balas komentar yang berasal dari / menyebut @rsiakendangsari.
    if _is_rsia(owner, comment_text):
        return None

    # ── kategori: belajar/tutor SEO ──
    if any(k in t for k in ["tutor", "belajar seo", "cara belajar", "mulai belajar", "gimana caranya", "bagaimana caranya"]):
        return random.choice([
            "Makasih udah mampir kak! \U0001F64F Buat mulai belajar SEO, saran saya mulai dari 3 hal: pahami cara kerja Google, riset kata kunci yang relevan, dan konsisten bikin konten yang menjawab kebutuhan orang. Gak perlu tools mahal dulu — pahami konsepnya. Kalau ada yang bingung, tanya aja di sini ya! \U0001F60A",
            "Senang banget ada yang mau belajar SEO! \U0001F604 Mulainya dari riset kata kunci dulu ya kak — dari situ kita tahu orang lagi nyari apa. Pelan-pelan aja, yang penting mulai dan konsisten. Nanti kalau mentok, diskusi di sini aja!",
        ])

    # ── kategori: lucu / instan / mie ──
    if any(k in t for k in ["indomie", "instan", "wkwk", "wkwkw", "haha", "hehe"]):
        return random.choice([
            "Haha setuju banget! \U0001F604 Kalau yang instan itu Indomie & Mie Sedap, kalau SEO mah harus sabar dikit. Tapi hasilnya jauh lebih mengenyangkan \U0001F60E",
            "Wkwk relatable banget! \U0001F602 Justru di situ bedanya — yang instan cuma numpang lewat, yang konsisten yang dapet hasil jangka panjang.",
        ])

    # ── kategori: setuju/sepakatan ──
    if any(k in t for k in ["sepakat", "setuju", "bener banget", "bener juga", "betul", "bener"]):
        return random.choice([
            "Sepakat! \U0001F64C Hasil yang bertahap justru yang paling awet. SEO itu kayak nanam pohon — makin lama dirawat, makin rindang.",
            "Makasih kak! \U0001F60A Senang rasanya kalau insight-nya nyambung sama pengalaman teman-teman di sini. Semoga makin berkembang ya usahanya!",
        ])

    # ── kategori: backlink ──
    if "backlink" in t:
        return random.choice([
            "Betul kak, backlink itu penting tapi bukan satu-satunya. Konten yang relevan + pengalaman pengguna yang baik justru fondasi yang lebih sehat buat SEO jangka panjang.",
            "Iya nih, banyak yang mengira SEO = banyak backlink. Padahal kualitas dan relevansi jauh lebih penting daripada kuantitas. Pelan-pelan tapi pasti!",
        ])

    # ── kategori: klien / business owner ──
    if any(k in t for k in ["klien", "business owner", "owner", "client"]):
        return random.choice([
            "Pertanyaan yang sering banget muncul! \U0001F4A1 Kuncinya komunikasi ekspektasi dari awal: SEO itu maraton, bukan sprint. Kalau dikemas dengan laporan progres yang jelas, owner biasanya paham kok kak.",
            "Nah ini tantangan klasik \U0001F604 Saya biasanya ajak owner lihat data dulu — dari mana pengunjung datang, kata kunci apa yang naik. Angka yang bicara lebih meyakinkan daripada janji.",
        ])

    # ── kategori: DM/WA/kontak ──
    if any(k in t for k in ["dm", "wa ", " whatsapp", "cek dm", "chat"]):
        return "Halo kak! \U0001F64F Boleh banget, silakan DM aja ya — nanti saya balas secepatnya. Makasih sudah mampir! \U0001F60A"

    # ── kategori: sales pitch / advertiser ──
    if any(k in t for k in ["advertiser", "spending", "saya bisa bantu", "jasa", "tawaran"]):
        return "Makasih kak sudah mampir dan sharing! \U0001F64F Saya selalu terbuka dengan kolaborasi yang saling menguntungkan. Boleh lanjut lewat DM biar bisa ngobrol lebih detail ya! \U0001F60A"

    # ── kategori: terima kasih / apresiasi ──
    if any(k in t for k in ["makasih", "terima kasih", "thanks", "thank you"]):
        return random.choice([
            "Sama-sama kak! \U0001F60A Senang bisa berbagi. Kalau ada topik yang pengen dibahas lebih dalam, tinggal komen aja ya!",
            "Makasih kembali! \U0001F64C Justru diskusi di kolom komentar ini yang bikin kontennya makin hidup. Mampir lagi ya kak!",
        ])

    # ── kategori: AI / tools ──
    if any(k in t for k in ["ai", "tools", "artificial"]):
        return random.choice([
            "Betul kak! \U0001F916 AI itu alat bantu, bukan pengganti strategi. Yang penting kita tetap paham konsepnya, biar AI-nya dipakai di tempat yang tepat.",
            "Setuju — tools AI sekarang memang powerful banget. Tapi yang bikin beda tetap cara kita menyusun strategi dan memahami kebutuhan pasar. \U0001F60A",
        ])

    # ── kategori: mention dari sesama akun kita (saling sapa) ──
    if any(k in t for k in ["@ukyhandoko", "@studiosoft.id", "@leitsurabaya", "@tslaw", "@dniclinic_krian", "@das_bengkel"]):
        return random.choice([
            "Makasih udah nyapa! \U0001F64C Senang banget bisa saling support di sini. Semoga kolaborasi kita makin seru ke depannya! \U0001F60A",
            "Halo! \U0001F44B Makasih udah mention. Kita emang satu tim — saling dukung dan saling belajar itu kuncinya. Sukses terus ya! \U0001F680",
        ])

    # ── default humanis (sambutan positif) ──
    return random.choice([
        "Makasih responnya kak! \U0001F64F Senang diskusinya hidup di sini. Kalau ada topik yang mau dibahas lebih dalam, tinggal komen aja ya!",
        "Wah makasih udah baca dan komen! \U0001F60A Semoga insight-nya kepake buat usaha kak. Jangan sungkan mampir lagi ya!",
        "Makasih udah mampir kak! \U0001F60A Setiap komen di sini sangat berarti — siapa tahu jadi bahasan seru berikutnya di postingan saya.",
        "Halo kak, makasih sudah menyempatkan komen! \U0001F60A Saya senang banget bisa ngobrol sama teman-teman di sini. Ada yang mau ditanyakan lagi?",
    ])


def main():
    tracker = load_tracker()
    pending = fetch_pending_all()
    todo = [p for p in pending if p["doc_id"] not in tracker]
    # STOP reply @rsiakendangsari (17 Agustus 2026) — skip komentar RSIA
    todo = [p for p in todo if not _is_rsia(p["owner"], p["text"])]
    print(f"Komentar pending (semua akun): {len(pending)} | belum dibalas: {len(todo)}")
    for p in todo[:MAX_PER_RUN]:
        print(f"  - [{p['account']}] {p['owner']}: {p['text'][:80]}")

    done = 0
    for p in todo[:MAX_PER_RUN]:
        reply = generate_reply(p["text"], p["owner"])
        if reply is None:
            print(f"  SKIP: komentar dari/menyebut @rsiakendangsari — tidak dibalas")
            continue
        # VALIDASI KETAT (FIXED 5 Agustus 2026): max karakter + link nyala, JANGAN dipotong
        try:
            reply = cek_teks_threads(reply, label="Balasan", maxlen=MAX_REPLY_CHARS)
        except ThreadsTextError as e:
            print(f"  SKIP: {e}")
            continue
        try:
            res = post_reply(p["doc_id"], reply)
            tracker[p["doc_id"]] = {
                "account": p["account"],
                "owner": p["owner"],
                "comment": p["text"][:100],
                "reply": reply[:100],
                "replied_at": time.strftime("%Y-%m-%d %H:%M:%S"),
            }
            save_tracker(tracker)
            print(f"  \U0001F5E8 [{p['account']}] Balas {p['owner']} ({p['comment_id']}) -> {str(res)[:80]}")
            done += 1
            if done < MAX_PER_RUN and done < len(todo):
                time.sleep(DELAY_SECONDS)
        except urllib.error.HTTPError as e:
            # 400 = bad request permanen (komentar emoji saja / sudah tidak valid)
            # → tandai failed biar gak dicoba ulang terus
            if e.code == 400:
                tracker[p["doc_id"]] = {
                    "account": p["account"],
                    "owner": p["owner"],
                    "comment": p["text"][:100],
                    "reply": "",
                    "failed": "400 bad request",
                    "replied_at": time.strftime("%Y-%m-%d %H:%M:%S"),
                }
                save_tracker(tracker)
            print(f"  \u26A0 [{p['account']}] Gagal balas {p['owner']}: HTTP {e.code}")
        except Exception as e:
            # error lain: JANGAN tandai tracker → dicoba lagi run berikutnya
            print(f"  \u26A0 [{p['account']}] Gagal balas {p['owner']}: {str(e)[:120]}")

    sisa = len(todo) - done
    print(f"Selesai — {done} reply terkirim (maks {MAX_PER_RUN}/run). Sisa antrian: {sisa} (diproses run berikutnya).")


if __name__ == "__main__":
    main()
