"""Shared helpers for the tg_* CLI scripts (read/send/search/inbox)."""
from __future__ import annotations

import sys
from datetime import datetime, timezone
from typing import Iterable

from telethon import TelegramClient


async def resolve_chat(client: TelegramClient, ref: str):
    """Resolve a chat reference to a Telethon entity.

    Accepts:
      - "@username" or "username" (with leading '+' for invite phone-number)
      - numeric id (positive or negative; large negative for supergroups)
      - case-insensitive name substring; errors if 0 or >1 matches
    """
    ref = ref.strip()

    if ref.startswith("@") or ref.startswith("+"):
        return await client.get_entity(ref)

    try:
        return await client.get_entity(int(ref))
    except ValueError:
        pass

    needle = ref.lower()
    matches = []
    async for d in client.iter_dialogs(archived=None):
        if needle in (d.name or "").lower():
            matches.append(d)

    if not matches:
        sys.exit(f"chat not found: {ref!r}")
    if len(matches) > 1:
        preview = "\n  ".join(f"{d.id:>15}  {d.name}" for d in matches[:10])
        more = "" if len(matches) <= 10 else f"\n  ... +{len(matches)-10} more"
        sys.exit(
            f"ambiguous chat {ref!r} ({len(matches)} matches):\n  "
            f"{preview}{more}\nuse the numeric id or @username"
        )
    return matches[0].entity


def parse_date(s: str) -> datetime:
    """Parse YYYY-MM-DD or full ISO into UTC-aware datetime."""
    if "T" in s or " " in s:
        dt = datetime.fromisoformat(s.replace("Z", "+00:00"))
    else:
        dt = datetime.strptime(s, "%Y-%m-%d")
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    return dt


def fmt_msg(msg, max_chars: int = 200) -> str:
    """Compact one-line representation of a Telethon Message."""
    sender = ""
    if getattr(msg, "sender", None) is not None:
        sender = (
            getattr(msg.sender, "username", None)
            or getattr(msg.sender, "first_name", None)
            or getattr(msg.sender, "title", None)
            or str(msg.sender_id)
        )
    elif msg.sender_id:
        sender = str(msg.sender_id)

    text = (msg.message or "").replace("\n", " ⏎ ")
    if len(text) > max_chars:
        text = text[: max_chars - 1] + "…"
    media = ""
    if msg.media and not msg.message:
        media = f" [media:{type(msg.media).__name__}]"
    return f"{msg.id:>9} │ {msg.date.strftime('%Y-%m-%d %H:%M')} │ {sender[:20]:<20} │ {text}{media}"


def confirm(prompt: str = "Onayla", default: bool = False) -> bool:
    """Interactive y/N. default=False → [y/N], default=True → [Y/n]."""
    suffix = " [Y/n]: " if default else " [y/N]: "
    try:
        r = input(prompt + suffix).strip().lower()
    except EOFError:
        return default
    if not r:
        return default
    return r in ("y", "yes", "evet", "e", "ok")


def chunked(items: Iterable, size: int):
    buf = []
    for x in items:
        buf.append(x)
        if len(buf) == size:
            yield buf
            buf = []
    if buf:
        yield buf
