#!/usr/bin/env python3
"""
Threads Reply Cron — Ngecek postingan Threads yang baru tayang, reply 3x otomatis
Jalan tiap 15 menit via cron system (bukan crontab)

Akun yang di-cover:
- @ukyhandoko (6a334e89c5ff4ce3a3225a48)
- StudioSoft Threads (6a335b9ec5ff4ce3a3225c2a)
- TS Law Threads (6a35f8b7c5ff4ce3a322b2ed)
- DAS Threads (6a39e461c5ff4ce3a3233e09)
- TSC Threads (6a4bbc5920e4f4f195e52960)
- DMark Threads (6a3574c6c5ff4ce3a3228d70)
"""

import urllib.request, json, base64, os, time
from datetime import datetime, timezone, timedelta

from repliz_client import AUTH, HEADERS, BASE

# ==================== KONFIGURASI ====================
WIB = timezone(timedelta(hours=7))
REPLY_TRACK_FILE = '/home/mantapman/.hermes/profiles/atun/workspace/.threads_reply_tracker.json'

THREADS_ACCOUNTS = {
    "6a334e89c5ff4ce3a3225a48": "Uky Threads",
    "6a335b9ec5ff4ce3a3225c2a": "StudioSoft Threads",
    # LEIT DIKELUARKAN 28 Agu 2026 (instruksi Bos): TIDAK ada mention dari akun kita
    # ke Threads LEIT (@leitsurabaya) — jangan dimasukkan lagi ke mesin reply/mention.
    "6a35f8b7c5ff4ce3a322b2ed": "TS Law Threads",
    "6a39e461c5ff4ce3a3233e09": "DAS Threads",
    "6a4bbc5920e4f4f195e52960": "TSC Threads",
    "6a3574c6c5ff4ce3a3228d70": "DMark Threads",
    "6a44ed1920e4f4f195d8ecf7": "EveryBe Threads",
}

# ==================== REPLY TEMPLATE ====================
# Fungsi bikin reply berdasarkan topik caption
def generate_replies(caption_text, akun_name):
    """Bikin 3 reply natural berdasarkan caption yang tayang"""
    caption_lower = caption_text.lower()
    
    # Deteksi keyword dari caption
    keywords = {
        "kecepatan": ["Bener banget soal kecepatan. Saya juga ninggalin website lemot dalam 3 detik.",
                      "Coba pake Pagespeed Insights atau GTmetrix buat cek skor loading website Anda.",
                      "Tips: kompres gambar pake WebP, aktifkan caching, dan pilih hosting yang tepat."],
        "seo": ["SEO itu investasi jangka panjang. Hasilnya gak instan tapi bertahan lama.",
                "Mulai dari riset keyword dulu. Cari yang volume sedang tapi relevan, kompetisinya rendah.",
                "Konten berkualitas + struktur website yang rapi = fondasi SEO yang kuat."],
        "branding": ["Branding itu bukan cuma logo. Ini pengalaman dari pertama kenal sampai pasca-pembelian.",
                     "Konsistensi adalah kunci. Visual, suara, dan pelayanan harus nyambung di semua titik.",
                     "Brand yang kuat bikin customer milih Anda tanpa mikir harga."],
        "marketing": ["Marketing tanpa data itu cuma feeling. Mulai tracking dari sekarang.",
                      "Fokus ke channel yang paling efektif untuk target pasar Anda. Jangan tersebar.",
                      "Konsistensi lebih penting dari intensitas. Posting rutin > posting massive sekali."],
        "legal": ["Legalitas itu fondasi bisnis. Jangan dianggap remeh.",
                  "Kontrak yang rapi bikin kerja sama lebih profesional dan aman.",
                  "Compliance itu investasi jangka panjang, bukan beban."],
        "bisnis": ["Kuncinya ada di sistem. Bisnis yang sustain punya SOP yang jelas.",
                   "Delegasi itu skill. Percayakan tugas yang bisa dikerjakan orang lain.",
                   "Fokus pada 1 hal yang paling berdampak, selesaikan, baru lanjut ke berikutnya."],
        "otomotif|mobil|mesin": ["Mesin yang terawat bikin mobil lebih awet dan performa optimal.",
                                  "Ganti oli rutin itu investasi kecil dengan dampak besar buat mesin.",
                                  "Jangan tunggu rusak baru servis. Preventive maintenance lebih murah."],
        "kulit|skincare|wajah": ["Konsistensi adalah kunci dalam perawatan kulit. Gak bisa instan.",
                                  "Kenali jenis kulit Anda dulu sebelum pilih produk. Satu produk belum tentu cocok untuk semua.",
                                  "Tabir surya adalah step yang paling sering dilewatkan tapi paling penting."],
        "default": ["Makasih responnya! Banyak yang nanyain soal ini, semoga penjelasannya membantu ya.",
                    "Kalau ada yang mau ditanyakan lebih lanjut, silakan komen di bawah ya.",
                    "Saya akan bahas topik ini lebih dalam di postingan berikutnya. Stay tuned!"],
    }
    
    # Cari keyword yang cocok
    matched_key = None
    for key, replies in keywords.items():
        if key != "default" and any(kw in caption_lower for kw in key.split("|")):
            matched_key = key
            break
    
    if not matched_key:
        # Cari keyword dari kata-kata spesifik di caption
        for kata in ["data", "digital", "online", "website", "aplikasi", "teknologi", "AI", "tools",
                     "customer", "pelanggan", "klien", "tim", "sistem", "proses", "otomasi",
                     "belajar", "skill", "kursus", "ilmu", "buku"]:
            if kata in caption_lower:
                matched_key = "default"
                break
    
    if not matched_key:
        matched_key = "default"
    
    return keywords.get(matched_key, keywords["default"])


