"""Read recent text posts from one public channel. No outgoing messages.
Python 3.10+, Telethon==1.45.0. Run: python telegram_reader.py todo2go --limit 30
"""
import argparse
import asyncio
import getpass
import json
import os
import re
from datetime import datetime, timedelta, timezone
from pathlib import Path
from telethon import TelegramClient, errors


def select_recent(messages, channel, cutoff):
    rows = []
    for message in messages:
        if message.date < cutoff:
            break
        if message.text:
            rows.append({"id": f"{channel}:{message.id}", "date": message.date.isoformat(),
                         "text": message.text, "url": f"https://t.me/{channel}/{message.id}"})
    return rows


async def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("channel", help="Public channel username, no URL")
    parser.add_argument("--limit", type=int, default=30)
    args = parser.parse_args()
    channel = args.channel.lstrip('@')
    if not re.fullmatch(r'[A-Za-z][A-Za-z0-9_]{3,31}', channel):
        parser.error('Use a public channel username, not a URL or private invite.')
    if not 1 <= args.limit <= 1000:
        parser.error('--limit must be between 1 and 1000')
    os.umask(0o077)
    api_id = int(os.environ.get('TELEGRAM_API_ID') or input('API ID: '))
    api_hash = os.environ.get('TELEGRAM_API_HASH') or getpass.getpass('API hash: ')
    client = TelegramClient('reader', api_id, api_hash, flood_sleep_threshold=0)
    cutoff = datetime.now(timezone.utc) - timedelta(hours=24)
    try:
        async with client:
            messages = []
            async for message in client.iter_messages(channel, limit=args.limit):
                messages.append(message)
                if message.date < cutoff:
                    break
            rows = select_recent(messages, channel, cutoff)
            path = Path('messages.jsonl')
            path.write_text(''.join(json.dumps(row, ensure_ascii=False) + '\n' for row in rows), encoding='utf-8')
            print(f'Saved {len(rows)} text posts to {path}. Scanned at most {args.limit} messages.')
    except errors.FloodWaitError as exc:
        print(f'Telegram requested a pause. Retry no sooner than {exc.seconds} seconds.')
        raise SystemExit(1)


if __name__ == '__main__':
    asyncio.run(main())
