import html
import re


CUSTOM_EMOJI_TYPE = "custom_emoji"
TELEGRAM_CAPTION_LIMIT = 1024
HTML_TAG_RE = re.compile(r"<[^>]+>")
QRIS_BUTTON_ICON_ID = "6339136888674192137"
DANA_BUTTON_ICON_ID = "6114140572992146796"


def _utf16_offsets(text):
    offsets = [0]
    for char in text:
        offsets.append(offsets[-1] + len(char.encode("utf-16-le")) // 2)
    return offsets


def _utf16_to_py_index(offsets, utf16_offset):
    for index, offset in enumerate(offsets):
        if offset >= utf16_offset:
            return index
    return len(offsets) - 1


def text_with_custom_emoji_html(message, transform=None):
    """Convert Telegram custom emoji entities in a text message to HTML tags."""
    text = message.text or message.caption or ""
    entities = message.entities if message.text is not None else message.caption_entities
    custom_entities = [
        entity
        for entity in (entities or [])
        if getattr(entity, "type", None) == CUSTOM_EMOJI_TYPE
        and getattr(entity, "custom_emoji_id", None)
    ]

    if not custom_entities:
        return transform(text) if transform else text

    offsets = _utf16_offsets(text)
    result = []
    last_index = 0

    for entity in sorted(custom_entities, key=lambda item: item.offset):
        start_index = _utf16_to_py_index(offsets, entity.offset)
        end_index = _utf16_to_py_index(offsets, entity.offset + entity.length)
        if start_index < last_index or end_index <= start_index:
            continue

        plain_segment = text[last_index:start_index]
        result.append(transform(plain_segment) if transform else plain_segment)

        emoji_text = html.escape(text[start_index:end_index])
        emoji_id = html.escape(str(entity.custom_emoji_id), quote=True)
        result.append(f'<tg-emoji emoji-id="{emoji_id}">{emoji_text}</tg-emoji>')
        last_index = end_index

    plain_segment = text[last_index:]
    result.append(transform(plain_segment) if transform else plain_segment)
    return "".join(result)


def parse_mode_for_custom_emoji_html(text):
    return "HTML" if "<tg-emoji " in (text or "") else None


def premium_button_icon_kwargs(custom_emoji_id):
    return {"api_kwargs": {"icon_custom_emoji_id": str(custom_emoji_id)}}


def visible_text_length(text):
    return len(html.unescape(HTML_TAG_RE.sub("", text or "")))