def load_tracker():
    if os.path.exists(REPLY_TRACK_FILE):
        with open(REPLY_TRACK_FILE) as f:
            return json.load(f)
    return {"replied": []}


def save_tracker(tracker):
    with open(REPLY_TRACK_FILE, 'w') as f:
        json.dump(tracker, f)


def get_posted_schedule_ids(account_id):
    """Ambil schedule yang SUDAH TAYANG (success) dan replies kosong"""
    # Coba GET /public/schedule/{id} dari beberapa ID terbaru
    # Alternatif: kita track dari log / cari via API terbaru
    # Karena gak ada endpoint list schedule, kita track dari log cron
    
    now_wib = datetime.now(WIB)
    # Cari schedule yang tayang dalam 24 jam terakhir
    
    found = []
    # Coba ambil schedule per accountId — kadang ada endpoint khusus
    for attempt in range(3):
        try:
            url = f"{BASE}/public/schedule?accountId={account_id}&page={attempt+1}&perPage=10"
            req = urllib.request.Request(url, headers=HEADERS)
            with urllib.request.urlopen(req, timeout=5) as r:
                data = json.loads(r.read())
                for doc in data.get('docs', []):
                    if doc.get('status') == 'success' and not doc.get('replies'):
                        found.append(doc)
        except:
            break
    
    return found


def reply_to_post(parent_id, account_id, reply_texts, akun_name):
    """Reply 3x ke postingan yang sudah tayang (langsung, tanpa jeda schedule)"""
    parent_data = None
    
    # Ambil detail postingan asli
    try:
        url = f"{BASE}/public/schedule/{parent_id}"
        req = urllib.request.Request(url, headers=HEADERS)
        with urllib.request.urlopen(req) as r:
            parent_data = json.loads(r.read())
    except:
        pass
    
    if not parent_data:
        return False
    
    now_utc = datetime.now(timezone.utc)
    now_str = now_utc.strftime("%Y-%m-%dT%H:%M:%S.000Z")
    
    for i, reply_text in enumerate(reply_texts):
        if len(reply_text) > 500:
            reply_text = reply_text[:497] + "..."
        
        # Reply langsung: scheduleAt = now
        payload = {
            "title": "",
            "description": reply_text,
            "topic": "",
            "type": "text",
            "medias": [],
            "meta": {"title": "", "description": "", "url": ""},
            "additionalInfo": {
                "isAiGenerated": False, "isDraft": False,
                "collaborators": [], "mentions": [],
                "music": {"id": "", "artist": "", "name": "", "thumbnail": ""},
                "products": [], "tags": []
            },
            "replies": [parent_id],
            "accountId": account_id,
            "scheduleAt": now_str,
        }
        
        body = json.dumps(payload).encode()
        req2 = urllib.request.Request(f"{BASE}/public/schedule", data=body, headers=HEADERS, method="POST")
        with urllib.request.urlopen(req2) as r2:
            result = json.loads(r2.read())
            new_id = result.get("scheduleId", result.get("_id", "?"))
            print(f"  Reply {i+1} → {new_id} ({len(reply_text)} chars)")
        
        if i < 2:  # Jeda 1 menit antar reply (kecuali yang terakhir)
            time.sleep(60)
    
    return True


def main():
    print(f"🧵 Threads Reply Cron — {datetime.now(WIB).strftime('%Y-%m-%d %H:%M WIB')}")
    print("="*60)
    
    tracker = load_tracker()
    replied_ids = set(tracker.get("replied", []))
    found_any = False
    
    for account_id, akun_name in THREADS_ACCOUNTS.items():
        print(f"\n📌 {akun_name}")
        
        # Ambil semua schedule yang udah tayang
        posts = get_posted_schedule_ids(account_id)
        
        if not posts:
            # Fallback: coba ambil dari file slot tracker atau log
            print(f"  ⏭️  Tidak ada postingan baru")
            continue
        
        for post in posts:
            pid = post.get('_id', '')
            if pid in replied_ids:
                continue
            
            desc = post.get('description', '')[:150]
            print(f"  📄 {pid} — {desc}...")
            
            # Generate reply
            replies = generate_replies(post.get('description', ''), akun_name)
            
            success = reply_to_post(pid, account_id, replies, akun_name)
            if success:
                replied_ids.add(pid)
                found_any = True
                print(f"  ✅ Berhasil reply 3x!")
    
    # Simpan tracker
    tracker["replied"] = sorted(list(replied_ids))
    save_tracker(tracker)
    
    if not found_any:
        print("\n✅ Tidak ada postingan baru yang perlu di-reply.")
    else:
        print(f"\n✅ Selesai! Total replied: {len(replied_ids)}")


if __name__ == "__main__":
    main()

