#!/usr/bin/env python3
"""Backfill thread_ids into existing engagers.json + new_followers.json.

Logs into IG via Chrome cookies, calls direct_thread_by_participants for each
handle, and writes the resolved thread_id back to the JSON. This is a READ
operation; it does NOT create new threads.
"""
import json
import time
from pathlib import Path
from urllib.parse import unquote

import rookiepy
from instagrapi import Client

BASE = Path("/Users/daichi/keith-dm-scanner")
ENG  = BASE / "engagers.json"
NF   = BASE / "new_followers.json"
DELAY = 1.0

SESSION = BASE / "session.json"
cl = Client()
cl.delay_range = [DELAY, DELAY + 0.5]
try:
    print("logging in via saved session.json...", flush=True)
    cl.load_settings(SESSION)
    cl.get_timeline_feed()  # verify session is alive
except Exception as e:
    print(f"session.json failed ({e}), trying chrome cookies", flush=True)
    cookies = rookiepy.chrome(domains=["instagram.com"])
    session_id = unquote({c["name"]: c["value"] for c in cookies}["sessionid"])
    cl.login_by_sessionid(session_id)
    cl.dump_settings(SESSION)
print(f"logged in as {cl.account_info().username}", flush=True)


def resolve(handle: str) -> str:
    h = handle.lstrip("@")
    if not h:
        return ""
    try:
        uid = cl.user_info_by_username_v1(h).pk
        t = cl.direct_thread_by_participants([int(uid)])
        if isinstance(t, dict):
            obj = t.get("thread") or {}
            return str(obj.get("thread_id") or "")
    except Exception as e:
        print(f"  err {handle}: {e}", flush=True)
    return ""


def enrich(path: Path, list_key: str, label: str):
    if not path.exists():
        print(f"{label}: {path} not found, skipping")
        return
    data = json.loads(path.read_text())
    items = data.get(list_key, [])
    print(f"\n{label}: {len(items)} items", flush=True)
    resolved = 0
    for i, item in enumerate(items, 1):
        if item.get("thread_id"):
            continue
        h = item.get("handle", "")
        tid = resolve(h)
        if tid:
            item["thread_id"] = tid
            resolved += 1
            print(f"  [{i}/{len(items)}] {h}: thread_id={tid}", flush=True)
        else:
            print(f"  [{i}/{len(items)}] {h}: no thread", flush=True)
        time.sleep(DELAY)
        # save incrementally every 10 items so we never lose progress
        if i % 10 == 0:
            path.write_text(json.dumps(data, indent=2, ensure_ascii=False))
    path.write_text(json.dumps(data, indent=2, ensure_ascii=False))
    print(f"{label}: resolved {resolved}/{len(items)} new thread_ids", flush=True)


enrich(ENG, "engagers", "engagers.json")
enrich(NF, "followers", "new_followers.json")
print("\ndone.", flush=True)
