"""Telegram ingestion via Telethon (MTProto).

This logs in as the real user account, not a bot — the Bot API cannot read
personal DMs, so there is no bot-shaped way to do this (see docs/project-plan.md
Phase 12 step 4). It runs strictly non-interactively: the session file at
TELEGRAM_SESSION_PATH must already exist, created once by hand with
`python ingest/telegram_login.py`. If it doesn't, or it has been invalidated,
this module warns and returns nothing rather than blocking a scheduled run on a
phone-code prompt nobody is there to answer.

Reading messages does not acknowledge them — Telethon only marks a chat read on
an explicit `send_read_acknowledge()`, which is never called here.
"""

import asyncio
import logging
import os
from datetime import datetime, timedelta, timezone

LOG = logging.getLogger(__name__)

MAX_BODY_CHARS = 2000
DEFAULT_SESSION_PATH = "/data/telegram.session"


def _session_path():
    return os.environ.get("TELEGRAM_SESSION_PATH", DEFAULT_SESSION_PATH)


async def _fetch_async(lookback_hours, api_id, api_hash, max_dialogs, max_per_dialog):
    from telethon import TelegramClient

    since = datetime.now(timezone.utc) - timedelta(hours=lookback_hours)
    messages = []

    client = TelegramClient(_session_path(), api_id, api_hash)
    await client.connect()
    try:
        if not await client.is_user_authorized():
            LOG.warning(
                "telegram: session at %s is not authorized — run `python ingest/telegram_login.py` once",
                _session_path(),
            )
            return []

        async for dialog in client.iter_dialogs(limit=max_dialogs):
            try:
                async for message in client.iter_messages(dialog.entity, limit=max_per_dialog):
                    if message.date is None or message.date < since:
                        break
                    if not message.message:
                        continue
                    sender = await message.get_sender()
                    sender_name = getattr(sender, "username", None) or getattr(
                        sender, "first_name", None
                    )
                    messages.append(
                        {
                            "source": "telegram",
                            "chat": dialog.name,
                            "from": sender_name or "unknown",
                            "outgoing": bool(message.out),
                            "timestamp": message.date.isoformat(),
                            "body": message.message[:MAX_BODY_CHARS],
                        }
                    )
            except Exception:
                LOG.warning("telegram: could not read dialog %r, skipping", dialog.name, exc_info=True)
    finally:
        await client.disconnect()

    return messages


def fetch(lookback_hours):
    api_id = os.environ.get("TELEGRAM_API_ID", "").strip()
    api_hash = os.environ.get("TELEGRAM_API_HASH", "").strip()
    max_dialogs = int(os.environ.get("TELEGRAM_MAX_DIALOGS", "25"))
    max_per_dialog = int(os.environ.get("TELEGRAM_MAX_MESSAGES_PER_DIALOG", "50"))

    if not (api_id and api_hash):
        LOG.warning("telegram: TELEGRAM_API_ID/TELEGRAM_API_HASH not set, skipping")
        return []

    if not os.path.exists(_session_path()):
        LOG.warning(
            "telegram: no session file at %s — run `python ingest/telegram_login.py` once, skipping",
            _session_path(),
        )
        return []

    try:
        messages = asyncio.run(
            _fetch_async(lookback_hours, int(api_id), api_hash, max_dialogs, max_per_dialog)
        )
    except Exception:
        LOG.warning("telegram: ingestion failed, returning nothing", exc_info=True)
        return []

    LOG.info("telegram: %d message(s) in the last %sh", len(messages), lookback_hours)
    return messages
