#!/usr/bin/env python3
"""Hitung stok artikel studiosoft.id yang LIVE dan BELUM dipakai di Threads."""
import re, glob, json, ssl, urllib.request, urllib.error, concurrent.futures

def extract_links(path):
    txt = open(path, encoding='utf-8', errors='ignore').read()
    return set(re.findall(r'https?://(?:www\.)?studiosoft\.id/[A-Za-z0-9_\-/]+', txt))

def norm(u):
    return u.rstrip('/')

avail = set()
for f in ['daftar_artikel_fb_unused.md', 'artikel-healthcare-studiosoft.md']:
    try:
        avail |= extract_links(f)
    except Exception:
        pass
for f in glob.glob('*.py'):
    try:
        avail |= extract_links(f)
    except Exception:
        pass
avail = {norm(u) for u in avail if 'studiosoft.id/' in u}
print(f'stok unik dari file: {len(avail)}')

# 72 link yang sudah dipakai di Threads (hasil query API sebelumnya)
used_raw = set()
try:
    import subprocess
    out = subprocess.run(['python3', '-c', '''
import sys, json, re; sys.path.insert(0,".")
from repliz_client import get_client
c = get_client()
used = set()
for accid in ("6a334e89c5ff4ce3a3225a48","6a335b9ec5ff4ce3a3225c2a"):
    for p in range(1, 80):
        r = c.get_schedules(page=p, limit=100)
        for d in r["docs"]:
            if d.get("accountId")==accid:
                desc = d.get("description") or ""
                for m in re.finditer(r"https?://(?:www\\.)?studiosoft\\.id/\\S+", desc):
                    used.add(m.group(0).rstrip(".,;!?)"))
print(json.dumps(sorted(used)))
'''], capture_output=True, text=True, timeout=120)
    used_raw = set(json.loads(out.stdout.strip()))
except Exception as e:
    print('  (gagal ambil used dari API, pakai kosong):', e)
used = {norm(u) for u in used_raw}
print(f'sudah dipakai di Threads: {len(used)}')

# cek live — parallel
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

def chk(u):
    try:
        req = urllib.request.Request(u, headers={'User-Agent': 'Mozilla/5.0'})
        with urllib.request.urlopen(req, timeout=20, context=ctx) as r:
            return u, r.status
    except urllib.error.HTTPError as e:
        return u, e.code
    except Exception as e:
        return u, f'ERR:{type(e).__name__}'

candidates = avail - used
print(f'kandidat (belum dipakai): {len(candidates)} — cek HTTP...')
live, dead = [], []
with concurrent.futures.ThreadPoolExecutor(max_workers=16) as ex:
    for u, s in ex.map(chk, sorted(candidates)):
        (live if s == 200 else dead).append((u, s))

print(f'✅ LIVE & belum dipakai Threads: {len(live)}')
print(f'❌ mati/error: {len(dead)}')
for u, s in dead[:8]:
    print(f'   {s} {u}')
with open('/tmp/ss_threads_stock.json', 'w') as f:
    json.dump({'live': [u for u, _ in live], 'dead': [[u, str(s)] for u, s in dead], 'used': sorted(used)}, f, indent=1, ensure_ascii=False)
print('disimpan: /tmp/ss_threads_stock.json')
