"""Single-call typed Telegram text-edit transport."""

from __future__ import annotations

from dataclasses import dataclass
from enum import StrEnum
from typing import TYPE_CHECKING, Protocol

if TYPE_CHECKING:
    from telegram import Message


class TelegramTextEditor(Protocol):
    async def edit_message_text(
        self, *, chat_id: int, message_id: int, text: str,
    ) -> Message | bool: ...


class TelegramEditKnownReason(StrEnum):
    REJECTED = "rejected"


class TelegramEditUnknownReason(StrEnum):
    CONNECTION_LOST = "connection_lost"
    TIMEOUT = "timeout"


@dataclass(frozen=True, slots=True)
class TelegramEditDelivered:
    message_id: str


@dataclass(frozen=True, slots=True)
class TelegramEditKnownFailure:
    reason: TelegramEditKnownReason


@dataclass(frozen=True, slots=True)
class TelegramEditUnknown:
    reason: TelegramEditUnknownReason


TelegramEditOutcome = (
    TelegramEditDelivered | TelegramEditKnownFailure | TelegramEditUnknown
)


async def edit_telegram_text(
    editor: TelegramTextEditor,
    *,
    chat_id: str,
    message_id: str,
    text: str,
) -> TelegramEditOutcome:
    """Call Telegram exactly once and classify its durable edit outcome."""
    try:
        _ = await editor.edit_message_text(
            chat_id=int(chat_id), message_id=int(message_id), text=text,
        )
    except Exception as error:
        error_kinds = {kind.__name__ for kind in type(error).__mro__}
        if "BadRequest" in error_kinds:
            if "not modified" in str(error).casefold():
                return TelegramEditDelivered(message_id)
            return TelegramEditKnownFailure(TelegramEditKnownReason.REJECTED)
        if "TimedOut" in error_kinds:
            return TelegramEditUnknown(TelegramEditUnknownReason.TIMEOUT)
        if error_kinds & {"NetworkError", "TelegramError"}:
            return TelegramEditUnknown(TelegramEditUnknownReason.CONNECTION_LOST)
        raise
    return TelegramEditDelivered(message_id)
