#!/usr/bin/env python3
"""List Telegram dialogs with activity in the last N minutes (default 60).

"Activity" = the dialog's top (latest) message timestamp >= now - N minutes.
This is a read-only GetDialogs call.

Usage:
  .venv/bin/python scripts/tg_recent_dialogs.py [--minutes 60]
"""
import argparse
import asyncio
import sys
import time
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent))
from tg_session_load import ENV_FILE, SESSION_DIR, SESSION_NAME, load_dotenv


async def list_recent(minutes: int) -> None:
    import os
    from pyrogram import Client
    from pyrogram.raw import functions, types

    load_dotenv(str(ENV_FILE))
    api_id = int(os.environ["TG_API_ID"])
    api_hash = os.environ["TG_API_HASH"]

    app = Client(name=SESSION_NAME, api_id=api_id, api_hash=api_hash,
                 workdir=str(SESSION_DIR))
    cutoff = int(time.time()) - minutes * 60

    await app.start()
    try:
        # Pull dialogs; resolve users/chats from the raw response so we get titles.
        offset_date = 0
        offset_id = 0
        offset_peer = types.InputPeerEmpty()
        seen = set()
        rows = []
        while True:
            r = await app.invoke(functions.messages.GetDialogs(
                offset_date=offset_date, offset_id=offset_id,
                offset_peer=offset_peer, limit=200, hash=0))
            dialogs = getattr(r, "dialogs", []) or []
            if not dialogs:
                break
            users = {u.id: u for u in (getattr(r, "users", []) or [])}
            chats = {c.id: c for c in (getattr(r, "chats", []) or [])}
            msgs = {m.id: m for m in (getattr(r, "messages", []) or [])}

            for d in dialogs:
                peer = d.peer
                top = getattr(d, "top_message", None)
                m = msgs.get(top) if top else None
                date = getattr(m, "date", None) if m else None
                if not date or date < cutoff:
                    continue
                key = None
                title = None
                kind = None
                if isinstance(peer, types.PeerUser):
                    u = users.get(peer.user_id)
                    key = ("user", peer.user_id)
                    kind = "user"
                    if u:
                        title = " ".join(filter(None, [u.first_name, u.last_name])) or (u.username or str(u.id))
                elif isinstance(peer, types.PeerChat):
                    c = chats.get(peer.chat_id)
                    key = ("chat", peer.chat_id)
                    kind = "group"
                    title = c.title if c else str(peer.chat_id)
                elif isinstance(peer, types.PeerChannel):
                    c = chats.get(peer.channel_id)
                    key = ("channel", peer.channel_id)
                    kind = "channel/supergroup"
                    title = c.title if c else str(peer.channel_id)
                if not key or key in seen:
                    continue
                seen.add(key)
                rows.append((date, kind, title))

            # pagination: only DialogsSlice carries a count; plain Dialogs is done
            if not isinstance(r, types.messages.DialogsSlice):
                break
            # next offset from last dialog
            last = dialogs[-1]
            offset_id = last.top_message
            last_msg = msgs.get(offset_id)
            if last_msg is None:
                break
            offset_date = last_msg.date
            peer = last.peer
            if isinstance(peer, types.PeerUser):
                u = users.get(peer.user_id)
                if not u:
                    break
                offset_peer = types.InputPeerUser(user_id=u.id, access_hash=u.access_hash)
            elif isinstance(peer, types.PeerChat):
                offset_peer = types.InputPeerChat(chat_id=peer.chat_id)
            else:
                c = chats.get(peer.channel_id)
                if not c:
                    break
                offset_peer = types.InputPeerChannel(channel_id=c.id, access_hash=c.access_hash)

        rows.sort(reverse=True)
        for date, kind, title in rows:
            ts = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(date))
            print(f"{ts}  [{kind}]  {title}")
        print(f"\n[i] {len(rows)} dialog(s) with top-message activity in last {minutes} min",
              file=sys.stderr)
    finally:
        await app.stop()


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--minutes", type=int, default=60)
    args = ap.parse_args()
    asyncio.run(list_recent(args.minutes))


if __name__ == "__main__":
    main()
