from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardRemove

# --- Telegram colored inline buttons (new feature) -----------------------
# Telegram now supports a "style" attribute on inline keyboard buttons with
# three values: "primary" (blue), "success" (green) and "danger" (red).
# python-telegram-bot doesn't model the field yet, so we pass it through
# `api_kwargs` which is serialized in to_dict() and sent verbatim to the API.

STYLE_PRIMARY = "primary"
STYLE_SUCCESS = "success"
STYLE_DANGER  = "danger"

# Keywords -> style. Order matters: danger first so "cancel order" still
# reads as danger and not as success.
_DANGER_HINTS = (
    "cancel", "back", "close", "exit", "delete", "remove", "reject",
    "decline", "no", "stop", "ban", "kick", "deny", "🔙", "❌", "🚫",
)
_SUCCESS_HINTS = (
    "confirm", "buy", "purchase", "pay", "approve", "accept", "yes",
    "deposit", "submit", "send", "ok", "done", "save", "verify",
    "joined", "claim", "withdraw", "✅", "💰", "💵", "💸",
)
_PRIMARY_HINTS = (
    "menu", "home", "products", "category", "orders", "support",
    "about", "referral", "wallet", "channel", "admin", "broadcast",
    "next", "prev", "page", "more", "view", "open", "edit", "add",
)


def style_for(text: str, target: str = "") -> str | None:
    """Pick a Telegram button style based on label / callback hints."""
    blob = f"{text or ''} {target or ''}".lower()
    for k in _DANGER_HINTS:
        if k in blob:
            return STYLE_DANGER
    for k in _SUCCESS_HINTS:
        if k in blob:
            return STYLE_SUCCESS
    for k in _PRIMARY_HINTS:
        if k in blob:
            return STYLE_PRIMARY
    return STYLE_PRIMARY  # default to a nice blue


# --- Emoji decoration (kept from previous version) -----------------------
_PALETTE = [
    "🟢", "🟠", "🔵", "🟣", "🔴", "🟡", "🟤", "⚪",
    "💎", "🔥", "⭐", "⚡", "🌈", "🎯", "🎨", "🚀",
]

_SERVICE_EMOJI = {
    "chatgpt": "🟢", "openai": "🟢",
    "claude": "🟠", "anthropic": "🟠",
    "gemini": "🔷", "google": "🔵",
    "grok": "⚫", "xai": "⚫",
    "netflix": "🔴", "prime": "🔵", "disney": "🏰", "hulu": "💚",
    "spotify": "🟢", "youtube": "🔴", "apple": "🍎",
    "canva": "🎨", "adobe": "🅰️", "figma": "🎨",
    "capcut": "🎬", "picsart": "🖌️", "openart": "🖼️",
    "vpn": "🛡️", "nord": "🛡️", "express": "🛡️",
    "xbox": "🎮", "play": "🎮", "steam": "🎮", "fortnite": "🎮",
    "telegram": "✈️", "discord": "💬", "linkedin": "💼",
    "gmail": "📧", "mail": "📧", "hotmail": "📧", "outlook": "📧",
    "notion": "📓", "quill": "✍️", "manus": "🧠",
    "lovable": "💗", "kling": "🎞️", "midjourney": "🎨",
    "elevenlabs": "🔊", "headspace": "🧘",
    "nitro": "💜", "dreamina": "🌠",
}


def _emoji_for(name: str, idx: int) -> str:
    n = (name or "").lower()
    for key, emo in _SERVICE_EMOJI.items():
        if key in n:
            return emo
    return _PALETTE[idx % len(_PALETTE)]


def decorate(name: str, idx: int = 0) -> str:
    if not name:
        return name
    # If admin used the {pe:ID} marker, keep it intact so the button code
    # can extract the icon — don't prepend a palette emoji.
    stripped = name.lstrip()
    if stripped.startswith("{pe:"):
        return name
    first = stripped[:1]
    if first and ord(first) > 127:
        return name
    return f"{_emoji_for(name, idx)} {name}"


# --- Button construction ------------------------------------------------
import re as _re
from utils.premium_emoji import AUTO_MAP as _PE_AUTO_MAP

# Explicit syntax in button label: "{pe:12345}🔥 Label" or "{pe:12345}Label".
# Optionally also consume the emoji that follows so it isn't shown twice
# (icon + same emoji in the text).
_PE_PREFIX_RE = _re.compile(r"^\{pe:(\d+)\}\s*([^\sA-Za-z0-9<>{}]+)?\s*")

# Match a leading emoji from AUTO_MAP (longest first)
_PE_KEYS_SORTED = sorted(_PE_AUTO_MAP.keys(), key=len, reverse=True)


def _extract_icon_emoji_id(text: str) -> tuple[str, str | None]:
    """Return (cleaned_text, custom_emoji_id_or_None).

    Supports:
      1. Explicit "{pe:ID}Label" prefix.
      2. A leading unicode emoji that exists in AUTO_MAP — its premium ID
         is attached as icon_custom_emoji_id and the emoji is stripped
         from the visible label (Telegram renders the icon separately).
    """
    if not text:
        return text, None
    m = _PE_PREFIX_RE.match(text)
    if m:
        return text[m.end():], m.group(1)
    stripped = text.lstrip()
    for key in _PE_KEYS_SORTED:
        if stripped.startswith(key):
            rest = stripped[len(key):].lstrip()
            return rest, _PE_AUTO_MAP[key]
    return text, None


def _btn(text: str, target: str, style: str | None = None) -> InlineKeyboardButton:
    is_url = isinstance(target, str) and (
        target.startswith("http://") or target.startswith("https://") or target.startswith("tg://")
    )
    chosen = style or style_for(text, "" if is_url else target)
    clean_text, icon_id = _extract_icon_emoji_id(text)
    api_kwargs: dict = {}
    if chosen:
        api_kwargs["style"] = chosen
    if icon_id:
        api_kwargs["icon_custom_emoji_id"] = icon_id
    api_kwargs = api_kwargs or None
    if is_url:
        return InlineKeyboardButton(clean_text or text, url=target, api_kwargs=api_kwargs)
    return InlineKeyboardButton(clean_text or text, callback_data=target, api_kwargs=api_kwargs)


def inline(rows) -> InlineKeyboardMarkup:
    """Build an inline keyboard.

    Each cell may be (text, target) or (text, target, style).
    """
    built = []
    for row in rows:
        built_row = []
        for cell in row:
            if len(cell) == 3:
                t, c, s = cell
            else:
                t, c = cell
                s = None
            built_row.append(_btn(t, c, s))
        built.append(built_row)
    return InlineKeyboardMarkup(built)



def remove_reply_kb() -> ReplyKeyboardRemove:
    return ReplyKeyboardRemove()


def main_menu_inline(channel_link: str | None = None) -> InlineKeyboardMarkup:
    rows = [
        [("🛍️ Products", "menu:products", STYLE_SUCCESS),
         ("💎 Deposit",  "menu:deposit",  STYLE_PRIMARY)],
        [("🎁 Referrals", "menu:referrals", STYLE_SUCCESS),
         ("📦 My Orders", "menu:orders",    STYLE_PRIMARY)],
        [("💬 Support", "menu:support", STYLE_PRIMARY),
         ("🌟 About",   "menu:about",   STYLE_PRIMARY)],
    ]
    if channel_link:
        rows.append([("📢 Join Our Channel", channel_link, STYLE_SUCCESS)])
    return inline(rows)


def back_kb(callback="menu:home") -> InlineKeyboardMarkup:
    return inline([[("🔙 Back to Menu", callback, STYLE_DANGER)]])
