#!/usr/bin/env python3
"""Verifikasi satu slot carousel feed IG StudioSoft (default 08:30 WIB).

Pakai: python3 verif_car10_slot.py 2026-10-17
Read-only: baca jadwal dari API, cek caption + media 200 di KEDUA ingress funnel.
"""
import json
import sys
import re
import subprocess
from concurrent.futures import ThreadPoolExecutor

import repliz_client as rc

ACC_IG_SS = "6a38ac33c5ff4ce3a3231232"
INGRESS = ["103.84.155.153", "103.84.155.217"]
HOST = "mantapserver.tail3947bb.ts.net"
CJK = re.compile(r"[\u3000-\u9fff\uff00-\uffef\u3040-\u30ff\uac00-\ud7af]")
CTA = re.compile(r"komentar|diskusi|pendapat|tulis di|menurut anda|menurut kamu|share", re.I)


def ambil_semua(client):
    out, page = [], 1
    while True:
        r = client.get_schedules(page=page, limit=100)
        docs = r.get("docs") or r.get("data") or []
        if not docs:
            break
        out.extend(docs)
        if len(docs) < 100 or len(out) >= (r.get("totalDocs") or 0):
            break
        page += 1
    return out


def cek_url(url, ip):
    try:
        p = subprocess.run(
            ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", "--max-time", "25",
             "--resolve", f"{HOST}:443:{ip}", url],
            capture_output=True, text=True, timeout=40)
        return p.stdout.strip() or "000"
    except Exception:
        return "ERR"


def main():
    tgl = sys.argv[1] if len(sys.argv) > 1 else None
    if not tgl:
        print("pakai: python3 verif_car10_slot.py YYYY-MM-DD")
        return 2
    client = rc.get_client()
    semua = ambil_semua(client)
    target = f"{tgl}T01:30:00.000Z"
    kandidat = [s for s in semua
                if s.get("accountId") == ACC_IG_SS
                and str(s.get("scheduleAt", ""))[:16] == target[:16]
                and s.get("type") == "album"]
    print(f"total jadwal dibaca: {len(semua)}")
    if not kandidat:
        print(f"❌ TIDAK ada album IG SS di slot {tgl} 08:30 WIB")
        return 1
    for s in kandidat:
        medias = s.get("medias") or []
        desc = s.get("description") or ""
        urls = [m.get("url") for m in medias if isinstance(m, dict) and m.get("url")]
        hasil = {}
        with ThreadPoolExecutor(max_workers=10) as ex:
            for ip in INGRESS:
                hasil[ip] = list(ex.map(lambda u: cek_url(u, ip), urls))
        print(f"id       : {s.get('_id')}")
        print(f"judul    : {s.get('title')}")
        print(f"akun     : {(s.get('account') or {}).get('name')}")
        print(f"status   : {s.get('status')}  | scheduleAt: {s.get('scheduleAt')}")
        print(f"tipe     : {s.get('type')} | medias: {len(medias)} | replies: {len(s.get('replies') or [])}")
        for ip in INGRESS:
            bad = [u for u, c in zip(urls, hasil[ip]) if c != "200"]
            print(f"ingress {ip}: {'✅ semua 200' if not bad else '❌ ' + str(bad[:4])}")
        print(f"media[0] : {urls[0] if urls else '-'}")
        print(f"media[-1]: {urls[-1] if urls else '-'}")
        tags = re.findall(r"#(\w+)", desc)
        print(f"caption  : {len(desc)} char | hashtag {tags} | besar={[t for t in tags if t != t.lower()]}")
        print(f"link     : {re.findall(r'https?://[^ ]+', desc)}")
        print(f"CTA      : {'✅' if CTA.search(desc[-200:]) else '❌ TIDAK ADA di 200 char terakhir'}")
        sebut = re.findall(r"@[\w.]+", desc)
        print(f"CJK      : {'❌ ADA' if CJK.search(desc) else '✅ bersih'} | mention: {sebut}")
        print("--- caption ---")
        print(desc)
        print("--- akhir caption ---")
    return 0


if __name__ == "__main__":
    sys.exit(main())
