
import asyncio, csv, json, os, sys, sqlite3, time as t
from pathlib import Path

BASE_DIR   = Path("/var/www/vps2.happyuser.info/AIMA_bot")
DATASET    = "users_without_shop_202605191510"
BATCH_SIZE = 30
BATCH      = 10
TG_SESSION = BASE_DIR / "data/processed/telegram/aima_support_session"

def load_env():
    for path in [BASE_DIR / ".env"]:
        if not path.exists(): continue
        for raw in path.read_text(encoding="utf-8", errors="ignore").splitlines():
            line = raw.strip()
            if not line or line.startswith("#") or "=" not in line: continue
            k, v = line.split("=", 1)
            os.environ.setdefault(k.strip(), v.strip().strip('"').strip("'"))

def norm(v):
    return "".join(c for c in str(v or "") if c.isdigit() or c == "+")

def collect_used():
    used_leads, used_phones = set(), set()
    for p in sorted((BASE_DIR/"data/processed").glob("*.csv")):
        with p.open(encoding="utf-8-sig") as f:
            for row in csv.DictReader(f):
                lid = str(row.get("lead_id","") or "").strip()
                ph  = str(row.get("phone","")   or "").strip()
                if lid: used_leads.add(lid)
                if ph:  used_phones.add(ph)
    return used_leads, used_phones

async def screen(candidates, needed):
    load_env()
    api_id   = os.environ.get("TG_API_ID")
    api_hash = os.environ.get("TG_API_HASH")
    from telethon import TelegramClient
    from telethon.tl.functions.contacts import ImportContactsRequest
    from telethon.tl.types import InputPhoneContact
    client = TelegramClient(str(TG_SESSION), int(api_id), api_hash)
    await client.connect()
    if not await client.is_user_authorized():
        print("[error] Not authorized"); sys.exit(1)

    # Перевірити чи Premium активний
    me = await client.get_me()
    is_premium = getattr(me, "premium", False)
    print(f"[ok] Connected as {getattr(me,'first_name','')} | Premium: {is_premium}", flush=True)

    found = []
    total_direct = 0
    total_retry_ok = 0
    total_scanned = 0

    for offset in range(0, len(candidates), BATCH):
        if len(found) >= needed: break
        chunk = candidates[offset:offset+BATCH]
        req = [InputPhoneContact(client_id=offset+i+1, phone=r[3],
               first_name=r[1] or r[3][-4:], last_name=r[2] or "")
               for i,r in enumerate(chunk)]
        ts = t.time()
        result = await client(ImportContactsRequest(req))
        found_phones = {norm(getattr(u,"phone","") or "").lstrip("+") for u in result.users}
        total_direct += len(result.users)

        # retry fallback з timeout=5s (безпечно з Premium)
        retry_ids = {rc for rc in getattr(result,"retry_contacts",[])}
        cid_map   = {offset+i+1: r for i,r in enumerate(chunk)}
        for cid in retry_ids:
            if cid in cid_map and len(found) < needed:
                r = cid_map[cid]
                try:
                    await asyncio.wait_for(client.get_entity(r[3]), timeout=5.0)
                    found_phones.add(norm(r[3]).lstrip("+"))
                    total_retry_ok += 1
                except Exception:
                    pass

        for r in chunk:
            if norm(r[3]).lstrip("+") in found_phones:
                found.append(r)
                if len(found) >= needed: break

        total_scanned += len(chunk)
        print(f"[screen] scanned={total_scanned} direct={total_direct} retry_ok={total_retry_ok} found={len(found)} t={t.time()-ts:.1f}s", flush=True)

    await client.disconnect()
    print(f"[done] {len(found)} досяжних (direct={total_direct} retry_ok={total_retry_ok}, scanned={total_scanned})", flush=True)
    return found[:needed]

load_env()
conn = sqlite3.connect(str(BASE_DIR/"data/processed/aima_conversion_shadow.sqlite"))
cur  = conn.cursor()
cur.execute("SELECT lead_id, first_name, last_name, phone, registered_at, last_activity_at FROM aima_imported_contacts WHERE dataset=? ORDER BY row_index ASC", (DATASET,))
all_rows = cur.fetchall()
conn.close()
used_leads, used_phones = collect_used()
candidates = [r for r in all_rows if r[3] and str(r[0]) not in used_leads and r[3] not in used_phones]
print(f"[screen] {DATASET}: {len(candidates)} вільних кандидатів", flush=True)

found = asyncio.get_event_loop().run_until_complete(screen(candidates, BATCH_SIZE))

out_path = BASE_DIR / "data/processed/aima_screened_premium_candidates.json"
if found:
    out_path.write_text(json.dumps([
        {"lead_id":r[0],"first_name":r[1] or "","last_name":r[2] or "","phone":r[3],
         "registered_at":r[4] or "","last_activity_at":r[5] or ""}
        for r in found
    ], ensure_ascii=False, indent=2), encoding="utf-8")
    print(f"[ok] {len(found)} збережено -> {out_path.name}", flush=True)
    for r in found: print(f"  {r[3]} {r[1]} {r[2]}")
else:
    print("[warn] 0 досяжних — можливо Premium ще не активний")
    sys.exit(2)
