import inspect
import itertools
import json
import logging
import os
import random
import re
from datetime import datetime, time as dt_time
from zoneinfo import ZoneInfo

try:
    import httpx
    HAS_HTTPX = True
except ImportError:
    HAS_HTTPX = False
    logging.warning("httpx یافت نشد. نصب کن: pip install httpx")

try:
    import jdatetime
    HAS_JDATETIME = True
except ImportError:
    HAS_JDATETIME = False

from telegram import (
    InlineKeyboardButton,
    InlineKeyboardMarkup,
    KeyboardButton,
    ReplyKeyboardMarkup,
    ReplyKeyboardRemove,
    Update,
)
from telegram.error import TelegramError
from telegram.ext import (
    Application,
    CallbackQueryHandler,
    CommandHandler,
    ContextTypes,
    MessageHandler,
    filters,
)

logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    level=logging.INFO,
)

BOT_TOKEN = "8635522990:AAGSIetl5hcykXJn_Zhj9di-VWj65HKJhvg"
ADMIN_CHAT_ID = 718384796
ADMIN_IDS: set = {ADMIN_CHAT_ID}

REQUIRED_CHANNEL = "ch_BlackStars"
REPORTS_CHANNEL = "ch_BlackStars"
BOT_USERNAME = "BlackGiftStars_bot"

PREMIUM_EMOJI_IDS = {
    "✅": "REPLACE_WITH_ID",
    "🔙": "REPLACE_WITH_ID",
    "❌": "REPLACE_WITH_ID",
    "💰": "REPLACE_WITH_ID",
    "🎁": "REPLACE_WITH_ID",
    "⭐": "REPLACE_WITH_ID",
    "✏": "REPLACE_WITH_ID",
    "📎": "REPLACE_WITH_ID",
    "👤": "REPLACE_WITH_ID",
    "💳": "REPLACE_WITH_ID",
    "💎": "REPLACE_WITH_ID",
    "🔢": "REPLACE_WITH_ID",
    "💬": "REPLACE_WITH_ID",
    "👥": "REPLACE_WITH_ID",
    "💫": "REPLACE_WITH_ID",
    "🚀": "REPLACE_WITH_ID",
    "☝": "REPLACE_WITH_ID",
    "📢": "REPLACE_WITH_ID",
    "⚠": "REPLACE_WITH_ID",
    "🛒": "REPLACE_WITH_ID",
    "📈": "REPLACE_WITH_ID",
    "💱": "REPLACE_WITH_ID",
    "💸": "REPLACE_WITH_ID",
    "🙏": "REPLACE_WITH_ID",
    "🔓": "REPLACE_WITH_ID",
    "📱": "REPLACE_WITH_ID",
    "🎀": "REPLACE_WITH_ID",
    "🎉": "REPLACE_WITH_ID",
    "🌟": "REPLACE_WITH_ID",
    "💡": "REPLACE_WITH_ID",
    "🧾": "REPLACE_WITH_ID",
    "🏷": "REPLACE_WITH_ID",
    "⚡": "REPLACE_WITH_ID",
    "📦": "REPLACE_WITH_ID",
    "🏦": "REPLACE_WITH_ID",
    "🚫": "REPLACE_WITH_ID",
    "🔑": "REPLACE_WITH_ID",
    "😊": "REPLACE_WITH_ID",
    "❗": "REPLACE_WITH_ID",
    "➕": "REPLACE_WITH_ID",
    "🧸": "REPLACE_WITH_ID",
    "🍾": "REPLACE_WITH_ID",
    "✍": "REPLACE_WITH_ID",
    "📊": "REPLACE_WITH_ID",
    "💼": "REPLACE_WITH_ID",
    "⛏": "REPLACE_WITH_ID",
    "🛠": "REPLACE_WITH_ID",
    "🔹": "REPLACE_WITH_ID",
    "🏅": "REPLACE_WITH_ID",
    "✨": "REPLACE_WITH_ID",
    "📥": "REPLACE_WITH_ID",
    "🔒": "REPLACE_WITH_ID",
    "🛍": "REPLACE_WITH_ID",
    "👇": "REPLACE_WITH_ID",
    "‼": "REPLACE_WITH_ID",
    "📨": "REPLACE_WITH_ID",
    "🔴": "REPLACE_WITH_ID",
    "🔗": "REPLACE_WITH_ID",
    "💵": "REPLACE_WITH_ID",
    "🤖": "REPLACE_WITH_ID",
    "🖼": "REPLACE_WITH_ID",
    "🔔": "REPLACE_WITH_ID",
    "🔸": "REPLACE_WITH_ID",
    "📝": "REPLACE_WITH_ID",
    "✔": "REPLACE_WITH_ID",
    "📣": "REPLACE_WITH_ID",
    "🎭": "REPLACE_WITH_ID",
    "📞": "REPLACE_WITH_ID",
    "📑": "REPLACE_WITH_ID",
    "🔮": "REPLACE_WITH_ID",
    "✓": "REPLACE_WITH_ID",
    "🟢": "REPLACE_WITH_ID",
    "⚙": "REPLACE_WITH_ID",
    "🪜": "REPLACE_WITH_ID",
    "😎": "REPLACE_WITH_ID",
    "👑": "REPLACE_WITH_ID",
    "⛔": "REPLACE_WITH_ID",
    "💗": "REPLACE_WITH_ID",
    "🌹": "REPLACE_WITH_ID",
    "🏆": "REPLACE_WITH_ID",
    "💐": "REPLACE_WITH_ID",
    "🎂": "REPLACE_WITH_ID",
    "💍": "REPLACE_WITH_ID",
    "💝": "REPLACE_WITH_ID",
    "🐻": "REPLACE_WITH_ID",
    "🎪": "REPLACE_WITH_ID",
    "🎅": "REPLACE_WITH_ID",
    "🍀": "REPLACE_WITH_ID",
    "🌱": "REPLACE_WITH_ID",
    "🫶": "REPLACE_WITH_ID",
    "🟪": "REPLACE_WITH_ID",
    "📂": "REPLACE_WITH_ID",
    "👨": "REPLACE_WITH_ID",
    "🎨": "REPLACE_WITH_ID",
    "🛡": "REPLACE_WITH_ID",
    "👎": "REPLACE_WITH_ID",
    "📌": "REPLACE_WITH_ID",
    "👾": "REPLACE_WITH_ID",
    "🔍": "REPLACE_WITH_ID",
    "❤": "REPLACE_WITH_ID",
    "💙": "REPLACE_WITH_ID",
    "💠": "REPLACE_WITH_ID",
    "👀": "REPLACE_WITH_ID",
    "🗓": "REPLACE_WITH_ID",
    "🔥": "REPLACE_WITH_ID",
    "🪪": "REPLACE_WITH_ID",
    "🎋": "REPLACE_WITH_ID",
    "🏠": "REPLACE_WITH_ID",
    "✕": "REPLACE_WITH_ID",
    "📤": "REPLACE_WITH_ID",
    "🙈": "REPLACE_WITH_ID",
    "🗑": "REPLACE_WITH_ID",
    "📋": "REPLACE_WITH_ID",
    "➖": "REPLACE_WITH_ID",
    "♻": "REPLACE_WITH_ID",
    "🔄": "REPLACE_WITH_ID",
    "📩": "REPLACE_WITH_ID",
    "📷": "REPLACE_WITH_ID",
}

try:
    DATA_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "giftix_data.json")
except NameError:
    DATA_FILE = os.path.join(os.path.expanduser("~"), "giftix_data.json")

CARD_NUMBER = "6219861852196764"
CARD_HOLDER = "یاسین میرزایی"

TON_PRICE = 298225
MIN_TON = 0.1

PREMIUM_PRICES = {
    "3": 1750000,
    "6": 2841000,
    "12": 4950000,
}

DAILY_LIMIT = 900000
BANK_VERIFY_LIMIT_BONUS = 3000000

try:
    TEHRAN_TZ = ZoneInfo("Asia/Tehran")
except Exception:
    from datetime import timezone, timedelta
    logging.warning(
        "دیتابیس tzdata پیدا نشد؛ از افست ثابت +03:30 استفاده می‌شه. "
        "برای دقت کامل (با احتساب تغییر ساعت رسمی احتمالی) نصب کن: pip install tzdata"
    )
    TEHRAN_TZ = timezone(timedelta(hours=3, minutes=30))

REFERRAL_COMMISSION_PERCENT = 5
REFERRAL_SIGNUP_BONUS = 1000
REFERRAL_POINTS_REQUIRED = 7
REFERRAL_REWARD_GIFTS = ["teddy", "heart"]

STARS_PRICE = 2847
STARS_MIN = 50

GIFT_STAR_PRICE = 3514

BASE_TON_PRICE    = 298225
BASE_STARS_PRICE  = 2637
BASE_PREMIUM_PRICES = {"3": 1577000, "6": 2560000, "12": 4460000}

PROFIT_PERCENT = {
    "ton":      10,
    "stars":     8,
    "gift":     21,
    "premium":  11,
}

TON_PRICE_API_URL = "https://api.nobitex.ir/market/stats?srcCurrency=ton&dstCurrency=rls"
USD_TOMAN_API_URL = "https://api.nobitex.ir/market/stats?srcCurrency=usdt&dstCurrency=rls"

STAR_USD_PRICE = 0.014
PREMIUM_USD_PRICES = {"3": 13.99, "6": 24.99, "12": 44.99}

def recalc_prices() -> None:
    global STARS_PRICE, GIFT_STAR_PRICE, TON_PRICE
    STARS_PRICE   = round(BASE_STARS_PRICE * (1 + PROFIT_PERCENT["stars"] / 100))
    GIFT_STAR_PRICE = round(BASE_STARS_PRICE * (1 + PROFIT_PERCENT["gift"] / 100))
    TON_PRICE     = round(BASE_TON_PRICE * (1 + PROFIT_PERCENT["ton"] / 100))
    for plan, base in BASE_PREMIUM_PRICES.items():
        PREMIUM_PRICES[plan] = round(base * (1 + PROFIT_PERCENT["premium"] / 100))

    for key, g in GIFTS.items():
        g["price"] = round(g["stars"] * GIFT_STAR_PRICE)

GIFTS = {
    "teddy":        {"name": "تدی",          "emoji": "🧸",  "stars": 15},
    "heart":        {"name": "قلب",          "emoji": "💗",  "stars": 15},
    "rose":         {"name": "گل رز",        "emoji": "🌹",  "stars": 25},
    "kado":         {"name": "کادو",         "emoji": "🎁",  "stars": 25},
    "rocket":       {"name": "سفینه",        "emoji": "🚀",  "stars": 50},
    "trophy":       {"name": "جام",          "emoji": "🏆",  "stars": 100},
    "champagne":    {"name": "شامپاین",      "emoji": "🍾",  "stars": 50},
    "flowers":      {"name": "گل",           "emoji": "💐",  "stars": 50},
    "cake":         {"name": "کیک",          "emoji": "🎂",  "stars": 50},
    "ring":         {"name": "حلقه",         "emoji": "💍",  "stars": 100},
    "diamond":      {"name": "الماس",        "emoji": "💎",  "stars": 100},
    "heart_val":    {"name": "قلب ولن",      "emoji": "💝",  "stars": 52},
    "bear_val":     {"name": "خرس ولن",      "emoji": "🐻",  "stars": 52},
    "bear_wday":    {"name": "خرس روز زن",   "emoji": "🧸",  "stars": 52},
    "bear_april":   {"name": "خرس 1 اوریل",  "emoji": "🎪",  "stars": 52},
    "bear_xmas":    {"name": "خرس کریسمسی",  "emoji": "🎅",  "stars": 52},
    "bear_patrick": {"name": "خرس پاتریک",   "emoji": "🍀",  "stars": 52},
}

for _g in GIFTS.values():
    _g["price"] = round(_g["stars"] * GIFT_STAR_PRICE)
recalc_prices()

USERS: dict = {}
USER_NAMES: dict = {}
TOPUP_REQUESTS: dict = {}
ORDERS: dict = {}
ADMIN_WAITING_REJECT: dict = {}
SUPPORT_TICKETS: dict = {}
ADMIN_WAITING_SUPPORT_REPLY: dict = {}
PENDING_REFERRALS: dict = {}
BANK_VERIFY_REQUESTS: dict = {}
BOT_ENABLED = True
REFERRAL_POINTS_ENABLED = False
_counter = itertools.count(1)

def is_admin(uid: int) -> bool:
    return uid in ADMIN_IDS

def is_banned(uid: int) -> bool:
    return bool(USERS.get(uid, {}).get("banned", False))

def get_user(uid: int) -> dict:
    if uid not in USERS:
        USERS[uid] = {
            "balance": 0,
            "discount_balance": 0,
            "score": 0,
            "referrals": 0,
            "referrer_id": None,
            "orders": [],
            "daily_topup_used": 0,
            "daily_topup_date": today_str(),
            "phone_number": None,
            "phone_verified": False,
            "bank_verified": False,
            "extra_daily_limit": 0,
            "banned": False,
        }
    return USERS[uid]

async def register_user_and_referral(uid: int, context: ContextTypes.DEFAULT_TYPE) -> None:
    get_user(uid)
    ref_id = PENDING_REFERRALS.pop(uid, None)
    if ref_id and ref_id != uid and not USERS[uid].get("referrer_id"):
        USERS[uid]["referrer_id"] = ref_id
        referrer = get_user(ref_id)
        referrer["referrals"] += 1
        point_awarded = False
        if REFERRAL_POINTS_ENABLED:
            referrer["score"] += 1
            point_awarded = True
        invited_name = USER_NAMES.get(uid, "یک کاربر جدید")
        try:
            await context.bot.send_message(
                ref_id,
                referral_notification_text(
                    invited_name,
                    point_awarded,
                    referrer["referrals"],
                    referrer["discount_balance"],
                    referrer["score"],
                )
            , parse_mode="HTML")
        except Exception:
            logging.exception("خطا در ارسال پیام اطلاع‌رسانی رفرال به معرف")
        save_data()

def fmt(n: int) -> str:
    return f"{n:,}"

def today_str() -> str:
    return datetime.now(TEHRAN_TZ).strftime("%Y-%m-%d")

def get_daily_remaining(uid: int) -> int:
    u = get_user(uid)
    if u.get("daily_topup_date") != today_str():
        u["daily_topup_date"] = today_str()
        u["daily_topup_used"] = 0
    total_limit = DAILY_LIMIT + u.get("extra_daily_limit", 0)
    return max(total_limit - u["daily_topup_used"], 0)

def use_daily_limit(uid: int, amount: int) -> None:
    get_daily_remaining(uid)
    USERS[uid]["daily_topup_used"] += amount

def refund_daily_limit(uid: int, amount: int) -> None:
    u = get_user(uid)
    if u.get("daily_topup_date") == today_str():
        u["daily_topup_used"] = max(u["daily_topup_used"] - amount, 0)

def apply_referral_commission(buyer_id: int, price: int) -> None:
    if price <= 0:
        return
    buyer = get_user(buyer_id)
    referrer_id = buyer.get("referrer_id")
    if not referrer_id:
        return
    commission = round(price * REFERRAL_COMMISSION_PERCENT / 100)
    if commission <= 0:
        return
    referrer = get_user(referrer_id)
    referrer["discount_balance"] += commission

def compute_final_price(order: dict, user_id: int) -> int:
    price = order.get("price", 0)
    if order.get("discount_applied"):
        disc_balance = get_user(user_id)["discount_balance"]
        return max(price - min(disc_balance, price), 0)
    return price

def consume_discount_if_applied(order: dict, user_id: int) -> None:
    if order.get("discount_applied"):
        price = order.get("price", 0)
        u = get_user(user_id)
        used = min(u["discount_balance"], price)
        u["discount_balance"] -= used

def new_id() -> str:
    return str(random.randint(1000000, 9999999))

def new_req_id() -> str:
    return str(next(_counter))

def save_data() -> None:
    data = {
        "users": {str(k): v for k, v in USERS.items()},
        "user_names": {str(k): v for k, v in USER_NAMES.items()},
        "orders": ORDERS,
        "topup_requests": TOPUP_REQUESTS,
        "bank_verify_requests": BANK_VERIFY_REQUESTS,
        "pending_referrals": {str(k): v for k, v in PENDING_REFERRALS.items()},
        "support_tickets": SUPPORT_TICKETS,
        "bot_enabled": BOT_ENABLED,
        "referral_points_enabled": REFERRAL_POINTS_ENABLED,
        "stars_price": STARS_PRICE,
        "ton_price": TON_PRICE,
        "premium_prices": PREMIUM_PRICES,
        "gifts_prices": {k: v["price"] for k, v in GIFTS.items()},
        "gifts": GIFTS,
        "daily_limit": DAILY_LIMIT,
        "profit_percent": PROFIT_PERCENT,
        "base_ton_price": BASE_TON_PRICE,
        "base_stars_price": BASE_STARS_PRICE,
        "base_premium_prices": BASE_PREMIUM_PRICES,
        "card_number": CARD_NUMBER,
        "card_holder": CARD_HOLDER,
        "support_bot_username": SUPPORT_BOT_USERNAME,
        "support_financial_username": SUPPORT_FINANCIAL_USERNAME,
        "required_channel": REQUIRED_CHANNEL,
        "reports_channel": REPORTS_CHANNEL,
        "admin_ids": list(ADMIN_IDS),
        "announcement_text": ANNOUNCEMENT_TEXT,
    }
    try:
        tmp = DATA_FILE + ".tmp"
        with open(tmp, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        os.replace(tmp, DATA_FILE)
    except Exception:
        logging.exception("خطا در ذخیره داده‌ها")

def load_data() -> None:
    global BOT_ENABLED, REFERRAL_POINTS_ENABLED, STARS_PRICE, TON_PRICE, DAILY_LIMIT
    global BASE_TON_PRICE, BASE_STARS_PRICE, CARD_NUMBER, CARD_HOLDER, REQUIRED_CHANNEL, REPORTS_CHANNEL
    global SUPPORT_BOT_USERNAME, SUPPORT_FINANCIAL_USERNAME
    global ANNOUNCEMENT_TEXT
    if not os.path.exists(DATA_FILE):
        logging.info("فایل داده یافت نشد؛ با تنظیمات پیش‌فرض شروع می‌شه.")
        return
    try:
        with open(DATA_FILE, "r", encoding="utf-8") as f:
            data = json.load(f)

        for k, v in data.get("users", {}).items():
            USERS[int(k)] = v

        for k, v in data.get("user_names", {}).items():
            USER_NAMES[int(k)] = v

        ORDERS.update(data.get("orders", {}))
        TOPUP_REQUESTS.update(data.get("topup_requests", {}))
        BANK_VERIFY_REQUESTS.update(data.get("bank_verify_requests", {}))
        SUPPORT_TICKETS.update(data.get("support_tickets", {}))

        for k, v in data.get("pending_referrals", {}).items():
            PENDING_REFERRALS[int(k)] = v

        BOT_ENABLED = data.get("bot_enabled", True)
        REFERRAL_POINTS_ENABLED = data.get("referral_points_enabled", False)
        STARS_PRICE = data.get("stars_price", STARS_PRICE)
        TON_PRICE = data.get("ton_price", TON_PRICE)
        PREMIUM_PRICES.update(data.get("premium_prices", {}))
        DAILY_LIMIT = data.get("daily_limit", DAILY_LIMIT)
        PROFIT_PERCENT.update(data.get("profit_percent", {}))
        BASE_TON_PRICE = data.get("base_ton_price", BASE_TON_PRICE)
        BASE_STARS_PRICE = data.get("base_stars_price", BASE_STARS_PRICE)
        BASE_PREMIUM_PRICES.update(data.get("base_premium_prices", {}))
        CARD_NUMBER = data.get("card_number", CARD_NUMBER)
        CARD_HOLDER = data.get("card_holder", CARD_HOLDER)
        SUPPORT_BOT_USERNAME = data.get("support_bot_username", SUPPORT_BOT_USERNAME)
        SUPPORT_FINANCIAL_USERNAME = data.get("support_financial_username", SUPPORT_FINANCIAL_USERNAME)
        REQUIRED_CHANNEL = data.get("required_channel", REQUIRED_CHANNEL)
        REPORTS_CHANNEL = data.get("reports_channel", REPORTS_CHANNEL)
        ANNOUNCEMENT_TEXT = data.get("announcement_text", ANNOUNCEMENT_TEXT)

        saved_admin_ids = data.get("admin_ids", [])
        if saved_admin_ids:
            ADMIN_IDS.update(int(a) for a in saved_admin_ids)
        ADMIN_IDS.add(ADMIN_CHAT_ID)

        GIFTS.update(data.get("gifts", GIFTS))
        recalc_prices()

        for key, price in data.get("gifts_prices", {}).items():
            if key in GIFTS:
                GIFTS[key]["price"] = price

        logging.info(
            f"داده‌ها بارگذاری شد: {len(USERS)} کاربر، {len(ORDERS)} سفارش"
        )
    except Exception:
        logging.exception("خطا در بارگذاری داده‌ها — با تنظیمات پیش‌فرض شروع می‌شه")

STYLE_MAP = {
    "primary": "primary",
    "info": "primary",
    "blue": "primary",
    "success": "success",
    "green": "success",
    "teal": "success",
    "danger": "danger",
    "red": "danger",
    "dark": "danger",
}

def _active_premium_emojis() -> dict:
    """
    فقط اون ورودی‌هایی از PREMIUM_EMOJI_IDS رو برمی‌گردونه که آیدی واقعی
    (فقط رقم) جاشون گذاشته شده باشه. تا وقتی یه ایموجی هنوز مقدار
    REPLACE_WITH_ID یا خالی داره، دست‌نخورده (به‌صورت معمولی) باقی می‌مونه
    و باعث خطا/کرش نمی‌شه.
    """
    return {
        emo: eid
        for emo, eid in PREMIUM_EMOJI_IDS.items()
        if isinstance(eid, str) and eid.strip().isdigit()
    }

def glass_button(text: str, callback_data: str, color: str = "primary") -> InlineKeyboardButton:
    """
    ساخت دکمه با رنگ واقعی تلگرام (Bot API 9.4+) و ایموجی پرمیوم در صورت وجود.
    اگه متن دکمه شامل یکی از ایموجی‌های تعریف‌شده توی PREMIUM_EMOJI_IDS باشه،
    اون ایموجی از متن حذف و به‌جاش به‌صورت آیکون پرمیوم (icon_custom_emoji_id)
    قبل از متن دکمه نمایش داده می‌شه.
    اگه کتابخونه‌ی نصب‌شده از پارامترهای style / icon_custom_emoji_id پشتیبانی
    نکنه (نسخه قدیمی‌تر)، به صورت خودکار بدون اون‌ها ساخته می‌شه تا ربات کرش نکنه.
    """
    style = STYLE_MAP.get(color)
    btn_text = text
    emoji_id = None
    for emo, eid in _active_premium_emojis().items():
        if emo in btn_text:
            emoji_id = eid
            btn_text = btn_text.replace(emo, "", 1).strip()
            break

    kwargs = {}
    if style:
        kwargs["style"] = style
    if emoji_id:
        kwargs["icon_custom_emoji_id"] = emoji_id

    while True:
        try:
            return InlineKeyboardButton(btn_text, callback_data=callback_data, **kwargs)
        except TypeError:
            if "icon_custom_emoji_id" in kwargs:
                kwargs.pop("icon_custom_emoji_id")
                continue
            if "style" in kwargs:
                kwargs.pop("style")
                continue
            return InlineKeyboardButton(text, callback_data=callback_data)

def glass_kb(buttons: list, row_width: int = 2) -> InlineKeyboardMarkup:
    """ساخت کیبورد شیشه‌ای با دکمه‌های رنگی"""
    rows = []
    current_row = []
    for btn in buttons:
        current_row.append(btn)
        if len(current_row) >= row_width:
            rows.append(current_row)
            current_row = []
    if current_row:
        rows.append(current_row)
    return InlineKeyboardMarkup(rows)

def apply_premium_emojis(text):
    """
    جایگزینی ایموجی‌های معمولی با نسخه‌ی پرمیوم‌شون (تگ tg-emoji) توی متن‌هایی
    که با parse_mode=HTML ارسال می‌شن. فقط ایموجی‌هایی که توی PREMIUM_EMOJI_IDS
    آیدی واقعی (عددی) گرفته باشن جایگزین می‌شن؛ بقیه دست‌نخورده می‌مونن.
    """
    active = _active_premium_emojis()
    if not text or not isinstance(text, str) or not active:
        return text
    for emo, eid in active.items():
        if emo in text:
            text = text.replace(emo, f'<tg-emoji emoji-id="{eid}">{emo}</tg-emoji>')
    return text

def _make_premium_emoji_wrapper(orig_func, param_name):
    sig = inspect.signature(orig_func)

    async def wrapper(self, *args, **kwargs):
        try:
            bound = sig.bind(self, *args, **kwargs)
            bound.apply_defaults()
            if bound.arguments.get("parse_mode") == "HTML":
                val = bound.arguments.get(param_name)
                if isinstance(val, str):
                    bound.arguments[param_name] = apply_premium_emojis(val)
            return await orig_func(*bound.args, **bound.kwargs)
        except TypeError:
            return await orig_func(self, *args, **kwargs)

    return wrapper

def enable_premium_emojis() -> None:
    """
    این تابع رو یک‌بار موقع استارت ربات صدا بزن. متدهای اصلی ارسال/ویرایش پیام
    روی ExtBot رو پچ می‌کنه تا هرجای ربات که با parse_mode=HTML پیام می‌فرسته
    (send_message / reply_text / edit_message_text / edit_message_caption /
    send_photo با کپشن)، ایموجی‌های تعریف‌شده توی PREMIUM_EMOJI_IDS خودکار
    به نسخه‌ی پرمیوم تبدیل بشن؛ بدون نیاز به دستکاری تک‌تک جاهایی که پیام
    ارسال می‌شه.
    """
    if not PREMIUM_EMOJI_IDS:
        return
    from telegram.ext import ExtBot

    if getattr(ExtBot, "_premium_emoji_patched", False):
        return

    for method_name, param_name in [
        ("send_message", "text"),
        ("edit_message_text", "text"),
        ("edit_message_caption", "caption"),
        ("send_photo", "caption"),
    ]:
        orig = getattr(ExtBot, method_name, None)
        if orig is None:
            continue
        setattr(ExtBot, method_name, _make_premium_emoji_wrapper(orig, param_name))

    ExtBot._premium_emoji_patched = True
    logging.info("پچ ایموجی پرمیوم فعال شد.")

def sender_display_name(user) -> str:
    """نام نمایشی خریدار (فرستنده سفارش) برای نمایش در پیام موفقیت سفارش."""
    if getattr(user, "username", None):
        return "@" + user.username
    return user.full_name or f"کاربر {user.id}"

def parse_numeric_id(text: str):
    """
    ورودی کاربر را به آیدی عددی تلگرام تبدیل می‌کند.
    اگر ورودی معتبر نبود (عدد نبود)، None برمی‌گرداند.
    """
    raw = text.strip().lstrip("@")
    if raw.isdigit():
        return int(raw)
    return None

USERNAME_RE = re.compile(r"^[A-Za-z][A-Za-z0-9_]{4,31}$")

def parse_username_input(text: str):
    """
    ورودی کاربر را به یوزرنیم معتبر تلگرام تبدیل می‌کند (با @ در ابتدا).
    اگر ورودی فرمت یوزرنیم تلگرام را نداشت، None برمی‌گرداند.
    """
    raw = text.strip().lstrip("@")
    if USERNAME_RE.match(raw):
        return "@" + raw
    return None

async def resolve_target_by_username(context: ContextTypes.DEFAULT_TYPE, username: str):
    """
    تلاش می‌کند با استفاده از یوزرنیم، آیدی عددی کاربر مقصد را از تلگرام بگیرد.
    اگر ربات دسترسی به چت آن کاربر نداشته باشد (مثلا کاربر هرگز با ربات استارت نزده)،
    به‌جای کرش کردن، None برمی‌گرداند و خود یوزرنیم برای ثبت سفارش کافی است.
    """
    try:
        chat = await context.bot.get_chat(username)
        return chat.id
    except Exception:
        return None

async def is_member(context: ContextTypes.DEFAULT_TYPE, user_id: int) -> bool:
    try:
        member = await context.bot.get_chat_member(f"@{REQUIRED_CHANNEL}", user_id)
        return member.status in ("member", "administrator", "creator")
    except TelegramError as e:
        logging.warning(
            f"⚠️ is_member failed (ربات احتمالا ادمین @{REQUIRED_CHANNEL} نیست): {e}"
        )
        return True

def is_iranian_phone(phone: str) -> bool:
    """بررسی می‌کند که شماره تلفن، ایرانی (پیش‌شماره کشوری +98) باشد."""
    if not phone:
        return False
    digits = "".join(ch for ch in phone if ch.isdigit())
    if digits.startswith("0098"):
        digits = digits[4:]
    elif digits.startswith("98") and len(digits) >= 12:
        digits = digits[2:]
    elif digits.startswith("0") and len(digits) == 11:
        digits = digits[1:]
    return len(digits) == 10 and digits.startswith("9")

def persian_now_str() -> str:
    if HAS_JDATETIME:
        now = jdatetime.datetime.now()
    else:
        now = datetime.now()
    return now.strftime("%Y-%m-%d     %H:%M:%S")

def persian_date_time_parts() -> tuple:
    if HAS_JDATETIME:
        now = jdatetime.datetime.fromgregorian(datetime=datetime.now(TEHRAN_TZ))
    else:
        now = datetime.now(TEHRAN_TZ)
    date_str = f"{now.year}/{now.month}/{now.day}"
    time_str = f"{now.hour:02d}:{now.minute:02d}:{now.second:02d}"
    return date_str, time_str

WELCOME_TEXT = (
    "<b>🌟 ب ربات فروشگاه 𝗕𝗹𝗮𝗰𝗸 𝗦𝘁𝗮𝗿𝘀 | گیفت و استارز خوش آمدید !</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "✨با ما بهترین خدمات تلگرام را با کمترین قیمت و بالاترین سرعت دریافت کنید\n\n"
    "🎁 خدمات بات 𝗕𝗹𝗮𝗰𝗸 𝗦𝘁𝗮𝗿𝘀 | گیفت و استارز\n\n"
    "• ⭐️استارز تلگرام\n"
    "• 💎پرمیوم تلگرام\n"
    "• 🎁گیفت‌های استارزی و NFT\n"
    "• ⚡️فروش ارز تون ( GRAM )\n\n"
    "🚀 برای شروع ، یکی از گزینه‌های منو پایین را انتخاب کنید ☝️"
)

ANNOUNCEMENT_TEXT = (
    "<b>🔔 اطلاعیه مهم</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "در حال حاضر اطلاعیه‌ی خاصی ثبت نشده است.\n\n"
    "این بخش توسط ادمین از طریق پنل مدیریت قابل ویرایش است."
)

REFERRAL_RULES_TEXT = (
    "<b>⭐️ کاربر عزیز، لطفاً قبل از زیرمجموعه‌گیری دقت کنید:</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "1- هرگونه زیرمجموعه‌گیری فیک (مثل اکانت‌های تکراری یا متعلق به خودتان) تخلف محسوب می‌شود.\n\n"
    "2- جذب زیرمجموعه فیک (مانند ورود یک شخص با چند اکانت) خلاف قوانین بوده و موجب حذف موجودی شما می‌شود.\n\n"
    "ما بابت زیرمجموعه‌گیری واقعی و فعال به کاربران خود هدیه ارائه می‌دهیم.\n\n"
    "امیدواریم با رعایت قوانین، شما هم یکی از کاربران خوب و ارزشمند ما باشید 🌱"
)

PRODUCT_TEXT = (
    "<b>🛒 محصول مورد نظر خودتو انتخاب کن !</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "🚀 تمامی سفارشات با بالاترین سرعت و همراه با پشتیبانی کامل انجام می‌شن "
    "تا تجربه‌ای مطمئن و بی‌دغدغه داشته باشی !\n\n"
    "🫶 از لیست زیر ، گزینه مورد نظرت رو انتخاب کن :"
)

PREMIUM_TEXT = (
    "<b>🟪 Telegram Premium</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "⭐️ سطح فوق جدیدی از امکانات تلگرام را تجربه کنید.\n\n"
    "✅فعال شدن تیک آبی \n"
    "💎 دسترسی به قابلیت‌های اختصاصی پریمیوم\n"
    "📂 افزایش محدودیت‌های آپلود\n"
    "⚡️ سرعت بیشتر در دانلود و استفاده از تلگرام\n"
    "👨\u200d🎨 استیکرها، ایموجی‌ها و قابلیت‌های ویژه\n"
    "📈 ابزارهای حرفه‌ای برای مدیریت بهتر\n\n"
    "🛡 فعال‌سازی رسمی، \n"
    "امن و بدون نیاز به دسترسی به اکانت\n\n"
    "🚀 انجام سفارش در کوتاه‌ترین زمان ممکن\n\n"
    "✍️ کدام گزینه را انتخاب می‌کنید؟"
)

ASK_USERNAME_TEXT = (
    "📎 <b>گیرنده این سفارش کیست؟</b>\n\n"
    "🔸 اگر قصد خرید برای <b>اکانت خودتان</b> را دارید، روی «👤 برای خودم» بزنید.\n\n"
    "🔸 اگر قصد خرید برای <b>شخص دیگری</b> را دارید، ابتدا روی «👥 برای دیگران» بزنید و در مرحله بعد یوزرنیم را برایمان ارسال کنید.\n\n"
    "✍️ کدام گزینه را انتخاب می‌کنید؟"
)

ASK_USERNAME_FOR_OTHER_TEXT = (
    "📥 <b>ارسال یوزرنیم گیرنده</b>\n\n"
    "لطفاً یوزرنیم تلگرام شخص مورد نظر را همین‌جا برایمان ارسال کنید.\n\n"
    "📝 <b>نمونه:</b>\n"
    "<code>@username</code>\n\n"
    "ℹ️ یوزرنیم باید همان یوزرنیم عمومی تلگرام شخص باشد (بدون فاصله)."
)

CANCELLED_TEXT = (
    "<b>👎 سفارش شما لغو شد</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "برای خرید مجدد، از منوی اصلی گزینه ' خـریـد مـحـصـول🛒' را انتخاب کنید."
)

TON_BUY_TEXT = (
    "<b>💰 خرید ارز تون (GRAM)</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "✨ ارز تون را با بهترین قیمت و تحویل مستقیم به کیف پول خود دریافت کنید.\n\n"
    "💎 انتقال مستقیم به ولت \n"
    "⚡️ انجام سریع سفارش\n"
    "🔒 تراکنش امن و قابل‌اعتماد\n"
    "🙏 پشتیبانی کامل در تمامی مراحل\n\n"
    f"📊 قیمت هر TON:  {fmt(TON_PRICE)} تومان\n"
    f"📌 حداقل سفارش: {MIN_TON} TON\n\n"
    "☝️ مقدار TON موردنیاز خود را وارد کنید.\n\n"
    "💡 مثال: 0.5 یا 2.5"
)

TON_WALLET_TEXT = (
    "<b>💼 آدرس ولت تون ( TON )</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "⚠️ نکات مهم قبل از ارسال آدرس :\n\n"
    "• آدرس باید مخصوص شبکه TON باشد.\n"
    "• آدرس را کامل و بدون فاصله یا تغییر ارسال نمایید.\n"
    "• مسئولیت صحت آدرس واردشده بر عهده کاربر است.\n\n"
    "📎 نمونه فرمت آدرس ولت تون :\n"
    "UQ….................…xY\n"
    "یا\n"
    "EQ….................…9K\n\n"
    "🔓 لطفاً آدرس ولت تون ( TON ) خود را ارسال کنید :"
)

TON_MEMO_QUESTION_TEXT = (
    "<b>💼 آدرس ولت ثبت شد!</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "💬 یک سوال مهم:\n\n"
    "بعضی ولت‌های TON برای دریافت درستِ ارز، نیاز به کامنت (ممو) دارن "
    "تا واریز به همون ولت بره و گم نشه!\n\n"
    "🌟 ولت شما کامنت/ممو داره؟\n"
    "• اگه داره، روی «بله، کامنت دارم» بزن و متن کامنت رو بفرست\n"
    "• اگه نداره یا مطمئن نیستی، روی «رد کردن» بزن"
)

TON_MEMO_INPUT_TEXT = (
    "<b>💬 ارسال کامنت/ممو ولت</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "لطفاً متن کامنت (ممو) ولت تون رو همینجا بفرستید "
    "تا دقیقاً همون برای واریز استفاده بشه."
)

WALLET_INCREASE_TEXT = (
    "<b>💰 افـزایـش مـوجـودی حساب شما</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "شما می‌توانید موجودی خود را به دو روش امن و سریع افزایش دهید :\n\n"
    "💳 پرداخت تومانی – پس از واریز ، موجودی شما به سرعت با تایید پشتیبانی شارژ میشود.\n\n"
    "🚀 فرآیند افزایش موجودی ساده ، سریع و امن است و پس از پرداخت می‌توانید "
    "به راحتی از تمامی خدمات ربات استفاده کنید ✔️"
)

RECEIPT_PROMPT_TEXT = "<b>💳 رسید خود را در قالب عکس ارسال کنید</b>"

RECEIPT_SENT_TEXT = (
    "<b>✅ درخواست افزایش موجودی شما با موفقیت ارسال شد</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "پس از تایید نهایی توسط ادمین، موجودی حساب شما به مبلغی که تعیین کرده اید شارژ میشود"
)

STARS_BUY_TEXT = (
    "<b>🌟 خرید استارز تلگرام</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "🚀 تحویل آنی، پشتیبانی لحظه‌ای و ثبت سفارش بدون تأخیر\n\n"
    "✨ مناسب برای:\n"
    "💎  خرید تلگرام پریمیوم \n"
    "⭐️ ری‌اکشن‌های استارزی\n"
    "📣 تبلیغات تلگرامی\n"
    "🛍 مینی‌اپ‌ها \n"
    "🎁خرید گیفت\n\n"
    f"📈 حداقل خرید:  {STARS_MIN} عدد\n\n"
    "👇 تعداد استارز موردنیاز خود را وارد کنید:"
)

STARS_MIN_ERROR_TEXT = (
    f"<b>‼️ حداقل تعداد استارز برای خرید {STARS_MIN} عدد میباشد ...</b>"
)

GIFT_LIST_TEXT = (
    "<b>💰 هدیه دادن گیفت ، تجربه‌ای خاص در تلگرام!</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "⭐️ با گیفت‌های استارزی می‌تونی دوستان، خانواده یا معشوقت رو شگفت‌زده کنی !\n\n"
    "💫 مزایای گیفت‌های استارزی :\n\n"
    "• 🎁 ارسال هدیه به دوستان و آشنایان برای سوپرایز کردن\n"
    "• 👾 قابل نمایش روی پروفایل تلگرام\n\n"
    "💱 لطفاً گیفت مورد نظر خود را از لیست زیر انتخاب کنید :"
)

GIFT_TYPE_TEXT = (
    "<b>🎁 خرید گیفت</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "نوع گیفت مورد نظر خود را انتخاب کنید:"
)

GIFT_ANON_TEXT = (
    "<b>🎭 نحوه ارسال گیفت</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "می‌خواهید گیفت به صورت ناشناس ارسال شود یا نام شما برای گیرنده نمایش داده شود؟"
)

GIFT_COMMENT_ASK_TEXT = (
    "<b>💬 تنظیم متن زیر گیفت</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "می‌خواهید متنی زیر گیفت قرار بدید؟"
)

GIFT_COMMENT_INPUT_TEXT = "<b>متن مورد نظر خود را ارسال کنید:</b>"

TRACK_TEXT = (
    "<b>📦 پیگیری سفارش</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "🔢 در صورتی که کد پیگیری محصول خود را دارید دکمه زیر را فشار دهید\n"
    "‼️ برای اطلاع از وضعیت سفارش خود باید کد پیگیری داشته باشید"
)

TRACK_ASK_CODE_TEXT = "<b>🔢 کد پیگیری سفارشتان را ارسال کنید 🔍</b>"

TRACK_NOT_FOUND_TEXT = (
    "<b>❌ کد پیگیری یافت نشد.</b>\n\nلطفا کد پیگیری صحیح رو دوباره ارسال کن."
)

SUPPORT_USERNAME = "Eli_as13"
SUPPORT_BOT_USERNAME = "Eli_as13"
SUPPORT_FINANCIAL_USERNAME = "Eli_as13"

SUPPORT_TEXT = "<b>لطفاً یکی از گزینه‌های زیر را انتخاب کنید تا با پشتیبانی ارتباط بگیرید 👇</b>"

SUPPORT_INDIRECT_TEXT = "<b>💬 پیام خود را برای پشتیبانی ارسال کنید 📞</b>"

SUPPORT_SENT_CONFIRM_TEXT = (
    "<b>💬 پیام شما به پشتیبانی ارسال شد  و  در اسرع وقت به آن پاسخ داده خواهد شد✅</b>"
)

TRUST_CHANNEL = "GiftIx_1"

TRUST_TEXT = (
    "<b>⭐ چرا می‌توانید با خیال راحت به ما اعتماد کنید؟</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "ما یک ساله در زمینه‌ی خرید و فروش استارز و پرمیوم فعالیت داریم و در این مدت "
    "با صداقت، سرعت و پشتیبانی قوی تونستیم اعتماد صدها کاربر رو جلب کنیم ❤️\n\n"
    "✅ دلایل اعتماد :\n"
    "• 💳 پرداخت سریع، مطمئن و شفاف\n"
    "• 🌟 بیش از 200 رضایت واقعی مشتری\n"
    "• 📞 پشتیبانی فعال 24 ساعته، قبل و بعد از خرید\n"
    "• 🧾 دارای نماد اعتبار و سابقه‌ی چندساله فعالیت بدون هیچ گزارش منفی\n\n"
    f"📣 برای مشاهده‌ی نظرات و رضایت کاربران، می‌تونید در کانال @{TRUST_CHANNEL} ما\n"
    "هشتگ زیر رو جست‌وجو کنید ☝️\n\n"
    "☝️ #رضایت_GiftIx\n"
    "اعتماد شما باعث افتخار ماست 💙"
)

JOIN_TEXT = (
    "<b>برای استفاده از ربات، باید در کانال‌های زیر عضو شوید</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    f"@{REQUIRED_CHANNEL}"
)

JOIN_CONFIRMED_TEXT = "<b>✅ عضویتت تایید شد، حالا میتونی از ربات استفاده کنی.</b>"

PHONE_REQUEST_TEXT = (
    "<b>📱 برای استفاده از ربات، لطفاً با دکمه زیر شماره تلفن خودتان را به اشتراک بگذارید.</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "⚠️ توجه: ربات فقط برای کاربران دارای شماره تلفن ایرانی (+98) فعال است."
)

PHONE_MISMATCH_TEXT = "<b>⚠️ لطفاً فقط شماره تلفن خودتان را به اشتراک بگذارید، نه شماره شخص دیگری را.</b>"

PHONE_VERIFIED_TEXT = "<b>✅ شماره تلفن شما با موفقیت تایید شد.</b>"

PHONE_REJECTED_TEXT = (
    "<b>❌ متاسفانه این ربات فقط برای کاربران دارای شماره تلفن ایرانی (+98) قابل استفاده است.</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "امکان استفاده از ربات برای شما وجود ندارد."
)

TRANSFER_ASK_ID_TEXT = (
    "<b>💠 انتقال موجودی</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "لطفاً آیدی عددی کاربری که می‌خواهید موجودی به او منتقل شود را ارسال کنید.\n\n"
    "برای لغو، /cancel را بفرستید."
)

TRANSFER_INVALID_ID_TEXT = "<b>❌ لطفاً فقط آیدی عددی معتبر ارسال کنید.</b>"

TRANSFER_USER_NOT_FOUND_TEXT = "<b>❌ کاربری با این آیدی در ربات یافت نشد.</b>"

TRANSFER_SELF_TEXT = "<b>❌ نمی‌توانید به خودتان موجودی انتقال دهید.</b>"

BANK_CARD_ASK_TEXT = (
    "<b>🏦 احراز بانکی</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "لطفاً یک عکس واضح از کارت بانکی خود که نام صاحب حساب و شماره کارت در آن مشخص باشد ارسال کنید.\n\n"
    "پس از تایید توسط ادمین، سقف مجاز واریز روزانه شما افزایش می‌یابد.\n\n"
    "برای لغو، /cancel را بفرستید."
)

BANK_CARD_SENT_TEXT = "<b>📨 عکس کارت بانکی شما برای بررسی ارسال شد. پس از تایید، سقف واریز روزانه شما افزایش خواهد یافت.</b>"

BANK_VERIFY_APPROVED_TEXT = f"<b>✅ احراز بانکی شما تایید شد. سقف مجاز واریز روزانه شما {fmt(BANK_VERIFY_LIMIT_BONUS)} تومان افزایش یافت.</b>"

BANK_VERIFY_REJECTED_TEXT = "<b>❌ متاسفانه احراز بانکی شما تایید نشد. لطفاً با یک عکس واضح‌تر دوباره تلاش کنید.</b>"

BOT_OFF_TEXT = (
    "<b>🔴 ربات در حال حاضر خاموش است.</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "به زودی دوباره روشن خواهد شد، لطفا کمی صبر کنید 🙏"
)

BANNED_TEXT = (
    "<b>🚫 دسترسی شما به ربات توسط مدیریت مسدود شده است.</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "در صورت اعتراض با پشتیبانی تماس بگیرید."
)

ADMIN_BROADCAST_ASK_TEXT = "<b>📢 متن پیامی که می‌خوای برای تمام کاربران ربات ارسال بشه رو بفرست:</b>"

ADMIN_VIEW_USERS_EMPTY_TEXT = "<b>👥 هنوز هیچ کاربری ربات رو استارت نکرده.</b>"

ADMIN_PRICE_MENU_TEXT = "<b>💰 تنظیم قیمت محصولات\n\nمحصول مورد نظر برای تغییر قیمت رو انتخاب کن:</b>"

ADMIN_PREMIUM_PLAN_SELECT_TEXT = "<b>✏️ قیمت کدوم پلن پرمیوم رو می‌خوای تغییر بدی؟</b>"

ADMIN_GIFT_PRICE_LIST_TEXT = "<b>🎀 گیفت مورد نظر برای مشاهده/تغییر قیمت رو انتخاب کن:</b>"

def confirm_username_text(username: str) -> str:
    return (
        "📥 <b>تایید گیرنده سفارش</b>\n\n"
        f"👤 یوزرنیم: <code>{username}</code>\n\n"
        "✅ آیا یوزرنیم بالا را تایید می‌کنید؟"
    )

def premium_invoice_text(plan, price, username, disc, final) -> str:
    return (
        "<b>⏰ فاکتور خرید پرمیوم</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💫 نوع پلن: {plan} ماهه\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💰 مبلغ فاکتور:  {fmt(price)} تومان\n"
        f"🎁 کل موجودی تخفیف:  {fmt(disc)} تومان\n\n"
        f"💡 حداکثر تخفیف قابل اعمال:  {fmt(min(disc, price))} تومان\n\n"
        f"💳 مبلغ نهایی:  {fmt(final)} تومان\n\n"
        "🍾 در صورتی که جزئیات بالا مورد تأیید شماست \n\n"
        "روی دکمه «تأیید ✅» کلیک کنید."
    )

def premium_success_text(plan, username, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت ثبت شد!</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💫 پلن: {plan} ماهه\n"
        f"📎 یوزر: {username}\n"
        f"💰 مبلغ پرداخت‌شده: {fmt(price)} تومان\n\n"
        f"🔑 کد پیگیری سفارش : {order_id}\n\n"
        "⏳ سفارش شما در حال پردازش است و به‌زودی وضعیت آن از طریق ربات اطلاع‌رسانی خواهد شد.\n\n"
        "🙏 از اعتماد شما سپاسگزاریم."
    )

def premium_done_text(plan, username, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت انجام شد 🎉</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "☝️اطلاعات سفارش:\n\n"
        "ℹ️ نوع خدمات: پرمیوم تلگرام\n"
        f"💫 پلن: {plan} ماهه\n"
        f"📎 یوزر: {username}\n"
        f"💳 مبلغ نهایی پرداخت شده:  {fmt(price)} تومان\n"
        f"🔓 کد پیگیری سفارش: {order_id}\n\n"
        "😊 از اعتماد و انتخاب شما سپاسگزاریم."
    )

def admin_premium_text(user, plan, username, price, order_id) -> str:
    uname = f"@{user.username}" if user.username else "---"
    return (
        "<b>🛒 سفارش جدید - پرمیوم تلگرام</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n"
        f"💫 پلن: {plan} ماهه\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💰 مبلغ پرداخت‌شده: {fmt(price)} تومان\n"
        f"🔢 کد پیگیری: {order_id}"
    )

def ton_invoice_text(amount, wallet, memo, price, disc, final) -> str:
    return (
        "<b>📑 فاکتور خرید ارز تون</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💫 مقدار خرید: {amount} تون\n"
        f"🏦 ولت آدرس دریافتی: {wallet}\n"
        f"💬 ممو/کامنت ولت: {memo}\n"
        f"💰 مبلغ فاکتور:  {fmt(price)} تومان\n"
        f"🎁 کل موجودی تخفیف:  {fmt(disc)} تومان\n\n"
        f"💡 حداکثر تخفیف قابل اعمال:  {fmt(min(disc, price))} تومان\n\n"
        f"💳 مبلغ نهایی:  {fmt(final)} تومان\n\n"
        "🔮 در صورتی که جزئیات بالا مورد تأیید شماست ✓ \n"
        "روی دکمه «تأیید ✅» کلیک کنید."
    )

def ton_success_text(amount, wallet, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت ثبت شد.</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "⛏️نوع خدمات : خرید ارز تون\n"
        f"🔢 تعداد : {amount}\n"
        f"📎 آدرس ولت : {wallet}\n"
        f"💰 مبلغ پرداختی :  {fmt(price)} تومان\n"
        f"🔑 کد پیگیری سفارش : {order_id}\n\n"
        "⏳ سفارش شما در حال پردازش است و به‌زودی وضعیت آن از طریق ربات اطلاع‌رسانی خواهد شد.\n\n"
        "🙏 از اعتماد شما سپاسگزاریم."
    )

def ton_done_text(amount, wallet, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت انجام شد 🎉</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "☝️اطلاعات سفارش:\n\n"
        "ℹ️ نوع خدمات: خرید ارز تون\n"
        f"👀 تعداد: {amount} TON\n"
        f"🔗 ولت تون: {wallet}\n"
        f"💳 مبلغ نهایی پرداخت شده:  {fmt(price)} تومان\n"
        f"🔓 کد پیگیری سفارش: {order_id}\n\n"
        "😊 از اعتماد و انتخاب شما سپاسگزاریم."
    )

def stars_invoice_text(count, username, price, disc, final) -> str:
    return (
        "<b>⏰ فاکتور خرید استارز</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💫 مقدار خرید: {count}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💰 مبلغ فاکتور:  {fmt(price)} تومان\n"
        f"🎁 کل موجودی تخفیف:  {fmt(disc)} تومان\n\n"
        f"💡 حداکثر تخفیف قابل اعمال:  {fmt(min(disc, price))} تومان\n\n"
        f"💳 مبلغ نهایی:  {fmt(final)} تومان\n\n"
        "🍾 در صورتی که جزئیات بالا مورد تأیید شماست \n\n"
        "روی دکمه «تأیید ✅» کلیک کنید."
    )

def stars_success_text(count, username, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت ثبت شد!</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "⛏️ نوع خدمات: خرید استارز تلگرام\n"
        f"⭐️ تعداد: {count} استارز\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💰 مبلغ پرداختی:  {fmt(price)} تومان\n"
        f"🔑 کد پیگیری سفارش : {order_id}\n\n"
        "⏳ سفارش شما در حال پردازش است و به‌زودی وضعیت آن از طریق ربات اطلاع‌رسانی خواهد شد.\n\n"
        "🙏 از اعتماد شما سپاسگزاریم."
    )

def stars_done_text(count, username, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت انجام شد 🎉</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "☝️اطلاعات سفارش:\n\n"
        "ℹ️ نوع خدمات: خرید استارز تلگرام\n"
        f"⭐️ تعداد: {count} استارز\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💳 مبلغ نهایی پرداخت شده:  {fmt(price)} تومان\n"
        f"🔓 کد پیگیری سفارش: {order_id}\n\n"
        "😊 از اعتماد و انتخاب شما سپاسگزاریم."
    )

def admin_stars_text(user, count, username, price, order_id) -> str:
    uname = f"@{user.username}" if user.username else "---"
    return (
        "<b>🛒 سفارش جدید - استارز تلگرام</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n"
        f"⭐️ تعداد استارز: {count}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💰 مبلغ پرداخت‌شده: {fmt(price)} تومان\n"
        f"🔢 کد پیگیری: {order_id}"
    )

def gift_label(key: str) -> str:
    g = GIFTS[key]
    return f"گیفت {g['name']} ({g['stars']} ⭐️)"

def gift_invoice_text(key, username, hidden, comment, price, disc, final) -> str:
    hide_str = "✅ بله" if hidden else "❌ خیر"
    comment_str = comment if comment else "ندارد"
    return (
        "<b>📑 فاکتور خرید گیفت</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💫 مقدار خرید: {gift_label(key)}\n"
        f"🔗 یوزر دریافت‌کننده: {username}\n"
        f"🔒 گیفت هاید: {hide_str}\n"
        f"کامنت : {comment_str}\n\n"
        f"💰 مبلغ فاکتور:  {fmt(price)} تومان\n"
        f"🎁 کل موجودی تخفیف:  {fmt(disc)} تومان\n\n"
        f"💡 حداکثر تخفیف قابل اعمال:  {fmt(min(disc, price))} تومان\n\n"
        f"💳 مبلغ نهایی:  {fmt(final)} تومان\n\n"
        "🔮 در صورتی که جزئیات بالا مورد تأیید شماست ✓ \n"
        "روی دکمه «تأیید ✅» کلیک کنید."
    )

def gift_success_text(key, username, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت ثبت شد!</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "⛏️ نوع خدمات: خرید گیفت استارز\n"
        f"🎁 گیفت: {gift_label(key)}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💰 مبلغ پرداختی:  {fmt(price)} تومان\n"
        f"🔑 کد پیگیری سفارش : {order_id}\n\n"
        "⏳ سفارش شما در حال پردازش است و به‌زودی وضعیت آن از طریق ربات اطلاع‌رسانی خواهد شد.\n\n"
        "🙏 از اعتماد شما سپاسگزاریم."
    )

def gift_done_text(key, username, price, order_id) -> str:
    return (
        "<b>✅ سفارش شما با موفقیت انجام شد 🎉</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "☝️اطلاعات سفارش:\n\n"
        "ℹ️ نوع خدمات: خرید گیفت استارز\n"
        f"🎁 گیفت: {gift_label(key)}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"💳 مبلغ نهایی پرداخت شده:  {fmt(price)} تومان\n"
        f"🔓 کد پیگیری سفارش: {order_id}\n\n"
        "😊 از اعتماد و انتخاب شما سپاسگزاریم."
    )

def admin_gift_text(user, key, username, hidden, comment, price, order_id) -> str:
    uname = f"@{user.username}" if user.username else "---"
    hide_str = "✅ بله" if hidden else "❌ خیر"
    comment_display = f"<code>{comment}</code>" if comment else "ندارد"
    return (
        "<b>🛒 سفارش جدید - گیفت استارز</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n"
        f"🎁 گیفت: {gift_label(key)}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"🔒 هاید: {hide_str}\n"
        f"💬 کامنت: {comment_display}\n"
        f"💰 مبلغ پرداخت‌شده: {fmt(price)} تومان\n"
        f"🔢 کد پیگیری: {order_id}"
    )

def admin_support_text(user, message_text: str) -> str:
    uname = f"@{user.username}" if user.username else "---"
    return (
        "<b>📨 پیام جدید پشتیبانی</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n\n"
        f"💬 متن پیام:\n{message_text}"
    )

def order_report_fields(order: dict):
    if order["type"] == "premium":
        return "پرمیوم تلگرام", "💎", f"{order['plan']} ماهه"
    if order["type"] == "ton":
        return "خرید ارز تون", "💱", f"{order['amount']} TON"
    if order["type"] == "stars":
        return "استارز تلگرام", "⭐️", f"{order['count']} 🌟"
    if order["type"] == "referral_reward":
        return "جایزه رفرال", "🎁", gift_label(order["key"])

    return "گیفت استارز", "🎁", gift_label(order["key"])

def price_display(order: dict) -> str:
    if order.get("price", 0) <= 0:
        return "رایگان 🎁"
    return f"{fmt(order['price'])} تومان"

def report_text(buyer_name: str, order: dict) -> str:
    label, emoji, qty = order_report_fields(order)
    return (
        "<b>🛍 خرید موفق ✅</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 خریدار: {buyer_name}\n"
        f"🛒 سفارش : {label} {emoji}\n"
        f"⛏️ تعداد: {qty}\n"
        f"💰 مبلغ پرداخت شده :  {price_display(order)} \n\n"
        f"⏰ {persian_now_str()} \n"
        f"📱 @{BOT_USERNAME}"
    )

def order_status_text(order: dict) -> str:
    type_ = order["type"]
    status_label = "تکمیل شده ✅" if order.get("status") == "done" else "در حال انجام ⏳"

    if type_ == "premium":
        label, emoji = "پرمیوم تلگرام", "💎"
        qty = f"{order['plan']} ماهه"
        extra = f"📎 یوزر دریافت‌کننده: {order['username']}"
    elif type_ == "ton":
        label, emoji = "خرید ارز تون", "⚡️"
        qty = f"{order['amount']} تون"
        extra = f"🔓 آدرس ولت کاربر دریافت کننده: {order['wallet']}"
    elif type_ == "stars":
        label, emoji = "استارز تلگرام", "⭐️"
        qty = f"{order['count']} عدد"
        extra = f"📎 یوزر دریافت‌کننده: {order['username']}"
    elif type_ == "referral_reward":
        label, emoji = "جایزه رفرال", "🎁"
        qty = gift_label(order["key"])
        extra = f"📎 یوزر دریافت‌کننده: {order['username']}"
    else:
        label, emoji = "گیفت استارز", "🎁"
        qty = gift_label(order["key"])
        extra = f"📎 یوزر دریافت‌کننده: {order['username']}"

    date_raw = order.get("created_at", persian_now_str())
    parts = date_raw.split()
    date_display = f"{parts[0]} ساعت {parts[-1]}" if len(parts) >= 2 else date_raw

    return (
        "<b>🔢 مشخصات سفارش </b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"📦 نوع سفارش: {label} {emoji}\n"
        f"📊 تعداد: {qty}\n"
        f"💼 قیمت:  {price_display(order)}\n"
        f"📱 وضعیت: {status_label}\n\n\n"
        f"{extra}\n"
        f"🗓️ تاریخ و ساعت: {date_display}"
    )

def admin_announcement_text() -> str:
    return (
        "<b>📢 تنظیم اطلاعیه مهم</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "این متن با کلیک کاربر روی دکمه اول منوی اصلی نمایش داده می‌شود.\n\n"
        f"📝 متن فعلی:\n\n{ANNOUNCEMENT_TEXT}"
    )

def admin_panel_text() -> str:
    status = "🟢 روشن" if BOT_ENABLED else "🔴 خاموش"
    ref_status = "🟢 فعال" if REFERRAL_POINTS_ENABLED else "🔴 غیرفعال"
    return (
        "<b>🛠 پنل مدیریت ربات</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"وضعیت فعلی ربات: {status}\n"
        f"وضعیت جایزه دعوت: {ref_status}\n\n"
        "از گزینه‌های زیر یکی رو انتخاب کن:"
    )

def broadcast_confirm_text(text: str) -> str:
    return (
        "<b>📢 متن زیر برای تمام کاربران ربات ارسال خواهد شد:</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"{text}\n\n"
        "آیا مطمئن هستید؟"
    )

def broadcast_message_text(text: str) -> str:
    return f"<b>👤 پیام مدیریت به تمام کاربران</b>\n━━━━━━━━━━━━━━━━━━\n\n{text}"

def broadcast_done_text(success: int, fail: int) -> str:
    return f"<b>✅ پیام به {success} کاربر ارسال شد.\n❌ ارسال به {fail} کاربر ناموفق بود.</b>"

def view_users_text() -> str:
    if not USERS:
        return ADMIN_VIEW_USERS_EMPTY_TEXT
    lines = []
    for uid, udata in USERS.items():
        name = USER_NAMES.get(uid, "ناشناس")
        lines.append(f"👤 {name} | 🆔 {uid} | 💰 {fmt(udata['balance'])} تومان")
    header = f"<b>👥 کاربران ربات ({len(USERS)} نفر)</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    body = "\n".join(lines)
    full = header + body
    if len(full) > 4000:
        full = full[:4000] + "\n\n...و بقیه (متن بریده شد)"
    return full

def admin_stars_price_text() -> str:
    return f"<b>⭐️ قیمت فعلی هر ۱ استارز:\n\n💰 {fmt(STARS_PRICE)} تومان</b>"

def admin_ask_stars_price_text() -> str:
    return "<b>✏️ قیمت جدید هر ۱ استارز رو به تومان وارد کن:</b>"

def admin_ton_price_text() -> str:
    price_per_tenth = round(TON_PRICE * MIN_TON)
    return f"<b>💱 قیمت فعلی هر {MIN_TON} TON:\n\n💰 {fmt(price_per_tenth)} تومان</b>"

def admin_ask_ton_price_text() -> str:
    return f"<b>✏️ قیمت جدید هر {MIN_TON} TON رو به تومان وارد کن:</b>"

def admin_premium_price_text() -> str:
    return (
        "<b>💎 قیمت‌های فعلی پرمیوم تلگرام:</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"🔹 3 ماهه:  {fmt(PREMIUM_PRICES['3'])} تومان\n"
        f"🔹 6 ماهه:  {fmt(PREMIUM_PRICES['6'])} تومان\n"
        f"🔹 12 ماهه:  {fmt(PREMIUM_PRICES['12'])} تومان"
    )

def admin_ask_premium_price_text(plan: str) -> str:
    return f"<b>✏️ قیمت جدید پلن {plan} ماهه رو به تومان وارد کن:</b>"

def admin_gift_price_detail_text(key: str) -> str:
    return f"<b>{gift_label(key)}\n\n💰 قیمت فعلی: {fmt(GIFTS[key]['price'])} تومان</b>"

def admin_ask_gift_price_text(key: str) -> str:
    return f"<b>✏️ قیمت جدید {gift_label(key)} رو به تومان وارد کن:</b>"

def admin_daily_limit_text() -> str:
    return (
        "<b>⚙️ تنظیم سقف شارژ روزانه</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💳 سقف مجاز فعلی: {fmt(DAILY_LIMIT)} تومان\n\n"
        "این مقدار حداکثر شارژ هر کاربر در روز است."
    )

def admin_ask_daily_limit_text() -> str:
    return (
        "<b>✏️ سقف مجاز شارژ روزانه جدید رو به تومان وارد کن:</b>\n\n"
        f"(سقف فعلی: {fmt(DAILY_LIMIT)} تومان)"
    )

def admin_profit_menu_text() -> str:
    return "<b>📈 تغییر درصد سود محصولات\n\nمحصول مورد نظر رو انتخاب کن:</b>"

def admin_profit_stars_text() -> str:
    pct = PROFIT_PERCENT["stars"]
    base = BASE_STARS_PRICE * 50
    profit_amt = round(base * pct / 100)
    sell = STARS_PRICE * 50
    return (
        "<b>⭐️ درصد سود استارز تلگرام</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"📦 مقدار نمایشی: {STARS_MIN} استارز\n"
        f"💵 قیمت پایه {STARS_MIN} استارز:  {fmt(base)} تومان\n"
        f"📈 درصد سود فعلی: {pct}٪\n"
        f"💰 مقدار سود:  {fmt(profit_amt)} تومان\n"
        f"🏷 قیمت فروش {STARS_MIN} استارز:  {fmt(sell)} تومان"
    )

def admin_profit_ton_text() -> str:
    pct = PROFIT_PERCENT["ton"]
    base = BASE_TON_PRICE
    profit_amt = round(base * pct / 100)
    sell = TON_PRICE
    return (
        "<b>💱 درصد سود ارز تون</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"📦 مقدار نمایشی: ۱ TON\n"
        f"💵 قیمت پایه ۱ TON:  {fmt(base)} تومان\n"
        f"📈 درصد سود فعلی: {pct}٪\n"
        f"💰 مقدار سود:  {fmt(profit_amt)} تومان\n"
        f"🏷 قیمت فروش ۱ TON:  {fmt(sell)} تومان"
    )

def admin_profit_gift_text() -> str:
    pct = PROFIT_PERCENT["gift"]
    base_per_star = BASE_STARS_PRICE
    sell_per_star = GIFT_STAR_PRICE
    profit_amt = sell_per_star - base_per_star
    return (
        "<b>🎀 درصد سود گیفت استارز</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"📦 مقدار نمایشی: هر استارز گیفت\n"
        f"💵 قیمت پایه هر استارز:  {fmt(base_per_star)} تومان\n"
        f"📈 درصد سود فعلی: {pct}٪\n"
        f"💰 مقدار سود هر استارز:  {fmt(profit_amt)} تومان\n"
        f"🏷 قیمت فروش هر استارز گیفت:  {fmt(sell_per_star)} تومان\n\n"
        "⚙️ این درصد روی قیمت همه گیفت‌ها اعمال می‌شود."
    )

def admin_profit_premium_text() -> str:
    pct = PROFIT_PERCENT["premium"]
    lines = []
    for plan, base in BASE_PREMIUM_PRICES.items():
        sell = PREMIUM_PRICES[plan]
        profit_amt = sell - base
        lines.append(f"🔹 {plan} ماهه: {fmt(base)} ← {fmt(sell)} تومان (+{fmt(profit_amt)})")
    return (
        "<b>💎 درصد سود پرمیوم تلگرام</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"📈 درصد سود فعلی: {pct}٪\n\n"
        + "\n".join(lines)
    )

def admin_ask_profit_text(product_fa: str) -> str:
    return f"<b>✏️ درصد سود جدید {product_fa} رو وارد کن (فقط عدد، بدون %):</b>"

def admin_ton_text(user, amount, wallet, memo, price, order_id) -> str:
    uname = f"@{user.username}" if user.username else "---"
    return (
        "<b>🛒 سفارش جدید - خرید ارز تون</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n"
        f"💫 مقدار: {amount} TON\n"
        f"🏦 آدرس ولت:\n<code>{wallet}</code>\n"
        f"💬 ممو: {memo}\n"
        f"💰 مبلغ پرداخت‌شده: {fmt(price)} تومان\n"
        f"🔢 کد پیگیری: {order_id}"
    )

def insufficient_text(shortfall: int) -> str:
    return (
        f"<b>برای ادامه خرید مبلغ کمبود شما {fmt(shortfall)} تومان است.</b>\n\n"
        "یکی از روش های زیر را برای شارژ سریع انتخاب کنید:"
    )

def wallet_text(balance: int, remaining: int) -> str:
    return (
        "<b>کیف پول 💰</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"موجودی شما:  {fmt(balance)} تومان 💸\n"
        f"باقی مانده سقف مجاز افزایش موجودی تومانی امروز:  {fmt(remaining)} 🚀\n\n"
        "برای افزایش موجودی خود روی دکمه زیر کلیک کنید 👇"
    )

def toman_payment_text(remaining: int) -> str:
    return (
        "<b>💳 پرداخت تومانی </b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "ابتدا مبلغی که قصد دارید به موجودی خود اضافه کنید را وارد کنید.\n\n\n"
        f"📱 باقیمانده سقف مجاز پرداخت تومانی امروز :  {fmt(remaining)} تومان\n\n\n"
        "‼️ توجه کنید که مبلغ واریزی نباید بیشتر از مبلغ سقف مجاز باشد ، "
        "در غیر اینصورت حساب شما فقط در حد سقف مجاز شارژ خواهد شد "
        "و مسئولیت آن به عهده خودتان است ❌"
    )

def daily_limit_exceeded_text(remaining: int) -> str:
    if remaining <= 0:
        return (
            "<b>❌ سقف مجاز شارژ تومانی امروز شما تموم شده.</b>\n━━━━━━━━━━━━━━━━━━\n\n"
            "لطفا فردا دوباره تلاش کن یا با پشتیبانی در ارتباط باش."
        )
    return (
        "<b>❌ مبلغی که وارد کردی بیشتر از سقف مجاز باقی‌مونده امروزته.</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"📱 سقف مجاز باقی‌مونده امروز شما:  {fmt(remaining)} تومان\n\n"
        "لطفا مبلغ کمتر یا مساوی همین مقدار رو وارد کن."
    )

def card_details_text(amount: int) -> str:
    return (
        "<b>💳 اطلاعات پرداخت کارت به کارت</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💸 مبلغ واریزی:   {fmt(amount)} تومان\n\n"
        "💼 شماره کارت جهت واریز :\n\n"
        f"<code>{CARD_NUMBER}</code>\n\n"
        f"👤 به نام: {CARD_HOLDER}\n\n"
        "⚡️ لطفا پس از واریز پول،  «دکمه ارسال رسید» را بزنید و سپس "
        "رسید پرداخت را بصورت عکس ارسال کنید\n\n"
        "❗️توجه: چنانچه رسید بصورت متن بود از آن اسکرین شات بگیرید و اسکرین شات را ارسال کنید.\n\n"
        "❗️در صورت مغایرت مبلغ تعیین شده با مبلغ واریز شده به کارت مسئولیت آن به عهده خودتان است."
    )

def admin_topup_caption(user, amount: int, req_id: str) -> str:
    uname = f"@{user.username}" if user.username else "---"
    return (
        "<b>🧾 درخواست افزایش موجودی جدید</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n"
        f"💸 مبلغ: {fmt(amount)} تومان\n"
        f"🔢 شماره درخواست: {req_id}"
    )

def admin_bank_verify_caption(user, req_id: str) -> str:
    uname = f"@{user.username}" if user.username else "---"
    return (
        "<b>🏦 درخواست احراز بانکی جدید</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n"
        f"🔢 شماره درخواست: {req_id}\n\n"
        "لطفاً عکس کارت بانکی را بررسی کنید."
    )

def approved_text(balance: int) -> str:
    return (
        "<b>🔥 مشتری عزیز</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "✔️ رسید افزایش موجودی شما با موفقیت تایید شد\n"
        f"موجودی شما:  {fmt(balance)} تومان"
    )

def rejected_text(reason: str) -> str:
    return f"<b>❌ متاسفانه درخواست افزایش موجودی شما رد شد.</b>\n━━━━━━━━━━━━━━━━━━\n\nدلیل: {reason}"

def account_text(user) -> str:
    u = get_user(user.id)
    name = user.full_name or (f"@{user.username}" if user.username else "بدون نام")
    date_str, time_str = persian_date_time_parts()
    return (
        "<b>🪪 — مشخصات حساب کاربری شما:</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"├ نام: {name}\n"
        f"├ شناسه: {user.id}\n"
        f"└ تعداد زیرمجموعه شما: {u['referrals']} نفر\n\n"
        f"├ تاریخ: {date_str}\n"
        f"└ ساعت: {time_str}"
    )

def referral_text(user) -> str:
    u = get_user(user.id)
    link = f"https://t.me/{BOT_USERNAME}?start=ref_{user.id}"
    return (
        "<b>👥 زیرمجموعه‌گیری ( Referral System )</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"🔗 لینک اختصاصی شما :\n{link}\n\n"
        f"👥 زیرمجموعه‌ها : {u['referrals']} نفر\n"
        f"💰 درآمد شما :  {fmt(u['discount_balance'])} تومان\n"
        f"🏅 امتیاز رفرال : {u['score']}\n\n"
        "❗️ توضیحات سیستم رفرال :\n\n"
        "• با ارسال لینک اختصاصی خود ، دوستانتان را به ربات دعوت کنید.\n\n"
        f"• هر زمان زیرمجموعه‌ی شما خریدی انجام دهد، {REFERRAL_COMMISSION_PERCENT}٪ از مبلغ "
        "آن خرید به موجودی تخفیف شما اضافه می‌شود.\n\n"
        "• اگر در تایم‌های اعلام‌شده توسط ادمین زیرمجموعه بگیرید ، به ازای هر دعوت "
        "1 امتیاز به امتیاز رفرال شما اضافه می‌شود.\n\n"
        f"• تایم‌ها از طریق اطلاع‌رسانی ربات و کانال تلگرام @{TRUST_CHANNEL} اعلام می‌شوند\n\n"
        f"• درصورت داشتن هر {REFERRAL_POINTS_REQUIRED} امتیاز "
        "شما قادر به دریافت یک جایزه هستید\n\n"
        "(جایزه : گیفت تدی یا قلب 15 استارزی به انتخاب خودتان)"
    )

def referral_notification_text(
    invited_name: str,
    point_awarded: bool,
    total_referrals: int = 0,
    total_discount: int = 0,
    total_score: int = 0,
) -> str:
    text = (
        "<b>🎉 تبریک! یک زیرمجموعه جدید داری!</b>\n\n"
        f"👤 کاربر «{invited_name}» با لینک دعوت شما عضو ربات شد.\n\n"
    )
    if point_awarded:
        text += f"🏅 1 امتیاز رفرال به امتیازهای شما اضافه شد.\n"
    text += (
        "\n━━━━━━━━━━━━━━━━━\n"
        f"👥 کل زیرمجموعه‌های شما: {total_referrals} نفر\n"
        f"💸 موجودی تخفیف شما: {fmt(total_discount)} تومان\n"
        f"🏅 امتیاز رفرال شما: {total_score}\n\n"
        f"💡 هر خریدی که زیرمجموعه‌تون انجام بده، {REFERRAL_COMMISSION_PERCENT}٪ "
        "از مبلغ خرید به موجودی تخفیف شما اضافه میشه."
    )
    return text

def referral_reward_select_text() -> str:
    return "<b>🎁 یکی از گیفت‌های زیر رو به عنوان جایزه رفرال انتخاب کن:</b>"

def referral_reward_invoice_text(key: str, username: str) -> str:
    return (
        "<b>🎁 فاکتور جایزه رفرال</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"💫 جایزه: {gift_label(key)}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"🏅 امتیاز مصرفی: {REFERRAL_POINTS_REQUIRED}\n"
        "💰 مبلغ قابل پرداخت: رایگان 🎁\n\n"
        "🍾 در صورتی که جزئیات بالا مورد تأیید شماست \n\n"
        "روی دکمه «تأیید ✅» کلیک کنید."
    )

def referral_reward_success_text(key: str, username: str, order_id: str) -> str:
    return (
        "<b>✅ جایزه رفرال شما با موفقیت ثبت شد!</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"🎁 جایزه: {gift_label(key)}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        "💰 مبلغ پرداختی: رایگان 🎁\n"
        f"🔑 کد پیگیری سفارش : {order_id}\n\n"
        "⏳ سفارش شما در حال پردازش است و به‌زودی وضعیت آن از طریق ربات اطلاع‌رسانی خواهد شد.\n\n"
        "🙏 از همراهی شما سپاسگزاریم."
    )

def admin_referral_reward_text(user, key: str, username: str, order_id: str) -> str:
    uname = f"@{user.username}" if user.username else "---"
    return (
        "<b>🎁 سفارش جدید - جایزه رفرال (رایگان)</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"👤 کاربر: {user.full_name} ({uname})\n"
        f"🆔 آیدی عددی: {user.id}\n"
        f"🎁 گیفت: {gift_label(key)}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        f"🔢 کد پیگیری: {order_id}"
    )

def referral_reward_done_text(key: str, username: str, order_id: str) -> str:
    return (
        "<b>✅ جایزه رفرال شما با موفقیت انجام شد 🎉</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        "☝️اطلاعات سفارش:\n\n"
        "ℹ️ نوع خدمات: جایزه رفرال\n"
        f"🎁 گیفت: {gift_label(key)}\n"
        f"📎 یوزر دریافت‌کننده: {username}\n"
        "💳 مبلغ نهایی پرداخت شده: رایگان 🎁\n"
        f"🔓 کد پیگیری سفارش: {order_id}\n\n"
        "😊 از همراهی شما سپاسگزاریم."
    )

def main_kb(is_admin: bool = False) -> InlineKeyboardMarkup:
    rows = [
        [glass_button("🎋 𝗕𝗹𝗮𝗰𝗸 𝗦𝘁𝗮𝗿𝘀 | گیفت و استارز", "main_announcement", "primary")],
        [
            glass_button("👤 حساب کاربری", "main_account", "primary"),
            glass_button("زیرمجموعه گیری🪜", "main_invite", "primary"),
        ],
        [
            glass_button("⭐ خرید استارز تلگرام", "product_stars", "primary"),
            glass_button("🧸 خرید گیفت تلگرام", "product_gift_stars", "primary"),
        ],
        [
            glass_button("💎 خرید GRAM کوین", "product_buy_ton", "primary"),
            glass_button("🎁 خرید تلگرام پرمیوم", "product_premium", "primary"),
        ],
        [glass_button("🚀 خرید ( Boost ) بُوست تلگرام", "main_boost", "primary")],
        [glass_button("💬 پشتیبانی 𝗕𝗹𝗮𝗰𝗸 𝗦𝘁𝗮𝗿𝘀 | گیفت و استارز", "main_support", "primary")],
    ]
    if is_admin:
        rows.append([glass_button("『 🛠 پنل ادمین 』", "main_admin", "primary")])
    return InlineKeyboardMarkup(rows)

def account_kb(balance: int) -> InlineKeyboardMarkup:
    rows = [
        [
            InlineKeyboardButton(f"{fmt(balance)} تومان", callback_data="account_noop"),
            InlineKeyboardButton("موجودی شما 💰 :", callback_data="account_noop"),
        ],
        [
            glass_button("شارژ کیف پول ▼", "main_wallet", "green"),
            glass_button("انتقال موجودی ▲", "account_transfer", "blue"),
        ],
        [InlineKeyboardButton("سفارشات اخیر 🏠", callback_data="main_track")],
        [InlineKeyboardButton("احراز بانکی ⓘ", callback_data="account_verify_bank")],
        [InlineKeyboardButton("ابزارهای کاربردی تلگرام 🛠", callback_data="account_telegram_tools")],
        [glass_button("بازگشت به صفحه اصلی ✕", "back_to_welcome", "red")],
    ]
    return InlineKeyboardMarkup(rows)

def product_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("💎 پرمیوم تلگرام", "product_premium", "purple"),
        glass_button("⭐️ استارز تلگرام", "product_stars", "primary"),
        glass_button("🎁 خرید گیفت", "gift_type_select", "pink"),
        glass_button("?? خرید ارز تون", "product_buy_ton", "success"),
        glass_button("🔙 بازگشت", "back_to_welcome", "dark"),
    ], row_width=2)

def premium_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("3 ماه", "premium_3", "primary"),
        glass_button("6 ماه", "premium_6", "purple"),
        glass_button("12 ماه", "premium_12", "pink"),
        glass_button("🔙 بازگشت", "back_to_products", "dark"),
    ], row_width=3)

def cancel_username_input_kb(back_callback: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", back_callback, "dark"),
    ], row_width=1)

def ask_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("👤 برای خودم", "username_self", "success"),
        glass_button("👥 برای دیگران", "username_other", "primary"),
        glass_button("🔙 بازگشت", "back_to_premium", "dark"),
    ], row_width=2)

def confirm_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ بله", "confirm_yes", "success"),
        glass_button("❌ خیر", "confirm_no", "danger"),
    ], row_width=2)

def invoice_kb(discount_applied: bool = False) -> InlineKeyboardMarkup:
    discount_label = "❌ لغو تخفیف" if discount_applied else "💸 اعمال تخفیف"
    return glass_kb([
        glass_button("تأیید ✅", "invoice_confirm", "success"),
        glass_button(discount_label, "invoice_discount", "warning"),
        glass_button("❌ کنسل", "invoice_cancel", "danger"),
    ], row_width=2)

def insufficient_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("💳 کارت به کارت", "topup_from_invoice", "primary"),
        glass_button("🔙 بازگشت به منو", "back_to_products", "danger"),
    ], row_width=1)

def wallet_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("افزایش موجودی", "wallet_increase", "success"),
        glass_button("🔙 بازگشت", "back_to_welcome", "dark"),
    ], row_width=1)

def wallet_increase_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("💳 پرداخت تومانی", "topup_from_wallet", "primary"),
        glass_button("🔙 بازگشت", "wallet_back", "dark"),
    ], row_width=1)

def toman_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "topup_back", "dark"),
    ], row_width=1)

def card_details_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "card_back", "dark"),
        glass_button("📨 ارسال رسید", "send_receipt", "success"),
    ], row_width=2)

def receipt_prompt_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "receipt_back", "dark"),
    ], row_width=1)

def admin_topup_kb(req_id: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ تایید", f"topup_approve_{req_id}", "success"),
        glass_button("❌ رد", f"topup_reject_{req_id}", "danger"),
    ], row_width=2)

def admin_order_kb(order_id: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ انجام شد", f"order_done_{order_id}", "success"),
    ], row_width=1)

def order_success_kb(
    order_id: str,
    type_label: str,
    type_emoji: str,
    recipient: str = None,
    mode_label: str = None,
    sender: str = None,
    for_other: bool = False,
) -> InlineKeyboardMarkup:
    """
    دکمه‌های شیشه‌ای «سفارش با موفقیت ثبت شد» که زیر پیام موفقیت هر نوع سفارش
    (گیفت، استارز، پرمیوم، تون، جایزه رفرال) به کاربر نمایش داده می‌شود.

    اگر سفارش برای شخص دیگری ثبت شده باشد (for_other=True) و مقدار sender هم
    داده شده باشد، به‌جای یک دکمه‌ی «گیرنده سفارش»، دو دکمه‌ی آبی جداگانه برای
    «گیرنده» و «فرستنده» نمایش داده می‌شود.
    """
    rows = [
        [glass_button(f"🔢 کد پیگیری : {order_id}", "noop", "success")],
        [glass_button(f"{type_emoji} نوع سفارش : {type_label}", "noop", "primary")],
    ]
    if mode_label:
        rows.append([glass_button(f"🎭 نوع ارسال : {mode_label}", "noop", "primary")])
    if for_other and recipient and sender:
        rows.append([glass_button("📤 فرستنده", "noop", "dark"), glass_button(sender, "noop", "primary")])
        rows.append([glass_button("📥 گیرنده", "noop", "dark"), glass_button(recipient, "noop", "primary")])
    elif recipient:
        rows.append([glass_button(f"📎 گیرنده سفارش : {recipient}", "noop", "primary")])
    rows.append([InlineKeyboardButton(f"🤖 ربات {BOT_USERNAME}", url=f"https://t.me/{BOT_USERNAME}")])
    return InlineKeyboardMarkup(rows)

def buy_product_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🛒 خرید محصول", "back_to_products", "primary"),
    ], row_width=1)

def ton_back_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "back_to_products", "dark"),
    ], row_width=1)

def ton_wallet_back_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "ton_back_to_amount", "dark"),
    ], row_width=1)

def ton_memo_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ بله، کامنت دارم", "ton_memo_yes", "success"),
        glass_button("❌ رد کردن", "ton_memo_skip", "danger"),
        glass_button("🔙 بازگشت", "ton_memo_back", "dark"),
    ], row_width=2)

def ton_memo_input_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "ton_memo_input_back", "dark"),
    ], row_width=1)

def ton_invoice_kb(discount_applied: bool = False) -> InlineKeyboardMarkup:
    discount_label = "❌ لغو تخفیف" if discount_applied else "💸 اعمال تخفیف"
    return glass_kb([
        glass_button("تأیید ✅", "ton_invoice_confirm", "success"),
        glass_button(discount_label, "ton_invoice_discount", "warning"),
        glass_button("❌ کنسل", "ton_invoice_cancel", "danger"),
    ], row_width=2)

def stars_back_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "back_to_products", "dark"),
    ], row_width=1)

def stars_min_error_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "back_to_products", "dark"),
    ], row_width=1)

def ask_stars_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("👤 برای خودم", "stars_username_self", "success"),
        glass_button("👥 برای دیگران", "stars_username_other", "primary"),
        glass_button("🔙 بازگشت", "stars_back_to_amount", "dark"),
    ], row_width=2)

def confirm_stars_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ بله", "stars_confirm_yes", "success"),
        glass_button("❌ خیر", "stars_confirm_no", "danger"),
    ], row_width=2)

def stars_invoice_kb(discount_applied: bool = False) -> InlineKeyboardMarkup:
    discount_label = "❌ لغو تخفیف" if discount_applied else "💸 اعمال تخفیف"
    return glass_kb([
        glass_button("تأیید ✅", "stars_invoice_confirm", "success"),
        glass_button(discount_label, "stars_invoice_discount", "warning"),
        glass_button("❌ کنسل", "stars_invoice_cancel", "danger"),
    ], row_width=2)

def gift_type_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("⭐️ گیفت استارزی", "gift_type_stars", "primary"),
        glass_button("🖼 گیفت NFT", "gift_type_nft", "info"),
        glass_button("🔙 بازگشت", "back_to_products", "dark"),
    ], row_width=1)

def gift_anon_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🙈 ناشناس", "gift_anon_yes", "primary"),
        glass_button("😎 غیر ناشناس", "gift_anon_no", "success"),
        glass_button("🔙 بازگشت", "gift_back_to_list", "dark"),
    ], row_width=2)

def gift_comment_ask_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✍️ تنظیم متن", "gift_comment_set", "info"),
        glass_button("🚫 رد کردن", "gift_comment_skip", "danger"),
    ], row_width=1)

def gift_list_kb() -> InlineKeyboardMarkup:
    """
    نمایش گیفت‌ها به‌صورت جدول ۳ ستونه (گیفت | قیمت | ارزش)، دقیقاً مثل ربات نمونه.
    این لیست مستقیم از دیکشنری GIFTS ساخته می‌شود، یعنی هر گیفتی که از پنل مدیریت
    اضافه/حذف بشه، خودکار توی همین جدول هم اعمال میشه.
    """
    rows = [[
        glass_button("🎁 گیفت", "gift_table_header", "success"),
        glass_button("💰 قیمت", "gift_table_header", "success"),
        glass_button("🌟 ارزش", "gift_table_header", "success"),
    ]]

    for key, g in GIFTS.items():
        rows.append([
            glass_button(f"{g['emoji']}", f"gift_select_{key}", "primary"),
            glass_button(f"{fmt(g['price'])} تومان", f"gift_select_{key}", "primary"),
            glass_button(f"{g['stars']}⭐️", f"gift_select_{key}", "primary"),
        ])

    rows.append([glass_button("◀️ بازگشت", "gift_type_back", "dark")])
    return InlineKeyboardMarkup(rows)

def ask_gift_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("👤 برای خودم", "gift_username_self", "success"),
        glass_button("👥 برای دیگران", "gift_username_other", "primary"),
        glass_button("🔙 بازگشت", "gift_back_to_list", "dark"),
    ], row_width=2)

def confirm_gift_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ بله", "gift_confirm_yes", "success"),
        glass_button("❌ خیر", "gift_confirm_no", "danger"),
    ], row_width=2)

def gift_invoice_kb(discount_applied: bool = False) -> InlineKeyboardMarkup:
    discount_label = "❌ لغو تخفیف" if discount_applied else "💸 اعمال تخفیف"
    return glass_kb([
        glass_button("تأیید ✅", "gift_invoice_confirm", "success"),
        glass_button(discount_label, "gift_invoice_discount", "warning"),
        glass_button("❌ کنسل", "gift_invoice_cancel", "danger"),
    ], row_width=2)

def gift_comment_input_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "gift_comment_input_back", "dark"),
    ], row_width=1)

def support_kb() -> InlineKeyboardMarkup:
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("🤖 پشتیبانی ربات", url=f"https://t.me/{SUPPORT_BOT_USERNAME}")],
        [InlineKeyboardButton("💰 پشتیبانی مالی", url=f"https://t.me/{SUPPORT_FINANCIAL_USERNAME}")],
    ])

def support_indirect_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "support_back", "dark"),
    ], row_width=1)

def admin_support_kb(ticket_id: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✍️ پاسخ دادن", f"support_reply_{ticket_id}", "primary"),
    ], row_width=1)

def join_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("📢 عضویت در کانال", "join_channel", "primary"),
        glass_button("✅ عضو شدم", "check_membership", "success"),
    ], row_width=1)

def phone_request_kb() -> ReplyKeyboardMarkup:
    return ReplyKeyboardMarkup(
        [[KeyboardButton("📱 اشتراک‌گذاری شماره تلفن", request_contact=True)]],
        resize_keyboard=True,
        one_time_keyboard=True,
    )

def admin_bank_verify_kb(req_id: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ تایید", f"bankverify_approve_{req_id}", "success"),
        glass_button("❌ رد", f"bankverify_reject_{req_id}", "danger"),
    ], row_width=2)

def report_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🛍 حالا اقدام به خرید کن", "buy_now", "success"),
    ], row_width=1)

def track_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔢 کد پیگیری محصول دارم", "track_have_code", "primary"),
    ], row_width=1)

def track_ask_code_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "track_back", "dark"),
    ], row_width=1)

def invite_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🎁 دریافت جایزه", "referral_claim_reward", "success"),
    ], row_width=1)

def referral_rules_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("با قوانین موافقم", "referral_rules_agree", "success"),
        glass_button("لغو ، با قوانین موافق نیستم", "referral_rules_disagree", "danger"),
    ], row_width=1)

def referral_reward_select_kb() -> InlineKeyboardMarkup:
    keyboard = []
    for k in REFERRAL_REWARD_GIFTS:
        g = GIFTS[k]
        keyboard.append([glass_button(f"{g['emoji']} گیفت {g['name']}", f"referral_reward_{k}", "pink")])
    keyboard.append([glass_button("🔙 بازگشت", "referral_back", "dark")])
    return InlineKeyboardMarkup(keyboard)

def ask_referral_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("👤 برای خودم", "referral_username_self", "success"),
        glass_button("👥 برای دیگران", "referral_username_other", "primary"),
        glass_button("🔙 بازگشت", "referral_reward_select_back", "dark"),
    ], row_width=2)

def confirm_referral_username_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ بله", "referral_confirm_yes", "success"),
        glass_button("❌ خیر", "referral_confirm_no", "danger"),
    ], row_width=2)

def referral_reward_invoice_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("تأیید ✅", "referral_invoice_confirm", "success"),
        glass_button("❌ کنسل", "referral_invoice_cancel", "danger"),
    ], row_width=1)

def admin_panel_kb() -> InlineKeyboardMarkup:
    toggle_label = "خاموش کردن ربات" if BOT_ENABLED else "روشن کردن ربات"
    ref_toggle_label = "غیرفعال‌سازی جایزه دعوت" if REFERRAL_POINTS_ENABLED else "فعال‌سازی جایزه دعوت"
    return glass_kb([
        glass_button(toggle_label, "admin_toggle_bot", "primary"),
        glass_button(ref_toggle_label, "admin_toggle_referral_points", "primary"),
        glass_button("📢 ارسال پیام به تمام کاربران", "admin_broadcast", "primary"),
        glass_button("🔔 تنظیم اطلاعیه مهم", "admin_announcement_settings", "primary"),
        glass_button("👥 دیدن کاربران ربات", "admin_view_users", "primary"),
        glass_button("💰 تنظیم قیمت", "admin_price_menu", "primary"),
        glass_button("📈 تغییر درصد سود", "admin_profit_menu", "primary"),
        glass_button("📊 تنظیم سقف شارژ روزانه", "admin_daily_limit", "primary"),
        glass_button("🎀 مدیریت گیفت‌ها", "admin_gift_management", "primary"),
        glass_button("💳 تنظیم شماره کارت", "admin_card_settings", "primary"),
        glass_button("💬 تنظیم پشتیبانی", "admin_support_settings", "primary"),
        glass_button("📢 تنظیم کانال جوین اجباری", "admin_join_settings", "primary"),
        glass_button("➕ افزودن ادمین", "admin_add_admin", "primary"),
        glass_button("👤 مدیریت کاربران", "admin_user_management", "primary"),
        glass_button("🗑 ریست کامل داده‌های ربات", "admin_reset_confirm", "primary"),
    ], row_width=2)

def admin_gift_management_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("➕ افزودن گیفت جدید", "admin_add_gift", "primary"),
        glass_button("❌ حذف گیفت", "admin_delete_gift", "primary"),
        glass_button("📋 لیست گیفت‌ها", "admin_gift_price_list", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=2)

def admin_delete_gift_kb() -> InlineKeyboardMarkup:
    buttons = []
    for key, g in GIFTS.items():
        buttons.append(glass_button(f"{g['emoji']} {g['name']}", f"admin_delete_gift_{key}", "primary"))
    buttons.append(glass_button("🔙 بازگشت", "admin_gift_management_back", "primary"))
    return glass_kb(buttons, row_width=2)

def admin_confirm_delete_gift_kb(key: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ بله، حذف شود", f"admin_confirm_delete_{key}", "primary"),
        glass_button("❌ نه، برگرد", "admin_delete_gift_back", "primary"),
    ], row_width=1)

def admin_card_settings_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تغییر شماره کارت", "admin_change_card_number", "primary"),
        glass_button("✏️ تغییر نام صاحب کارت", "admin_change_card_holder", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=1)

def admin_support_settings_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🤖 تغییر یوزرنیم پشتیبانی ربات", "admin_change_support_bot", "primary"),
        glass_button("💰 تغییر یوزرنیم پشتیبانی مالی", "admin_change_support_financial", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=1)

def admin_join_settings_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button(f"📢 کانال فعلی: @{REQUIRED_CHANNEL}", "admin_show_join_channel", "primary"),
        glass_button("✏️ تغییر کانال جوین اجباری", "admin_change_join_channel", "primary"),
        glass_button("📢 تنظیم کانال گزارشات", "admin_change_reports_channel", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=1)

def admin_reset_confirm_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✅ بله، همه چیز پاک بشه", "admin_reset_yes", "primary"),
        glass_button("❌ نه، برگرد", "admin_panel_back", "primary"),
    ], row_width=2)

def admin_back_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=1)

def admin_broadcast_ask_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=1)

def admin_broadcast_confirm_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("❌ نه", "admin_broadcast_no", "primary"),
        glass_button("✅ بله", "admin_broadcast_yes", "primary"),
    ], row_width=2)

def admin_price_menu_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("⭐️ استارز تلگرام", "admin_price_stars", "primary"),
        glass_button("💎 پرمیوم تلگرام", "admin_price_premium", "primary"),
        glass_button("💱 ارز تون", "admin_price_ton", "primary"),
        glass_button("🎀 گیفت استارز", "admin_price_giftstars", "primary"),
        glass_button("🖼 گیفت NFT", "admin_price_giftnft", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=2)

def admin_stars_price_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تغییر قیمت", "admin_change_stars_price", "primary"),
        glass_button("🔙 بازگشت", "admin_price_menu_back", "primary"),
    ], row_width=1)

def admin_stars_price_ask_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "admin_price_stars_back", "primary"),
    ], row_width=1)

def admin_ton_price_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تغییر قیمت", "admin_change_ton_price", "primary"),
        glass_button("🔙 بازگشت", "admin_price_menu_back", "primary"),
    ], row_width=1)

def admin_ton_price_ask_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "admin_price_ton_back", "primary"),
    ], row_width=1)

def admin_premium_price_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تغییر قیمت", "admin_change_premium_price", "primary"),
        glass_button("🔙 بازگشت", "admin_price_menu_back", "primary"),
    ], row_width=1)

def admin_premium_plan_select_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("3 ماه", "admin_premium_plan_3", "primary"),
        glass_button("6 ماه", "admin_premium_plan_6", "primary"),
        glass_button("12 ماه", "admin_premium_plan_12", "primary"),
        glass_button("🔙 بازگشت", "admin_price_premium_back", "primary"),
    ], row_width=3)

def admin_premium_price_ask_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "admin_premium_plan_select_back", "primary"),
    ], row_width=1)

def admin_gift_price_list_kb() -> InlineKeyboardMarkup:
    rows = []
    keys = list(GIFTS.keys())
    i = 0
    while i < len(keys):
        g = GIFTS[keys[i]]
        label_a = f"{g['emoji']} {g['name']}"
        if i + 1 < len(keys):
            g2 = GIFTS[keys[i + 1]]
            label_b = f"{g2['emoji']} {g2['name']}"
            rows.append([
                glass_button(label_a, f"admin_gift_price_{keys[i]}", "primary"),
                glass_button(label_b, f"admin_gift_price_{keys[i+1]}", "primary"),
            ])
            i += 2
        else:
            rows.append([glass_button(label_a, f"admin_gift_price_{keys[i]}", "primary")])
            i += 1
    rows.append([glass_button("🔙 بازگشت", "admin_price_menu_back", "primary")])
    return InlineKeyboardMarkup(rows)

def admin_gift_price_detail_kb(key: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تغییر قیمت", f"admin_change_gift_price_{key}", "primary"),
        glass_button("🔙 بازگشت", "admin_gift_price_list_back", "primary"),
    ], row_width=1)

def admin_gift_price_ask_kb(key: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", f"admin_gift_price_detail_back_{key}", "primary"),
    ], row_width=1)

def admin_daily_limit_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تنظیم سقف روزانه", "admin_change_daily_limit", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=1)

def admin_daily_limit_ask_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "admin_daily_limit_back", "primary"),
    ], row_width=1)

def admin_announcement_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تغییر متن اطلاعیه", "admin_change_announcement", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=1)

def admin_announcement_ask_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", "admin_announcement_settings", "primary"),
    ], row_width=1)

def admin_profit_menu_kb() -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("⭐️ استارز تلگرام", "admin_profit_stars", "primary"),
        glass_button("💱 ارز تون", "admin_profit_ton", "primary"),
        glass_button("🎀 گیفت استارز", "admin_profit_gift", "primary"),
        glass_button("💎 پرمیوم تلگرام", "admin_profit_premium", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=2)

def admin_profit_detail_kb(product: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("✏️ تنظیم سود", f"admin_set_profit_{product}", "primary"),
        glass_button("🔙 بازگشت", "admin_profit_menu_back", "primary"),
    ], row_width=1)

def admin_profit_ask_kb(product: str) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", f"admin_profit_{product}", "primary"),
    ], row_width=1)

ADMIN_UM_ASK_ID_TEXT = (
    "<b>👤 مدیریت کاربران</b>\n━━━━━━━━━━━━━━━━━━\n\n"
    "آیدی عددی کاربری که می‌خواهید مدیریت کنید را ارسال کنید.\n\n"
    "ℹ️ برای بدست آوردن آیدی عددی می‌توانید از ربات‌هایی مثل @userinfobot استفاده کنید."
)

def user_manage_text(uid: int) -> str:
    u = get_user(uid)
    name = USER_NAMES.get(uid, "ناشناس")
    admin_status = "✅ بله" if is_admin(uid) else "❌ خیر"
    ban_status = "🚫 بله" if u.get("banned") else "✅ خیر"
    phone_status = "✅ تایید شده" if u.get("phone_verified") else "❌ تایید نشده"
    bank_status = "✅ تایید شده" if u.get("bank_verified") else "❌ تایید نشده"
    remaining = get_daily_remaining(uid)
    return (
        "<b>👤 مدیریت کاربر</b>\n━━━━━━━━━━━━━━━━━━\n\n"
        f"نام: {name}\n"
        f"🆔 آیدی عددی: <code>{uid}</code>\n"
        f"💰 موجودی: {fmt(u['balance'])} تومان\n"
        f"🏷 موجودی تخفیف: {fmt(u['discount_balance'])} تومان\n"
        f"⭐ امتیاز: {u['score']}\n"
        f"🪜 تعداد زیرمجموعه: {u['referrals']}\n"
        f"📱 شماره تلفن: {u.get('phone_number') or '—'} ({phone_status})\n"
        f"🏦 احراز بانکی: {bank_status}\n"
        f"📊 سقف باقیمانده شارژ امروز: {fmt(remaining)} تومان\n"
        f"🧾 تعداد سفارشات: {len(u.get('orders', []))}\n"
        f"👑 ادمین: {admin_status}\n"
        f"🚫 مسدود: {ban_status}\n\n"
        "از گزینه‌های زیر برای مدیریت این کاربر استفاده کنید:"
    )

def admin_user_manage_kb(uid: int) -> InlineKeyboardMarkup:
    u = get_user(uid)
    ban_label = "✅ رفع مسدودیت" if u.get("banned") else "🚫 مسدود کردن کاربر"
    admin_label = "➖ حذف از ادمین‌ها" if is_admin(uid) else "➕ افزودن به ادمین‌ها"
    return glass_kb([
        glass_button("💰 تنظیم موجودی", f"admin_um_setbalance_{uid}", "primary"),
        glass_button("🏷 تنظیم موجودی تخفیف", f"admin_um_setdiscount_{uid}", "primary"),
        glass_button("⭐ تنظیم امتیاز", f"admin_um_setscore_{uid}", "primary"),
        glass_button("🧾 مشاهده سفارشات", f"admin_um_orders_{uid}", "primary"),
        glass_button(ban_label, f"admin_um_toggleban_{uid}", "primary"),
        glass_button(admin_label, f"admin_um_toggleadmin_{uid}", "primary"),
        glass_button("♻️ ریست اطلاعات کاربر", f"admin_um_reset_{uid}", "primary"),
        glass_button("🔄 بروزرسانی", f"admin_um_refresh_{uid}", "primary"),
        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
    ], row_width=2)

def admin_um_back_kb(uid: int) -> InlineKeyboardMarkup:
    return glass_kb([
        glass_button("🔙 بازگشت", f"admin_um_refresh_{uid}", "primary"),
    ], row_width=1)

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    context.user_data.clear()
    user = update.effective_user
    chat_id = update.effective_chat.id

    if context.args:
        payload = context.args[0]
        if payload.startswith("ref_"):
            try:
                ref_id = int(payload[len("ref_"):])
                if ref_id != user.id:
                    PENDING_REFERRALS[user.id] = ref_id
            except ValueError:
                pass

    if not is_admin(chat_id):
        if is_banned(user.id):
            await update.message.reply_text(BANNED_TEXT, parse_mode="HTML")
            return
        if not BOT_ENABLED:
            await update.message.reply_text(BOT_OFF_TEXT, parse_mode="HTML")
            return
        if not await is_member(context, user.id):
            await update.message.reply_text(JOIN_TEXT, reply_markup=join_kb(), parse_mode="HTML")
            return
        if not get_user(user.id).get("phone_verified"):
            context.user_data["state"] = "awaiting_contact"
            await update.message.reply_text(PHONE_REQUEST_TEXT, reply_markup=phone_request_kb(), parse_mode="HTML")
            return
    USER_NAMES[user.id] = user.full_name or (f"@{user.username}" if user.username else "بدون نام")
    await register_user_and_referral(user.id, context)
    await update.message.reply_text(WELCOME_TEXT, reply_markup=main_kb(is_admin(chat_id)), parse_mode="HTML")

async def contact_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user = update.effective_user
    chat_id = update.effective_chat.id
    contact = update.message.contact

    if not contact:
        return

    if contact.user_id != user.id:
        await update.message.reply_text(PHONE_MISMATCH_TEXT, reply_markup=phone_request_kb(), parse_mode="HTML")
        return

    if not is_iranian_phone(contact.phone_number):
        await update.message.reply_text(PHONE_REJECTED_TEXT, reply_markup=ReplyKeyboardRemove(), parse_mode="HTML")
        return

    u = get_user(user.id)
    u["phone_number"] = contact.phone_number
    u["phone_verified"] = True
    save_data()

    context.user_data["state"] = None
    USER_NAMES[user.id] = user.full_name or (f"@{user.username}" if user.username else "بدون نام")
    await register_user_and_referral(user.id, context)
    await update.message.reply_text(PHONE_VERIFIED_TEXT, reply_markup=ReplyKeyboardRemove(), parse_mode="HTML")
    await update.message.reply_text(WELCOME_TEXT, reply_markup=main_kb(is_admin(chat_id)), parse_mode="HTML")

async def text_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    text = update.message.text
    user = update.effective_user
    chat_id = update.effective_chat.id
    state = context.user_data.get("state")

    if is_admin(chat_id) and chat_id in ADMIN_WAITING_REJECT:
        req_id = ADMIN_WAITING_REJECT.pop(chat_id)
        req = TOPUP_REQUESTS.pop(req_id, None)
        if req:
            refund_daily_limit(req["user_id"], req["amount"])
            try:
                await context.bot.send_message(req["chat_id"], rejected_text(text), parse_mode="HTML")
            except Exception:
                logging.exception("خطا در ارسال پیام رد به کاربر")
        await update.message.reply_text("دلیل رد برای کاربر ارسال شد.", parse_mode="HTML")
        save_data()
        return

    if is_admin(chat_id) and chat_id in ADMIN_WAITING_SUPPORT_REPLY:
        ticket_id = ADMIN_WAITING_SUPPORT_REPLY.pop(chat_id)
        ticket = SUPPORT_TICKETS.pop(ticket_id, None)
        if ticket:
            try:
                await context.bot.send_message(
                    ticket["chat_id"],
                    f"📩 پاسخ پشتیبانی:\n\n{text}",
                    reply_to_message_id=ticket["message_id"],
                 parse_mode="HTML")
            except Exception:
                logging.exception("خطا در ارسال پاسخ پشتیبانی به کاربر")
        await update.message.reply_text("پاسخ شما برای کاربر ارسال شد.", parse_mode="HTML")
        return

    if not is_admin(chat_id) and is_banned(user.id):
        await update.message.reply_text(BANNED_TEXT, parse_mode="HTML")
        return

    if not is_admin(chat_id) and not BOT_ENABLED:
        await update.message.reply_text(BOT_OFF_TEXT, parse_mode="HTML")
        return

    if not is_admin(chat_id) and not await is_member(context, user.id):
        context.user_data.clear()
        await update.message.reply_text(JOIN_TEXT, reply_markup=join_kb(), parse_mode="HTML")
        return

    if not is_admin(chat_id) and not get_user(user.id).get("phone_verified"):
        context.user_data["state"] = "awaiting_contact"
        await update.message.reply_text(PHONE_REQUEST_TEXT, reply_markup=phone_request_kb(), parse_mode="HTML")
        return

    USER_NAMES[user.id] = user.full_name or (f"@{user.username}" if user.username else "بدون نام")
    await register_user_and_referral(user.id, context)

    if is_admin(chat_id):
        if state == "admin_awaiting_broadcast_text":
            context.user_data["broadcast_text"] = text
            context.user_data["state"] = None
            await update.message.reply_text(
                broadcast_confirm_text(text), reply_markup=admin_broadcast_confirm_kb()
            , parse_mode="HTML")
            return

        if state == "admin_awaiting_stars_price":
            raw = text.replace(",", "").strip()
            if not raw.isdigit():
                await update.message.reply_text(
                    "لطفا فقط عدد وارد کن.", reply_markup=admin_stars_price_ask_kb()
                , parse_mode="HTML")
                return
            global STARS_PRICE
            STARS_PRICE = int(raw)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                admin_stars_price_text(), reply_markup=admin_stars_price_kb()
            , parse_mode="HTML")
            return

        if state == "admin_awaiting_ton_price":
            raw = text.replace(",", "").strip()
            if not raw.isdigit():
                await update.message.reply_text(
                    "لطفا فقط عدد وارد کن.", reply_markup=admin_ton_price_ask_kb()
                , parse_mode="HTML")
                return
            global TON_PRICE
            TON_PRICE = round(int(raw) / MIN_TON)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                admin_ton_price_text(), reply_markup=admin_ton_price_kb()
            , parse_mode="HTML")
            return

        if state and state.startswith("admin_awaiting_premium_price_"):
            plan = state[len("admin_awaiting_premium_price_"):]
            raw = text.replace(",", "").strip()
            if not raw.isdigit():
                await update.message.reply_text(
                    "لطفا فقط عدد وارد کن.", reply_markup=admin_premium_price_ask_kb()
                , parse_mode="HTML")
                return
            PREMIUM_PRICES[plan] = int(raw)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                admin_premium_price_text(), reply_markup=admin_premium_price_kb()
            , parse_mode="HTML")
            return

        if state and state.startswith("admin_awaiting_gift_price_"):
            key = state[len("admin_awaiting_gift_price_"):]
            raw = text.replace(",", "").strip()
            if not raw.isdigit():
                await update.message.reply_text(
                    "لطفا فقط عدد وارد کن.", reply_markup=admin_gift_price_ask_kb(key)
                , parse_mode="HTML")
                return
            GIFTS[key]["price"] = int(raw)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                admin_gift_price_detail_text(key), reply_markup=admin_gift_price_detail_kb(key)
            , parse_mode="HTML")
            return

        if state == "admin_awaiting_daily_limit":
            raw = text.replace(",", "").strip()
            if not raw.isdigit() or int(raw) <= 0:
                await update.message.reply_text(
                    "لطفا فقط یک عدد مثبت وارد کن.", reply_markup=admin_daily_limit_ask_kb()
                , parse_mode="HTML")
                return
            global DAILY_LIMIT
            DAILY_LIMIT = int(raw)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                admin_daily_limit_text(), reply_markup=admin_daily_limit_kb()
            , parse_mode="HTML")
            return

        if state == "admin_awaiting_announcement_text":
            global ANNOUNCEMENT_TEXT
            ANNOUNCEMENT_TEXT = text
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                admin_announcement_text(), reply_markup=admin_announcement_kb()
            , parse_mode="HTML")
            return

        if state and state.startswith("admin_awaiting_profit_"):
            product = state[len("admin_awaiting_profit_"):]
            raw = text.replace(",", "").replace("%", "").strip()
            if not raw.replace(".", "").isdigit() or float(raw) < 0:
                await update.message.reply_text(
                    "لطفا فقط یک عدد مثبت وارد کن (مثال: 10).",
                    reply_markup=admin_profit_ask_kb(product),
                 parse_mode="HTML")
                return
            PROFIT_PERCENT[product] = round(float(raw), 2)
            recalc_prices()
            context.user_data["state"] = None
            save_data()
            text_fn = {
                "stars": admin_profit_stars_text,
                "ton": admin_profit_ton_text,
                "gift": admin_profit_gift_text,
                "premium": admin_profit_premium_text,
            }.get(product, admin_profit_stars_text)
            await update.message.reply_text(text_fn(), reply_markup=admin_profit_detail_kb(product), parse_mode="HTML")
            return

        if state == "admin_awaiting_card_number":
            CARD_NUMBER = text.strip()
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                "✅ شماره کارت با موفقیت تغییر کرد.\n\n"
                f"شماره کارت جدید: <code>{CARD_NUMBER}</code>",
                reply_markup=admin_card_settings_kb(),
                parse_mode="HTML"
            )
            return

        if state == "admin_awaiting_card_holder":
            CARD_HOLDER = text.strip()
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                "✅ نام صاحب کارت با موفقیت تغییر کرد.\n\n"
                f"نام جدید: {CARD_HOLDER}",
                reply_markup=admin_card_settings_kb(),
             parse_mode="HTML")
            return

        if state == "admin_awaiting_support_bot_username":
            global SUPPORT_BOT_USERNAME
            SUPPORT_BOT_USERNAME = text.strip().replace("@", "")
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                "✅ یوزرنیم پشتیبانی ربات با موفقیت تغییر کرد.\n\n"
                f"یوزرنیم جدید: @{SUPPORT_BOT_USERNAME}",
                reply_markup=admin_support_settings_kb(),
                parse_mode="HTML"
            )
            return

        if state == "admin_awaiting_support_financial_username":
            global SUPPORT_FINANCIAL_USERNAME
            SUPPORT_FINANCIAL_USERNAME = text.strip().replace("@", "")
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                "✅ یوزرنیم پشتیبانی مالی با موفقیت تغییر کرد.\n\n"
                f"یوزرنیم جدید: @{SUPPORT_FINANCIAL_USERNAME}",
                reply_markup=admin_support_settings_kb(),
                parse_mode="HTML"
            )
            return

        if state == "admin_awaiting_join_channel":
            channel = text.strip().replace("@", "")
            global REQUIRED_CHANNEL
            REQUIRED_CHANNEL = channel
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                "✅ کانال جوین اجباری با موفقیت تغییر کرد.\n\n"
                f"کانال جدید: @{REQUIRED_CHANNEL}",
                reply_markup=admin_join_settings_kb(),
             parse_mode="HTML")
            return

        if state == "admin_awaiting_reports_channel":
            channel = text.strip().replace("@", "")
            global REPORTS_CHANNEL
            REPORTS_CHANNEL = channel
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                "✅ کانال گزارشات با موفقیت تغییر کرد.\n\n"
                f"کانال جدید: @{REPORTS_CHANNEL}",
                reply_markup=admin_join_settings_kb(),
             parse_mode="HTML")
            return

        if state == "admin_awaiting_add_admin_id":
            forwarded_user = getattr(update.message, "forward_origin", None)
            new_admin_id = None
            if forwarded_user is not None:
                new_admin_id = getattr(getattr(forwarded_user, "sender_user", None), "id", None)
            if new_admin_id is None:
                raw = text.strip()
                if raw.isdigit():
                    new_admin_id = int(raw)
            if new_admin_id is None:
                await update.message.reply_text(
                    "❗️ آیدی عددی معتبر نبود. یک عدد بفرست یا پیام کاربر رو فوروارد کن.",
                    reply_markup=glass_kb([
                        glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
                    ], row_width=1),
                 parse_mode="HTML")
                return
            context.user_data["state"] = None
            if new_admin_id in ADMIN_IDS:
                await update.message.reply_text(
                    "ℹ️ این کاربر از قبل ادمین است.",
                    reply_markup=admin_panel_kb(),
                 parse_mode="HTML")
                return
            ADMIN_IDS.add(new_admin_id)
            save_data()
            await update.message.reply_text(
                f"✅ کاربر با آیدی <code>{new_admin_id}</code> به لیست ادمین‌ها اضافه شد.",
                reply_markup=admin_panel_kb(),
                parse_mode="HTML",
            )
            try:
                await context.bot.send_message(
                    new_admin_id,
                    "🎉 شما به عنوان ادمین ربات اضافه شدید! برای دسترسی به پنل مدیریت دستور /start را بزنید.",
                 parse_mode="HTML")
            except Exception:
                logging.exception("خطا در اطلاع‌رسانی به ادمین جدید")
            return

        if state == "admin_awaiting_user_manage_id":
            target_uid = parse_numeric_id(text)
            if target_uid is None:
                await update.message.reply_text(
                    "❗️ آیدی عددی معتبر نبود. لطفا فقط یک عدد بفرست.",
                    reply_markup=admin_back_kb(),
                 parse_mode="HTML")
                return
            context.user_data["state"] = None
            get_user(target_uid)
            await update.message.reply_text(
                user_manage_text(target_uid),
                reply_markup=admin_user_manage_kb(target_uid),
                parse_mode="HTML",
            )
            return

        if state and state.startswith("admin_um_awaiting_balance_"):
            target_uid = int(state[len("admin_um_awaiting_balance_"):])
            raw = text.replace(",", "").strip()
            if not raw.lstrip("-").isdigit():
                await update.message.reply_text(
                    "لطفا فقط عدد وارد کن.", reply_markup=admin_um_back_kb(target_uid)
                , parse_mode="HTML")
                return
            get_user(target_uid)["balance"] = int(raw)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                user_manage_text(target_uid),
                reply_markup=admin_user_manage_kb(target_uid),
                parse_mode="HTML",
            )
            return

        if state and state.startswith("admin_um_awaiting_discount_"):
            target_uid = int(state[len("admin_um_awaiting_discount_"):])
            raw = text.replace(",", "").strip()
            if not raw.lstrip("-").isdigit():
                await update.message.reply_text(
                    "لطفا فقط عدد وارد کن.", reply_markup=admin_um_back_kb(target_uid)
                , parse_mode="HTML")
                return
            get_user(target_uid)["discount_balance"] = int(raw)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                user_manage_text(target_uid),
                reply_markup=admin_user_manage_kb(target_uid),
                parse_mode="HTML",
            )
            return

        if state and state.startswith("admin_um_awaiting_score_"):
            target_uid = int(state[len("admin_um_awaiting_score_"):])
            raw = text.replace(",", "").strip()
            if not raw.lstrip("-").isdigit():
                await update.message.reply_text(
                    "لطفا فقط عدد وارد کن.", reply_markup=admin_um_back_kb(target_uid)
                , parse_mode="HTML")
                return
            get_user(target_uid)["score"] = int(raw)
            context.user_data["state"] = None
            save_data()
            await update.message.reply_text(
                user_manage_text(target_uid),
                reply_markup=admin_user_manage_kb(target_uid),
                parse_mode="HTML",
            )
            return

    if state == "awaiting_username":
        target_username = parse_username_input(text)
        if target_username is None:
            await update.message.reply_text(
                "❌ لطفا یک یوزرنیم معتبر تلگرام ارسال کن (مثل @username)."
            , parse_mode="HTML")
            return
        target_id = await resolve_target_by_username(context, target_username)
        pending = context.user_data.setdefault("pending_premium", {})
        pending["username"] = target_username
        pending["recipient_id"] = target_id
        pending["for_other"] = True
        context.user_data["state"] = None
        await update.message.reply_text(
            confirm_username_text(target_username), reply_markup=confirm_username_kb()
        , parse_mode="HTML")
        return

    if state == "awaiting_topup_amount":
        raw = text.replace(",", "").replace(" ", "")
        if not raw.isdigit():
            await update.message.reply_text("لطفا فقط عدد مبلغ رو بفرست. مثال: 40000", parse_mode="HTML")
            return
        amount = int(raw)
        remaining = get_daily_remaining(user.id)
        if amount > remaining:
            await update.message.reply_text(
                daily_limit_exceeded_text(remaining), reply_markup=toman_kb()
            , parse_mode="HTML")
            return
        use_daily_limit(user.id, amount)
        context.user_data["pending_topup"] = {"amount": amount}
        context.user_data["state"] = None
        await update.message.reply_text(
            card_details_text(amount), reply_markup=card_details_kb(), parse_mode="HTML"
        )
        return

    if state == "awaiting_receipt_photo":
        await update.message.reply_text("لطفا رسید پرداخت رو به صورت عکس ارسال کن 📷", parse_mode="HTML")
        return

    if state == "awaiting_stars_amount":
        raw = text.replace(",", "").strip()
        if not raw.isdigit():
            await update.message.reply_text(
                "لطفا فقط عدد وارد کن. مثال: 100",
                reply_markup=stars_min_error_kb(),
             parse_mode="HTML")
            return
        count = int(raw)
        if count < STARS_MIN:
            await update.message.reply_text(
                STARS_MIN_ERROR_TEXT,
                reply_markup=stars_min_error_kb(),
             parse_mode="HTML")
            return
        context.user_data["pending_stars"] = {"count": count}
        context.user_data["state"] = None
        await update.message.reply_text(ASK_USERNAME_TEXT, reply_markup=ask_stars_username_kb(), parse_mode="HTML")
        return

    if state == "awaiting_stars_username":
        target_username = parse_username_input(text)
        if target_username is None:
            await update.message.reply_text(
                "❌ لطفا یک یوزرنیم معتبر تلگرام ارسال کن (مثل @username)."
            , parse_mode="HTML")
            return
        target_id = await resolve_target_by_username(context, target_username)
        pending = context.user_data.setdefault("pending_stars", {})
        pending["username"] = target_username
        pending["recipient_id"] = target_id
        pending["for_other"] = True
        context.user_data["state"] = None
        await update.message.reply_text(
            confirm_username_text(target_username), reply_markup=confirm_stars_username_kb(), parse_mode="HTML"
        )
        return

    if state == "awaiting_gift_username":
        target_username = parse_username_input(text)
        if target_username is None:
            await update.message.reply_text(
                "❌ لطفا یک یوزرنیم معتبر تلگرام ارسال کن (مثل @username)."
            , parse_mode="HTML")
            return
        target_id = await resolve_target_by_username(context, target_username)
        pending = context.user_data.setdefault("pending_gift", {})
        pending["username"] = target_username
        pending["recipient_id"] = target_id
        pending["for_other"] = True
        context.user_data["state"] = None
        await update.message.reply_text(
            confirm_username_text(target_username), reply_markup=confirm_gift_username_kb(), parse_mode="HTML"
        )
        return

    if state == "awaiting_gift_comment":
        comment = text.strip()
        g = context.user_data["pending_gift"]
        g["comment"] = comment
        context.user_data["state"] = None
        key = g["key"]
        price = g.get("price", GIFTS[key]["price"])
        disc = get_user(user.id)["discount_balance"]
        final = compute_final_price(g, user.id)
        await update.message.reply_text(
            gift_invoice_text(key, g["username"], g["hidden"], comment, price, disc, final),
            reply_markup=gift_invoice_kb(g.get("discount_applied", False)),
         parse_mode="HTML")
        return

    if state == "awaiting_referral_username":
        target_username = parse_username_input(text)
        if target_username is None:
            await update.message.reply_text(
                "❌ لطفا یک یوزرنیم معتبر تلگرام ارسال کن (مثل @username)."
            , parse_mode="HTML")
            return
        target_id = await resolve_target_by_username(context, target_username)
        pending = context.user_data.setdefault("pending_referral_reward", {})
        pending["username"] = target_username
        pending["recipient_id"] = target_id
        pending["for_other"] = True
        context.user_data["state"] = None
        await update.message.reply_text(
            confirm_username_text(target_username), reply_markup=confirm_referral_username_kb(), parse_mode="HTML"
        )
        return

    if state == "awaiting_ton_amount":
        raw = text.replace(",", "").strip()
        try:
            amount = float(raw)
        except ValueError:
            await update.message.reply_text(f"لطفا عدد وارد کن. مثال: 0.5 یا 2", parse_mode="HTML")
            return
        if amount < MIN_TON:
            await update.message.reply_text(f"حداقل سفارش {MIN_TON} TON است.", parse_mode="HTML")
            return
        context.user_data["pending_ton"] = {"amount": amount}
        context.user_data["state"] = "awaiting_ton_wallet"
        await update.message.reply_text(TON_WALLET_TEXT, reply_markup=ton_wallet_back_kb(), parse_mode="HTML")
        return

    if state == "awaiting_ton_wallet":
        wallet = text.strip()
        if not (wallet.startswith("UQ") or wallet.startswith("EQ")) or len(wallet) < 40:
            await update.message.reply_text(
                "آدرس ولت نامعتبر به نظر می‌رسد.\n"
                "آدرس باید با UQ یا EQ شروع شود و کامل باشد."
            , parse_mode="HTML")
            return
        context.user_data["pending_ton"]["wallet"] = wallet
        context.user_data["state"] = None
        await update.message.reply_text(TON_MEMO_QUESTION_TEXT, reply_markup=ton_memo_kb(), parse_mode="HTML")
        return

    if state == "awaiting_ton_memo":
        memo = text.strip()
        ton = context.user_data["pending_ton"]
        ton["memo"] = memo
        ton["price"] = int(ton["amount"] * TON_PRICE)
        ton["discount_applied"] = False
        context.user_data["state"] = None
        price = ton["price"]
        disc = get_user(user.id)["discount_balance"]
        await update.message.reply_text(
            ton_invoice_text(ton["amount"], ton["wallet"], memo, price, disc, price),
            reply_markup=ton_invoice_kb(False),
         parse_mode="HTML")
        return

    if state == "awaiting_support_message":
        ticket_id = new_req_id()
        SUPPORT_TICKETS[ticket_id] = {
            "user_id": user.id,
            "chat_id": chat_id,
            "message_id": update.message.message_id,
        }
        await update.message.reply_text(SUPPORT_SENT_CONFIRM_TEXT, reply_markup=main_kb(is_admin(chat_id)), parse_mode="HTML")
        context.user_data["state"] = None
        if ADMIN_CHAT_ID:
            try:
                await context.bot.send_message(
                    ADMIN_CHAT_ID,
                    admin_support_text(user, text),
                    reply_markup=admin_support_kb(ticket_id),
                 parse_mode="HTML")
            except Exception:
                logging.exception("خطا در ارسال پیام پشتیبانی به ادمین")
        return

    if state == "awaiting_tracking_code":
        code = text.strip()
        order = ORDERS.get(code)
        if not order:
            await update.message.reply_text(TRACK_NOT_FOUND_TEXT, reply_markup=track_ask_code_kb(), parse_mode="HTML")
            return
        context.user_data["state"] = None
        await update.message.reply_text(order_status_text(order), parse_mode="HTML")
        return

    if state in ("account_transfer_awaiting_id", "account_transfer_awaiting_amount"):
        if text.strip() == "/cancel":
            context.user_data["state"] = None
            context.user_data["transfer_target_id"] = None
            await update.message.reply_text(
                account_text(user),
                reply_markup=account_kb(get_user(user.id)["balance"]),
                parse_mode="HTML",
            )
            return

    if state == "account_transfer_awaiting_id":
        raw = text.strip()
        if not raw.isdigit():
            await update.message.reply_text(
                TRANSFER_INVALID_ID_TEXT,
                reply_markup=glass_kb([glass_button("❌ لغو", "account_transfer_cancel", "danger")], row_width=1),
             parse_mode="HTML")
            return
        target_id = int(raw)
        if target_id == user.id:
            await update.message.reply_text(
                TRANSFER_SELF_TEXT,
                reply_markup=glass_kb([glass_button("❌ لغو", "account_transfer_cancel", "danger")], row_width=1),
             parse_mode="HTML")
            return
        if target_id not in USERS:
            await update.message.reply_text(
                TRANSFER_USER_NOT_FOUND_TEXT,
                reply_markup=glass_kb([glass_button("❌ لغو", "account_transfer_cancel", "danger")], row_width=1),
             parse_mode="HTML")
            return
        context.user_data["transfer_target_id"] = target_id
        context.user_data["state"] = "account_transfer_awaiting_amount"
        balance = get_user(user.id)["balance"]
        await update.message.reply_text(
            f"💰 موجودی فعلی شما: {fmt(balance)} تومان\n\n"
            "لطفاً مبلغی که می‌خواهید منتقل شود را به تومان وارد کنید:",
            reply_markup=glass_kb([glass_button("❌ لغو", "account_transfer_cancel", "danger")], row_width=1),
         parse_mode="HTML")
        return

    if state == "account_transfer_awaiting_amount":
        raw = text.replace(",", "").strip()
        if not raw.isdigit() or int(raw) <= 0:
            await update.message.reply_text(
                "❌ لطفا یک مبلغ معتبر (عدد بزرگتر از صفر) وارد کنید.",
                reply_markup=glass_kb([glass_button("❌ لغو", "account_transfer_cancel", "danger")], row_width=1),
             parse_mode="HTML")
            return
        amount = int(raw)
        sender = get_user(user.id)
        target_id = context.user_data.get("transfer_target_id")
        if not target_id or target_id not in USERS:
            context.user_data["state"] = None
            await update.message.reply_text(TRANSFER_USER_NOT_FOUND_TEXT, parse_mode="HTML")
            return
        if amount > sender["balance"]:
            await update.message.reply_text(
                f"❌ موجودی شما کافی نیست. موجودی فعلی: {fmt(sender['balance'])} تومان",
                reply_markup=glass_kb([glass_button("❌ لغو", "account_transfer_cancel", "danger")], row_width=1),
             parse_mode="HTML")
            return
        recipient = get_user(target_id)
        sender["balance"] -= amount
        recipient["balance"] += amount
        save_data()
        context.user_data["state"] = None
        context.user_data["transfer_target_id"] = None
        await update.message.reply_text(
            f"✅ مبلغ {fmt(amount)} تومان با موفقیت به کاربر {target_id} منتقل شد.\n"
            f"موجودی جدید شما: {fmt(sender['balance'])} تومان",
            reply_markup=account_kb(sender["balance"]),
         parse_mode="HTML")
        try:
            await context.bot.send_message(
                target_id,
                f"💰 مبلغ {fmt(amount)} تومان از طرف کاربر {user.id} به موجودی شما اضافه شد.\n"
                f"موجودی جدید شما: {fmt(recipient['balance'])} تومان",
             parse_mode="HTML")
        except Exception:
            logging.exception("خطا در اطلاع‌رسانی انتقال موجودی به گیرنده")
        return

    if state == "awaiting_bank_card_photo" and text.strip() == "/cancel":
        context.user_data["state"] = None
        await update.message.reply_text(
            account_text(user),
            reply_markup=account_kb(get_user(user.id)["balance"]),
            parse_mode="HTML",
        )
        return

    return

async def send_photo_to_admins(context: ContextTypes.DEFAULT_TYPE, file_id: str, caption: str, reply_markup=None) -> None:
    """رسید/عکس رو برای همه‌ی ادمین‌های ثبت‌شده در ADMIN_IDS ارسال می‌کنه (نه فقط ادمین اصلی)."""
    for aid in ADMIN_IDS:
        try:
            await context.bot.send_photo(
                aid,
                file_id,
                caption=caption,
                reply_markup=reply_markup,
                parse_mode="HTML",
            )
        except Exception:
            logging.exception(f"خطا در ارسال عکس به ادمین {aid}")

async def photo_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    state = context.user_data.get("state")

    if state == "awaiting_bank_card_photo":
        user = update.effective_user
        req_id = new_req_id()
        BANK_VERIFY_REQUESTS[req_id] = {
            "user_id": user.id,
            "chat_id": update.effective_chat.id,
        }
        await send_photo_to_admins(
            context,
            update.message.photo[-1].file_id,
            admin_bank_verify_caption(user, req_id),
            admin_bank_verify_kb(req_id),
        )
        context.user_data["state"] = None
        await update.message.reply_text(BANK_CARD_SENT_TEXT, parse_mode="HTML")
        return

    if context.user_data.get("state") != "awaiting_receipt_photo":
        return
    user = update.effective_user
    pending = context.user_data.get("pending_topup")
    if not pending:
        await update.message.reply_text("درخواست شارژ پیدا نشد، لطفا دوباره شروع کن.", parse_mode="HTML")
        context.user_data["state"] = None
        return

    amount = pending["amount"]
    req_id = new_req_id()
    TOPUP_REQUESTS[req_id] = {
        "user_id": user.id,
        "chat_id": update.effective_chat.id,
        "amount": amount,
    }

    await send_photo_to_admins(
        context,
        update.message.photo[-1].file_id,
        admin_topup_caption(user, amount, req_id),
        admin_topup_kb(req_id),
    )

    context.user_data["state"] = None
    context.user_data["pending_topup"] = None
    await update.message.reply_text(RECEIPT_SENT_TEXT, parse_mode="HTML")

async def callback_router(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    global BOT_ENABLED
    global REFERRAL_POINTS_ENABLED
    global DAILY_LIMIT
    global CARD_NUMBER
    global CARD_HOLDER
    global REQUIRED_CHANNEL
    global REPORTS_CHANNEL
    query = update.callback_query
    data = query.data
    user = update.effective_user
    chat_id = update.effective_chat.id

    if data == "main_boost":
        await query.answer("🚀 خرید بُوست تلگرام به‌زودی فعال می‌شود.", show_alert=True)
        return

    if data == "gift_type_nft":
        await query.answer("🖼 گیفت NFT به زودی فعال می‌شود.", show_alert=True)
        return

    await query.answer()

    if data in ("noop", "gift_table_header"):
        return

    if data == "check_membership":
        if await is_member(context, user.id):
            if not is_admin(chat_id) and not get_user(user.id).get("phone_verified"):
                context.user_data["state"] = "awaiting_contact"
                await query.edit_message_text(JOIN_CONFIRMED_TEXT, parse_mode="HTML")
                await context.bot.send_message(chat_id, PHONE_REQUEST_TEXT, reply_markup=phone_request_kb(), parse_mode="HTML")
                return
            USER_NAMES[user.id] = user.full_name or (f"@{user.username}" if user.username else "بدون نام")
            await register_user_and_referral(user.id, context)
            await query.edit_message_text(JOIN_CONFIRMED_TEXT, parse_mode="HTML")
            await context.bot.send_message(chat_id, WELCOME_TEXT, reply_markup=main_kb(is_admin(chat_id)), parse_mode="HTML")
        else:
            await query.answer(
                "هنوز در کانال عضو نشدید! لطفا ابتدا عضو شوید سپس دوباره امتحان کنید.",
                show_alert=True,
            )
        return

    if not (is_admin(chat_id) or is_admin(user.id)):
        if is_banned(user.id):
            await query.answer(BANNED_TEXT, show_alert=True)
            return
        if not BOT_ENABLED:
            await query.answer(BOT_OFF_TEXT, show_alert=True)
            return
        if not await is_member(context, user.id):
            context.user_data.clear()
            await query.edit_message_text(JOIN_TEXT, reply_markup=join_kb(), parse_mode="HTML")
            return
        if not get_user(user.id).get("phone_verified"):
            context.user_data.clear()
            context.user_data["state"] = "awaiting_contact"
            await context.bot.send_message(chat_id, PHONE_REQUEST_TEXT, reply_markup=phone_request_kb(), parse_mode="HTML")
            return

    USER_NAMES[user.id] = user.full_name or (f"@{user.username}" if user.username else "بدون نام")
    await register_user_and_referral(user.id, context)

    if data.startswith("admin_") and not (is_admin(chat_id) or is_admin(user.id)):
        return

    if data == "back_to_welcome":
        context.user_data.clear()
        await query.edit_message_text(WELCOME_TEXT, reply_markup=main_kb(is_admin(chat_id)), parse_mode="HTML")
        return

    if data == "main_buy":
        context.user_data["state"] = None
        await query.edit_message_text(PRODUCT_TEXT, reply_markup=product_kb(), parse_mode="HTML")
        return

    if data == "main_wallet":
        context.user_data["state"] = None
        balance = get_user(user.id)["balance"]
        remaining = get_daily_remaining(user.id)
        await query.edit_message_text(wallet_text(balance, remaining), reply_markup=wallet_kb(), parse_mode="HTML")
        return

    if data == "main_account":
        context.user_data["state"] = None
        await query.edit_message_text(
            account_text(user),
            reply_markup=account_kb(get_user(user.id)["balance"]),
            parse_mode="HTML",
        )
        return

    if data == "account_noop":
        await query.answer()
        return

    if data == "account_transfer":
        context.user_data["state"] = "account_transfer_awaiting_id"
        context.user_data["transfer_target_id"] = None
        await query.edit_message_text(
            TRANSFER_ASK_ID_TEXT,
            reply_markup=glass_kb([glass_button("❌ لغو", "account_transfer_cancel", "danger")], row_width=1),
         parse_mode="HTML")
        return

    if data == "account_transfer_cancel":
        context.user_data["state"] = None
        context.user_data["transfer_target_id"] = None
        await query.edit_message_text(
            account_text(user),
            reply_markup=account_kb(get_user(user.id)["balance"]),
            parse_mode="HTML",
        )
        return

    if data == "account_verify_bank":
        context.user_data["state"] = "awaiting_bank_card_photo"
        await query.edit_message_text(
            BANK_CARD_ASK_TEXT,
            reply_markup=glass_kb([glass_button("❌ لغو", "account_bank_cancel", "danger")], row_width=1),
         parse_mode="HTML")
        return

    if data == "account_bank_cancel":
        context.user_data["state"] = None
        await query.edit_message_text(
            account_text(user),
            reply_markup=account_kb(get_user(user.id)["balance"]),
            parse_mode="HTML",
        )
        return

    if data == "account_telegram_tools":
        await query.answer("🛠 ابزارهای کاربردی تلگرام به‌زودی فعال می‌شود.", show_alert=True)
        return

    if data == "main_announcement":
        context.user_data["state"] = None
        await query.edit_message_text(
            ANNOUNCEMENT_TEXT,
            reply_markup=glass_kb([glass_button("🔙 بازگشت", "back_to_welcome", "dark")], row_width=1),
         parse_mode="HTML")
        return

    if data == "main_invite":
        context.user_data["state"] = None
        await query.edit_message_text(REFERRAL_RULES_TEXT, reply_markup=referral_rules_kb(), parse_mode="HTML")
        return

    if data == "referral_rules_agree":
        context.user_data["state"] = None
        await query.edit_message_text(referral_text(user), reply_markup=invite_kb(), parse_mode="HTML")
        return

    if data == "referral_rules_disagree":
        context.user_data["state"] = None
        await query.edit_message_text(WELCOME_TEXT, reply_markup=main_kb(is_admin(chat_id)), parse_mode="HTML")
        return

    if data == "main_support":
        context.user_data["state"] = None
        await query.edit_message_text(SUPPORT_TEXT, reply_markup=support_kb(), parse_mode="HTML")
        return

    if data == "main_track":
        context.user_data["state"] = None
        await query.edit_message_text(TRACK_TEXT, reply_markup=track_kb(), parse_mode="HTML")
        return

    if data == "main_trust":
        context.user_data["state"] = None
        await query.edit_message_text(
            TRUST_TEXT,
            reply_markup=glass_kb([glass_button("🔙 بازگشت", "back_to_welcome", "dark")], row_width=1),
         parse_mode="HTML")
        return

    if data == "main_admin" and is_admin(chat_id):
        context.user_data["state"] = None
        await query.edit_message_text(admin_panel_text(), reply_markup=admin_panel_kb(), parse_mode="HTML")
        return

    if data == "back_to_products":
        context.user_data["state"] = None
        await query.edit_message_text(WELCOME_TEXT, reply_markup=main_kb(is_admin(chat_id)), parse_mode="HTML")
        return

    if data in ("product_gift_stars", "gift_type_select"):
        context.user_data["state"] = None
        await query.edit_message_text(GIFT_TYPE_TEXT, reply_markup=gift_type_kb(), parse_mode="HTML")
        return

    if data == "gift_type_back":
        context.user_data["state"] = None
        await query.edit_message_text(GIFT_TYPE_TEXT, reply_markup=gift_type_kb(), parse_mode="HTML")
        return

    if data == "gift_type_stars":
        context.user_data["state"] = None
        await query.edit_message_text(GIFT_LIST_TEXT, reply_markup=gift_list_kb(), parse_mode="HTML")
        return

    if data == "gift_back_to_list":
        context.user_data["state"] = None
        await query.edit_message_text(GIFT_LIST_TEXT, reply_markup=gift_list_kb(), parse_mode="HTML")
        return

    if data.startswith("gift_select_"):
        key = data[len("gift_select_"):]
        if key not in GIFTS:
            return
        context.user_data["pending_gift"] = {
            "key": key,
            "username": None,
            "hidden": True,
            "comment": None,
        }
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_gift_username_kb(), parse_mode="HTML")
        return

    if data == "gift_username_self":
        username = "@" + user.username if user.username else user.full_name
        pending = context.user_data.setdefault("pending_gift", {})
        pending["username"] = username
        pending["recipient_id"] = user.id
        pending["for_other"] = False
        context.user_data["state"] = None
        await query.edit_message_text(
            confirm_username_text(username), reply_markup=confirm_gift_username_kb(), parse_mode="HTML"
        )
        return

    if data == "gift_username_other":
        context.user_data["state"] = "awaiting_gift_username"
        await query.edit_message_text(
            ASK_USERNAME_FOR_OTHER_TEXT,
            reply_markup=cancel_username_input_kb("gift_back_to_ask_username"),
            parse_mode="HTML",
        )
        return

    if data == "gift_back_to_ask_username":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_gift_username_kb(), parse_mode="HTML")
        return

    if data == "gift_confirm_no":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_gift_username_kb(), parse_mode="HTML")
        return

    if data == "gift_confirm_yes":
        g = context.user_data.get("pending_gift", {})
        key = g.get("key", "")
        g["price"] = GIFTS[key]["price"]
        g["discount_applied"] = False
        g["hidden"] = True
        g["comment"] = None
        await query.edit_message_text(GIFT_ANON_TEXT, reply_markup=gift_anon_kb(), parse_mode="HTML")
        return

    if data in ("gift_anon_yes", "gift_anon_no"):
        g = context.user_data.get("pending_gift", {})
        g["hidden"] = (data == "gift_anon_yes")
        await query.edit_message_text(GIFT_COMMENT_ASK_TEXT, reply_markup=gift_comment_ask_kb(), parse_mode="HTML")
        return

    if data == "gift_comment_set":
        context.user_data["state"] = "awaiting_gift_comment"
        await query.edit_message_text(
            GIFT_COMMENT_INPUT_TEXT, reply_markup=gift_comment_input_kb()
        , parse_mode="HTML")
        return

    if data == "gift_comment_input_back":
        context.user_data["state"] = None
        await query.edit_message_text(GIFT_COMMENT_ASK_TEXT, reply_markup=gift_comment_ask_kb(), parse_mode="HTML")
        return

    if data == "gift_comment_skip":
        g = context.user_data.get("pending_gift", {})
        g["comment"] = None
        key = g["key"]
        username = g["username"]
        price = g.get("price", GIFTS[key]["price"])
        disc = get_user(user.id)["discount_balance"]
        final = compute_final_price(g, user.id)
        await query.edit_message_text(
            gift_invoice_text(key, username, g["hidden"], None, price, disc, final),
            reply_markup=gift_invoice_kb(g.get("discount_applied", False)),
         parse_mode="HTML")
        return

    if data == "gift_invoice_discount":
        g = context.user_data.get("pending_gift", {})
        g["discount_applied"] = not g.get("discount_applied", False)
        key = g["key"]
        username = g["username"]
        comment = g.get("comment")
        price = g.get("price", GIFTS[key]["price"])
        disc = get_user(user.id)["discount_balance"]
        final = compute_final_price(g, user.id)
        await query.edit_message_text(
            gift_invoice_text(key, username, g["hidden"], comment, price, disc, final),
            reply_markup=gift_invoice_kb(g["discount_applied"]),
         parse_mode="HTML")
        return

    if data == "gift_invoice_cancel":
        context.user_data["pending_gift"] = None
        context.user_data["state"] = None
        await query.edit_message_text(CANCELLED_TEXT, parse_mode="HTML")
        return

    if data == "gift_invoice_confirm":
        g = context.user_data.get("pending_gift", {})
        key = g.get("key", "")
        username = g.get("username", "-")
        hidden = g.get("hidden", True)
        comment = g.get("comment")
        price = g.get("price", GIFTS[key]["price"])
        final = compute_final_price(g, user.id)
        u = get_user(user.id)
        if u["balance"] >= final:
            u["balance"] -= final
            consume_discount_if_applied(g, user.id)
            apply_referral_commission(user.id, final)
            order_id = new_id()
            u["orders"].append(
                f"🎁 خرید {gift_label(key)} - به مبلغ {fmt(final)} تومان"
            )
            u["orders"] = u["orders"][-50:]
            context.user_data["pending_gift"] = None
            ORDERS[order_id] = {
                "type": "gift",
                "chat_id": update.effective_chat.id,
                "user_id": user.id,
                "buyer_name": user.full_name,
                "key": key,
                "username": username,
                "recipient_id": g.get("recipient_id"),
                "price": final,
                "status": "pending",
                "created_at": persian_now_str(),
            }
            save_data()
            mode_label = "ناشناس ✅" if hidden else "غیر ناشناس 😎"
            await query.edit_message_text(
                gift_success_text(key, username, final, order_id),
                reply_markup=order_success_kb(
                    order_id, "گیفت استارز", "🎁", recipient=username, mode_label=mode_label,
                    sender=sender_display_name(user), for_other=g.get("for_other", False),
                ),
             parse_mode="HTML")
            if REPORTS_CHANNEL:
                try:
                    await context.bot.send_message(
                        f"@{REPORTS_CHANNEL}",
                        admin_gift_text(user, key, username, hidden, comment, final, order_id),
                        reply_markup=admin_order_kb(order_id),
                        parse_mode="HTML",
                    )
                except Exception:
                    logging.exception("خطا در ارسال سفارش گیفت به کانال گزارشات")
        else:
            shortfall = final - u["balance"]
            context.user_data["topup_origin"] = "invoice"
            context.user_data["last_invoice_shortfall_price"] = final
            await query.edit_message_text(insufficient_text(shortfall), reply_markup=insufficient_kb(), parse_mode="HTML")
        return

    if data == "product_premium":
        await query.edit_message_text(PREMIUM_TEXT, reply_markup=premium_kb(), parse_mode="HTML")
        return

    if data in ("premium_3", "premium_6", "premium_12"):
        plan = data.split("_")[1]
        context.user_data["pending_premium"] = {
            "plan": plan,
            "price": PREMIUM_PRICES[plan],
        }
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_username_kb(), parse_mode="HTML")
        return

    if data == "back_to_premium":
        context.user_data["state"] = None
        await query.edit_message_text(PREMIUM_TEXT, reply_markup=premium_kb(), parse_mode="HTML")
        return

    if data == "username_self":
        username = "@" + user.username if user.username else user.full_name
        pending = context.user_data.setdefault("pending_premium", {})
        pending["username"] = username
        pending["recipient_id"] = user.id
        pending["for_other"] = False
        context.user_data["state"] = None
        await query.edit_message_text(
            confirm_username_text(username), reply_markup=confirm_username_kb(), parse_mode="HTML"
        )
        return

    if data == "username_other":
        context.user_data["state"] = "awaiting_username"
        await query.edit_message_text(
            ASK_USERNAME_FOR_OTHER_TEXT,
            reply_markup=cancel_username_input_kb("back_to_ask_username"),
            parse_mode="HTML",
        )
        return

    if data == "back_to_ask_username":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_username_kb(), parse_mode="HTML")
        return

    if data == "confirm_no":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_username_kb(), parse_mode="HTML")
        return

    if data == "confirm_yes":
        order = context.user_data.get("pending_premium", {})
        order["discount_applied"] = False
        plan = order.get("plan", "?")
        price = order.get("price", 0)
        username = order.get("username", "-")
        disc = get_user(user.id)["discount_balance"]
        await query.edit_message_text(
            premium_invoice_text(plan, price, username, disc, price),
            reply_markup=invoice_kb(False),
         parse_mode="HTML")
        return

    if data == "invoice_discount":
        order = context.user_data.get("pending_premium", {})
        order["discount_applied"] = not order.get("discount_applied", False)
        plan = order.get("plan", "?")
        price = order.get("price", 0)
        username = order.get("username", "-")
        disc = get_user(user.id)["discount_balance"]
        final = compute_final_price(order, user.id)
        await query.edit_message_text(
            premium_invoice_text(plan, price, username, disc, final),
            reply_markup=invoice_kb(order["discount_applied"]),
         parse_mode="HTML")
        return

    if data == "invoice_cancel":
        context.user_data["pending_premium"] = None
        context.user_data["state"] = None
        await query.edit_message_text(CANCELLED_TEXT, parse_mode="HTML")
        return

    if data == "invoice_confirm":
        order = context.user_data.get("pending_premium", {})
        plan = order.get("plan", "?")
        price = order.get("price", 0)
        username = order.get("username", "-")
        final = compute_final_price(order, user.id)
        u = get_user(user.id)
        if u["balance"] >= final:
            u["balance"] -= final
            consume_discount_if_applied(order, user.id)
            apply_referral_commission(user.id, final)
            order_id = new_id()
            u["orders"].append(
                f"💎 پرمیوم {plan} ماهه - به مبلغ {fmt(final)} تومان"
            )
            u["orders"] = u["orders"][-50:]
            context.user_data["pending_premium"] = None

            ORDERS[order_id] = {
                "type": "premium",
                "chat_id": update.effective_chat.id,
                "user_id": user.id,
                "buyer_name": user.full_name,
                "plan": plan,
                "username": username,
                "recipient_id": order.get("recipient_id"),
                "price": final,
                "status": "pending",
                "created_at": persian_now_str(),
            }
            save_data()
            await query.edit_message_text(
                premium_success_text(plan, username, final, order_id),
                reply_markup=order_success_kb(
                    order_id, "پرمیوم تلگرام", "💎", recipient=username,
                    sender=sender_display_name(user), for_other=order.get("for_other", False),
                ),
             parse_mode="HTML")
            if REPORTS_CHANNEL:
                try:
                    await context.bot.send_message(
                        f"@{REPORTS_CHANNEL}",
                        admin_premium_text(user, plan, username, final, order_id),
                        reply_markup=admin_order_kb(order_id),
                     parse_mode="HTML")
                except Exception:
                    logging.exception("خطا در ارسال سفارش پرمیوم به کانال گزارشات")
        else:
            shortfall = final - u["balance"]
            context.user_data["topup_origin"] = "invoice"
            context.user_data["last_invoice_shortfall_price"] = final
            await query.edit_message_text(
                insufficient_text(shortfall), reply_markup=insufficient_kb()
            , parse_mode="HTML")
        return

    if data == "wallet_increase":
        await query.edit_message_text(WALLET_INCREASE_TEXT, reply_markup=wallet_increase_kb(), parse_mode="HTML")
        return

    if data == "wallet_back":
        balance = get_user(user.id)["balance"]
        remaining = get_daily_remaining(user.id)
        await query.edit_message_text(wallet_text(balance, remaining), reply_markup=wallet_kb(), parse_mode="HTML")
        return

    if data in ("topup_from_invoice", "topup_from_wallet"):
        context.user_data["topup_origin"] = "invoice" if data == "topup_from_invoice" else "wallet"
        context.user_data["state"] = "awaiting_topup_amount"
        remaining = get_daily_remaining(user.id)
        await query.edit_message_text(toman_payment_text(remaining), reply_markup=toman_kb(), parse_mode="HTML")
        return

    if data == "topup_back":
        context.user_data["state"] = None
        origin = context.user_data.get("topup_origin")
        if origin == "invoice":
            price = context.user_data.get("last_invoice_shortfall_price", 0)
            shortfall = max(price - get_user(user.id)["balance"], 0)
            await query.edit_message_text(insufficient_text(shortfall), reply_markup=insufficient_kb(), parse_mode="HTML")
        else:
            await query.edit_message_text(WALLET_INCREASE_TEXT, reply_markup=wallet_increase_kb(), parse_mode="HTML")
        return

    if data == "card_back":
        context.user_data["state"] = "awaiting_topup_amount"
        remaining = get_daily_remaining(user.id)
        await query.edit_message_text(toman_payment_text(remaining), reply_markup=toman_kb(), parse_mode="HTML")
        return

    if data == "send_receipt":
        context.user_data["state"] = "awaiting_receipt_photo"
        await query.edit_message_text(RECEIPT_PROMPT_TEXT, reply_markup=receipt_prompt_kb(), parse_mode="HTML")
        return

    if data == "receipt_back":
        pending = context.user_data.get("pending_topup") or {}
        amount = pending.get("amount", 0)
        context.user_data["state"] = None
        await query.edit_message_text(
            card_details_text(amount), reply_markup=card_details_kb(), parse_mode="HTML"
        )
        return

    if data.startswith("bankverify_approve_") or data.startswith("bankverify_reject_"):
        if not is_admin(user.id):
            await query.answer("⛔️ فقط ادمین می‌تواند این درخواست را بررسی کند.", show_alert=True)
            return
        req_id = data.rsplit("_", 1)[-1]
        req = BANK_VERIFY_REQUESTS.pop(req_id, None)
        if not req:
            await query.edit_message_caption(caption="این درخواست قبلا پردازش شده.")
            return
        old_cap = query.message.caption or ""
        if data.startswith("bankverify_approve_"):
            target = get_user(req["user_id"])
            target["bank_verified"] = True
            target["extra_daily_limit"] = target.get("extra_daily_limit", 0) + BANK_VERIFY_LIMIT_BONUS
            save_data()
            await query.edit_message_caption(caption=old_cap + "\n\n✅ تایید شد", parse_mode="HTML")
            try:
                await context.bot.send_message(req["chat_id"], BANK_VERIFY_APPROVED_TEXT, parse_mode="HTML")
            except Exception:
                logging.exception("خطا در ارسال تایید احراز بانکی به کاربر")
        else:
            await query.edit_message_caption(caption=old_cap + "\n\n❌ رد شد", parse_mode="HTML")
            try:
                await context.bot.send_message(req["chat_id"], BANK_VERIFY_REJECTED_TEXT, parse_mode="HTML")
            except Exception:
                logging.exception("خطا در ارسال رد احراز بانکی به کاربر")
        return

    if data.startswith("topup_approve_") or data.startswith("topup_reject_"):
        req_id = data.split("_", 2)[2]
        req = TOPUP_REQUESTS.get(req_id)
        if not req:
            await query.edit_message_caption(caption="این درخواست قبلا پردازش شده.")
            return
        if data.startswith("topup_approve_"):
            u = get_user(req["user_id"])
            u["balance"] += req["amount"]
            TOPUP_REQUESTS.pop(req_id, None)
            save_data()
            old_cap = query.message.caption or ""
            await query.edit_message_caption(caption=old_cap + "\n\n✅ تایید شد", parse_mode="HTML")
            try:
                await context.bot.send_message(
                    req["chat_id"],
                    approved_text(u["balance"]),
                    reply_markup=buy_product_kb(),
                 parse_mode="HTML")
            except Exception:
                logging.exception("خطا در ارسال تایید به کاربر")
        else:
            ADMIN_WAITING_REJECT[update.effective_chat.id] = req_id
            old_cap = query.message.caption or ""
            await query.edit_message_caption(caption=old_cap + "\n\n⏳ در انتظار دلیل رد...", parse_mode="HTML")
            await context.bot.send_message(
                update.effective_chat.id,
                "لطفا دلیل رد را در یک پیام بفرست تا برای کاربر ارسال شود."
            , parse_mode="HTML")
        return

    if data.startswith("order_done_"):
        if not is_admin(user.id):
            await query.answer("⛔️ فقط ادمین می‌تواند این سفارش را تکمیل کند.", show_alert=True)
            return
        order_id = data[len("order_done_"):]
        order = ORDERS.get(order_id)
        if not order or order.get("status") == "done":
            await query.edit_message_text((query.message.text or "") + "\n\n✅ قبلاً پردازش شده", parse_mode="HTML")
            return
        order["status"] = "done"
        save_data()

        await query.edit_message_text(
            (query.message.text or "") + "\n\n✅ انجام شد"
        , parse_mode="HTML")

        try:
            if order["type"] == "premium":
                msg = premium_done_text(
                    order["plan"], order["username"], order["price"], order_id
                )
            elif order["type"] == "ton":
                msg = ton_done_text(
                    order["amount"], order["wallet"], order["price"], order_id
                )
            elif order["type"] == "stars":
                msg = stars_done_text(
                    order["count"], order["username"], order["price"], order_id
                )
            elif order["type"] == "referral_reward":
                msg = referral_reward_done_text(
                    order["key"], order["username"], order_id
                )
            else:
                msg = gift_done_text(
                    order["key"], order["username"], order["price"], order_id
                )
            await context.bot.send_message(
                order["chat_id"], msg, reply_markup=buy_product_kb()
            , parse_mode="HTML")
        except Exception:
            logging.exception("خطا در ارسال پیام انجام سفارش به کاربر")

        try:
            buyer_name = order.get("buyer_name") or "کاربر"
            await context.bot.send_message(
                f"@{REPORTS_CHANNEL}",
                report_text(buyer_name, order),
                reply_markup=report_kb(),
             parse_mode="HTML")
        except Exception:
            logging.exception("خطا در ارسال گزارش به کانال (احتمالا ربات ادمین کانال نیست)")
        return

    if data == "track_have_code":
        context.user_data["state"] = "awaiting_tracking_code"
        await query.edit_message_text(TRACK_ASK_CODE_TEXT, reply_markup=track_ask_code_kb(), parse_mode="HTML")
        return

    if data == "track_back":
        context.user_data["state"] = None
        await query.edit_message_text(TRACK_TEXT, reply_markup=track_kb(), parse_mode="HTML")
        return

    if data == "referral_back":
        context.user_data["state"] = None
        await query.edit_message_text(referral_text(user), reply_markup=invite_kb(), parse_mode="HTML")
        return

    if data == "referral_claim_reward":
        if not REFERRAL_POINTS_ENABLED:
            await query.answer(
                "❌ سیستم جایزه دعوت در حال حاضر توسط مدیریت غیرفعال شده است.",
                show_alert=True,
            )
            return
        if get_user(user.id)["score"] < REFERRAL_POINTS_REQUIRED:
            await query.answer(
                f"هنوز امتیاز کافی نداری! برای دریافت جایزه به {REFERRAL_POINTS_REQUIRED} امتیاز رفرال نیاز داری.",
                show_alert=True,
            )
            return
        await query.edit_message_text(
            referral_reward_select_text(), reply_markup=referral_reward_select_kb()
        , parse_mode="HTML")
        return

    if data == "referral_reward_select_back":
        context.user_data["state"] = None
        await query.edit_message_text(
            referral_reward_select_text(), reply_markup=referral_reward_select_kb()
        , parse_mode="HTML")
        return

    if data.startswith("referral_reward_") and data[len("referral_reward_"):] in REFERRAL_REWARD_GIFTS:
        key = data[len("referral_reward_"):]
        context.user_data["pending_referral_reward"] = {"key": key, "username": None}
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_referral_username_kb(), parse_mode="HTML")
        return

    if data == "referral_username_self":
        username = "@" + user.username if user.username else user.full_name
        pending = context.user_data.setdefault("pending_referral_reward", {})
        pending["username"] = username
        pending["recipient_id"] = user.id
        pending["for_other"] = False
        context.user_data["state"] = None
        await query.edit_message_text(
            confirm_username_text(username), reply_markup=confirm_referral_username_kb(), parse_mode="HTML"
        )
        return

    if data == "referral_username_other":
        context.user_data["state"] = "awaiting_referral_username"
        await query.edit_message_text(
            ASK_USERNAME_FOR_OTHER_TEXT,
            reply_markup=cancel_username_input_kb("referral_back_to_ask_username"),
            parse_mode="HTML",
        )
        return

    if data == "referral_back_to_ask_username":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_referral_username_kb(), parse_mode="HTML")
        return

    if data == "referral_confirm_no":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_referral_username_kb(), parse_mode="HTML")
        return

    if data == "referral_confirm_yes":
        r = context.user_data.get("pending_referral_reward", {})
        key = r.get("key", "")
        username = r.get("username", "-")
        await query.edit_message_text(
            referral_reward_invoice_text(key, username), reply_markup=referral_reward_invoice_kb()
        , parse_mode="HTML")
        return

    if data == "referral_invoice_cancel":
        context.user_data["pending_referral_reward"] = None
        context.user_data["state"] = None
        await query.edit_message_text(CANCELLED_TEXT, parse_mode="HTML")
        return

    if data == "referral_invoice_confirm":
        r = context.user_data.get("pending_referral_reward", {})
        key = r.get("key", "")
        username = r.get("username", "-")
        u = get_user(user.id)
        if not REFERRAL_POINTS_ENABLED:
            context.user_data["pending_referral_reward"] = None
            context.user_data["state"] = None
            await query.answer(
                "❌ سیستم جایزه دعوت در حال حاضر توسط مدیریت غیرفعال شده است.",
                show_alert=True,
            )
            await query.edit_message_text(referral_text(user), reply_markup=invite_kb(), parse_mode="HTML")
            return
        if u["score"] < REFERRAL_POINTS_REQUIRED:
            context.user_data["pending_referral_reward"] = None
            context.user_data["state"] = None
            await query.edit_message_text(
                "❌ امتیاز رفرال شما کافی نیست.", reply_markup=invite_kb()
            , parse_mode="HTML")
            return
        u["score"] -= REFERRAL_POINTS_REQUIRED
        order_id = new_id()
        u["orders"].append(f"🎁 جایزه رفرال - {gift_label(key)} - رایگان")
        u["orders"] = u["orders"][-50:]
        context.user_data["pending_referral_reward"] = None
        ORDERS[order_id] = {
            "type": "referral_reward",
            "chat_id": update.effective_chat.id,
            "user_id": user.id,
            "buyer_name": user.full_name,
            "key": key,
            "username": username,
            "recipient_id": r.get("recipient_id"),
            "price": 0,
            "status": "pending",
            "created_at": persian_now_str(),
        }
        save_data()
        await query.edit_message_text(
            referral_reward_success_text(key, username, order_id),
            reply_markup=order_success_kb(
                order_id, "جایزه رفرال", "🎁", recipient=username,
                sender=sender_display_name(user), for_other=r.get("for_other", False),
            ),
         parse_mode="HTML")
        if REPORTS_CHANNEL:
            try:
                await context.bot.send_message(
                    f"@{REPORTS_CHANNEL}",
                    admin_referral_reward_text(user, key, username, order_id),
                    reply_markup=admin_order_kb(order_id),
                 parse_mode="HTML")
            except Exception:
                logging.exception("خطا در ارسال جایزه رفرال به کانال گزارشات")
        return

    if data == "support_indirect":
        context.user_data["state"] = "awaiting_support_message"
        await query.edit_message_text(SUPPORT_INDIRECT_TEXT, reply_markup=support_indirect_kb(), parse_mode="HTML")
        return

    if data == "support_back":
        context.user_data["state"] = None
        await query.edit_message_text(SUPPORT_TEXT, reply_markup=support_kb(), parse_mode="HTML")
        return

    if data.startswith("support_reply_"):
        ticket_id = data[len("support_reply_"):]
        if ticket_id not in SUPPORT_TICKETS:
            await query.answer("این تیکت قبلا پاسخ داده شده یا پیدا نشد.", show_alert=True)
            return
        ADMIN_WAITING_SUPPORT_REPLY[update.effective_chat.id] = ticket_id
        await query.edit_message_text(
            (query.message.text or "") + "\n\nپاسخ خود را بگید"
        , parse_mode="HTML")
        return

    if data == "product_stars":
        context.user_data["state"] = "awaiting_stars_amount"
        context.user_data["pending_stars"] = {}
        await query.edit_message_text(STARS_BUY_TEXT, reply_markup=stars_back_kb(), parse_mode="HTML")
        return

    if data == "stars_back_to_amount":
        context.user_data["state"] = "awaiting_stars_amount"
        context.user_data["pending_stars"] = {}
        await query.edit_message_text(STARS_BUY_TEXT, reply_markup=stars_back_kb(), parse_mode="HTML")
        return

    if data == "stars_username_self":
        username = "@" + user.username if user.username else user.full_name
        pending = context.user_data.setdefault("pending_stars", {})
        pending["username"] = username
        pending["recipient_id"] = user.id
        pending["for_other"] = False
        context.user_data["state"] = None
        await query.edit_message_text(
            confirm_username_text(username), reply_markup=confirm_stars_username_kb(), parse_mode="HTML"
        )
        return

    if data == "stars_username_other":
        context.user_data["state"] = "awaiting_stars_username"
        await query.edit_message_text(
            ASK_USERNAME_FOR_OTHER_TEXT,
            reply_markup=cancel_username_input_kb("stars_back_to_ask_username"),
            parse_mode="HTML",
        )
        return

    if data == "stars_back_to_ask_username":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_stars_username_kb(), parse_mode="HTML")
        return

    if data == "stars_confirm_no":
        context.user_data["state"] = None
        await query.edit_message_text(ASK_USERNAME_TEXT, reply_markup=ask_stars_username_kb(), parse_mode="HTML")
        return

    if data == "stars_confirm_yes":
        s = context.user_data.get("pending_stars", {})
        count = s.get("count", 0)
        username = s.get("username", "-")
        s["price"] = count * STARS_PRICE
        s["discount_applied"] = False
        price = s["price"]
        disc = get_user(user.id)["discount_balance"]
        await query.edit_message_text(
            stars_invoice_text(count, username, price, disc, price),
            reply_markup=stars_invoice_kb(False),
         parse_mode="HTML")
        return

    if data == "stars_invoice_discount":
        s = context.user_data.get("pending_stars", {})
        s["discount_applied"] = not s.get("discount_applied", False)
        count = s.get("count", 0)
        username = s.get("username", "-")
        price = s.get("price", count * STARS_PRICE)
        disc = get_user(user.id)["discount_balance"]
        final = compute_final_price(s, user.id)
        await query.edit_message_text(
            stars_invoice_text(count, username, price, disc, final),
            reply_markup=stars_invoice_kb(s["discount_applied"]),
         parse_mode="HTML")
        return

    if data == "stars_invoice_cancel":
        context.user_data["pending_stars"] = None
        context.user_data["state"] = None
        await query.edit_message_text(CANCELLED_TEXT, parse_mode="HTML")
        return

    if data == "stars_invoice_confirm":
        s = context.user_data.get("pending_stars", {})
        count = s.get("count", 0)
        username = s.get("username", "-")
        price = s.get("price", count * STARS_PRICE)
        final = compute_final_price(s, user.id)
        u = get_user(user.id)
        if u["balance"] >= final:
            u["balance"] -= final
            consume_discount_if_applied(s, user.id)
            apply_referral_commission(user.id, final)
            order_id = new_id()
            u["orders"].append(f"⭐️ خرید {count} استارز - به مبلغ {fmt(final)} تومان")
            u["orders"] = u["orders"][-50:]
            context.user_data["pending_stars"] = None
            ORDERS[order_id] = {
                "type": "stars",
                "chat_id": update.effective_chat.id,
                "user_id": user.id,
                "buyer_name": user.full_name,
                "count": count,
                "username": username,
                "recipient_id": s.get("recipient_id"),
                "price": final,
                "status": "pending",
                "created_at": persian_now_str(),
            }
            save_data()
            await query.edit_message_text(
                stars_success_text(count, username, final, order_id),
                reply_markup=order_success_kb(
                    order_id, "استارز تلگرام", "⭐️", recipient=username,
                    sender=sender_display_name(user), for_other=s.get("for_other", False),
                ),
             parse_mode="HTML")
            if REPORTS_CHANNEL:
                try:
                    await context.bot.send_message(
                        f"@{REPORTS_CHANNEL}",
                        admin_stars_text(user, count, username, final, order_id),
                        reply_markup=admin_order_kb(order_id),
                     parse_mode="HTML")
                except Exception:
                    logging.exception("خطا در ارسال سفارش استارز به کانال گزارشات")
        else:
            shortfall = final - u["balance"]
            context.user_data["topup_origin"] = "invoice"
            context.user_data["last_invoice_shortfall_price"] = final
            await query.edit_message_text(insufficient_text(shortfall), reply_markup=insufficient_kb(), parse_mode="HTML")
        return

    if data == "product_buy_ton":
        context.user_data["state"] = "awaiting_ton_amount"
        context.user_data["pending_ton"] = {}
        await query.edit_message_text(TON_BUY_TEXT, reply_markup=ton_back_kb(), parse_mode="HTML")
        return

    if data == "ton_back_to_amount":
        context.user_data["state"] = "awaiting_ton_amount"
        context.user_data["pending_ton"] = {}
        await query.edit_message_text(TON_BUY_TEXT, reply_markup=ton_back_kb(), parse_mode="HTML")
        return

    if data == "ton_memo_yes":
        context.user_data["state"] = "awaiting_ton_memo"
        await query.edit_message_text(TON_MEMO_INPUT_TEXT, reply_markup=ton_memo_input_kb(), parse_mode="HTML")
        return

    if data == "ton_memo_input_back":
        context.user_data["state"] = None
        await query.edit_message_text(TON_MEMO_QUESTION_TEXT, reply_markup=ton_memo_kb(), parse_mode="HTML")
        return

    if data == "ton_memo_skip":
        ton = context.user_data.get("pending_ton", {})
        amount = ton.get("amount", 0)
        wallet = ton.get("wallet", "-")
        ton["memo"] = "ندارد"
        ton["price"] = int(amount * TON_PRICE)
        ton["discount_applied"] = False
        price = ton["price"]
        disc = get_user(user.id)["discount_balance"]
        await query.edit_message_text(
            ton_invoice_text(amount, wallet, "ندارد", price, disc, price),
            reply_markup=ton_invoice_kb(False),
         parse_mode="HTML")
        return

    if data == "ton_memo_back":
        context.user_data["state"] = "awaiting_ton_wallet"
        await query.edit_message_text(TON_WALLET_TEXT, reply_markup=ton_wallet_back_kb(), parse_mode="HTML")
        return

    if data == "ton_invoice_discount":
        ton = context.user_data.get("pending_ton", {})
        ton["discount_applied"] = not ton.get("discount_applied", False)
        amount = ton.get("amount", 0)
        wallet = ton.get("wallet", "-")
        memo = ton.get("memo", "ندارد")
        price = ton.get("price", int(amount * TON_PRICE))
        disc = get_user(user.id)["discount_balance"]
        final = compute_final_price(ton, user.id)
        await query.edit_message_text(
            ton_invoice_text(amount, wallet, memo, price, disc, final),
            reply_markup=ton_invoice_kb(ton["discount_applied"]),
         parse_mode="HTML")
        return

    if data == "ton_invoice_cancel":
        context.user_data["pending_ton"] = None
        context.user_data["state"] = None
        await query.edit_message_text(CANCELLED_TEXT, parse_mode="HTML")
        return

    if data == "ton_invoice_confirm":
        ton = context.user_data.get("pending_ton", {})
        amount = ton.get("amount", 0)
        wallet = ton.get("wallet", "-")
        memo = ton.get("memo", "ندارد")
        price = ton.get("price", int(amount * TON_PRICE))
        final = compute_final_price(ton, user.id)
        u = get_user(user.id)
        if u["balance"] >= final:
            u["balance"] -= final
            consume_discount_if_applied(ton, user.id)
            apply_referral_commission(user.id, final)
            order_id = new_id()
            u["orders"].append(
                f"💱 خرید ارز تون - به مبلغ {fmt(final)} تومان"
            )
            u["orders"] = u["orders"][-50:]
            context.user_data["pending_ton"] = None
            ORDERS[order_id] = {
                "type": "ton",
                "chat_id": update.effective_chat.id,
                "user_id": user.id,
                "buyer_name": user.full_name,
                "amount": amount,
                "wallet": wallet,
                "memo": memo,
                "price": final,
                "status": "pending",
                "created_at": persian_now_str(),
            }
            save_data()
            await query.edit_message_text(
                ton_success_text(amount, wallet, final, order_id),
                reply_markup=order_success_kb(order_id, "خرید ارز تون", "💱", recipient=wallet),
             parse_mode="HTML")
            if REPORTS_CHANNEL:
                try:
                    await context.bot.send_message(
                        f"@{REPORTS_CHANNEL}",
                        admin_ton_text(user, amount, wallet, memo, final, order_id),
                        reply_markup=admin_order_kb(order_id),
                        parse_mode="HTML",
                    )
                except Exception:
                    logging.exception("خطا در ارسال سفارش تون به کانال گزارشات")
        else:
            shortfall = final - u["balance"]
            context.user_data["topup_origin"] = "invoice"
            context.user_data["last_invoice_shortfall_price"] = final
            await query.edit_message_text(insufficient_text(shortfall), reply_markup=insufficient_kb(), parse_mode="HTML")
        return

    if data == "admin_panel_back":
        context.user_data["state"] = None
        await query.edit_message_text(admin_panel_text(), reply_markup=admin_panel_kb(), parse_mode="HTML")
        return

    if data == "admin_daily_limit":
        await query.edit_message_text(admin_daily_limit_text(), reply_markup=admin_daily_limit_kb(), parse_mode="HTML")
        return

    if data == "admin_daily_limit_back":
        context.user_data["state"] = None
        await query.edit_message_text(admin_daily_limit_text(), reply_markup=admin_daily_limit_kb(), parse_mode="HTML")
        return

    if data == "admin_change_daily_limit":
        context.user_data["state"] = "admin_awaiting_daily_limit"
        await query.edit_message_text(
            admin_ask_daily_limit_text(), reply_markup=admin_daily_limit_ask_kb()
        , parse_mode="HTML")
        return

    if data == "admin_announcement_settings":
        context.user_data["state"] = None
        await query.edit_message_text(admin_announcement_text(), reply_markup=admin_announcement_kb(), parse_mode="HTML")
        return

    if data == "admin_change_announcement":
        context.user_data["state"] = "admin_awaiting_announcement_text"
        await query.edit_message_text(
            "✏️ متن جدید اطلاعیه رو بفرست:", reply_markup=admin_announcement_ask_kb()
        , parse_mode="HTML")
        return

    if data == "admin_profit_menu":
        await query.edit_message_text(admin_profit_menu_text(), reply_markup=admin_profit_menu_kb(), parse_mode="HTML")
        return

    if data == "admin_profit_menu_back":
        context.user_data["state"] = None
        await query.edit_message_text(admin_profit_menu_text(), reply_markup=admin_profit_menu_kb(), parse_mode="HTML")
        return

    if data == "admin_profit_stars":
        await query.edit_message_text(admin_profit_stars_text(), reply_markup=admin_profit_detail_kb("stars"), parse_mode="HTML")
        return

    if data == "admin_profit_ton":
        await query.edit_message_text(admin_profit_ton_text(), reply_markup=admin_profit_detail_kb("ton"), parse_mode="HTML")
        return

    if data == "admin_profit_gift":
        await query.edit_message_text(admin_profit_gift_text(), reply_markup=admin_profit_detail_kb("gift"), parse_mode="HTML")
        return

    if data == "admin_profit_premium":
        await query.edit_message_text(admin_profit_premium_text(), reply_markup=admin_profit_detail_kb("premium"), parse_mode="HTML")
        return

    if data.startswith("admin_set_profit_"):
        product = data[len("admin_set_profit_"):]
        fa_names = {"stars": "استارز", "ton": "تون", "gift": "گیفت استارز", "premium": "پرمیوم"}
        context.user_data["state"] = f"admin_awaiting_profit_{product}"
        await query.edit_message_text(
            admin_ask_profit_text(fa_names.get(product, product)),
            reply_markup=admin_profit_ask_kb(product),
         parse_mode="HTML")
        return

    if data == "admin_reset_confirm":
        await query.edit_message_text(
            "⚠️ هشدار!\n\nاین عمل برگشت‌ناپذیر است.\n"
            "تمام کاربران، موجودی‌ها، سفارش‌ها و داده‌های ذخیره‌شده کاملاً پاک می‌شوند.\n\n"
            "آیا مطمئن هستید؟",
            reply_markup=admin_reset_confirm_kb(),
         parse_mode="HTML")
        return

    if data == "admin_reset_yes":
        USERS.clear()
        USER_NAMES.clear()
        ORDERS.clear()
        TOPUP_REQUESTS.clear()
        PENDING_REFERRALS.clear()
        SUPPORT_TICKETS.clear()
        ADMIN_WAITING_REJECT.clear()
        ADMIN_WAITING_SUPPORT_REPLY.clear()

        try:
            if os.path.exists(DATA_FILE):
                os.remove(DATA_FILE)
        except Exception:
            logging.exception("خطا در پاک کردن فایل داده")
        save_data()
        await query.edit_message_text(
            "✅ تمام داده‌های ربات پاک شد.\n\nکاربران باید دوباره /start بزنند.",
            reply_markup=admin_back_kb(),
         parse_mode="HTML")
        return

    if data == "admin_toggle_bot":
        BOT_ENABLED = not BOT_ENABLED
        save_data()
        await query.edit_message_text(admin_panel_text(), reply_markup=admin_panel_kb(), parse_mode="HTML")
        return

    if data == "admin_toggle_referral_points":
        REFERRAL_POINTS_ENABLED = not REFERRAL_POINTS_ENABLED
        save_data()
        await query.edit_message_text(admin_panel_text(), reply_markup=admin_panel_kb(), parse_mode="HTML")
        return

    if data == "admin_broadcast":
        context.user_data["state"] = "admin_awaiting_broadcast_text"
        await query.edit_message_text(ADMIN_BROADCAST_ASK_TEXT, reply_markup=admin_broadcast_ask_kb(), parse_mode="HTML")
        return

    if data == "admin_broadcast_no":
        context.user_data["state"] = "admin_awaiting_broadcast_text"
        await query.edit_message_text(ADMIN_BROADCAST_ASK_TEXT, reply_markup=admin_broadcast_ask_kb(), parse_mode="HTML")
        return

    if data == "admin_broadcast_yes":
        broadcast_text = context.user_data.get("broadcast_text", "")
        success, fail = 0, 0
        for uid in list(USERS.keys()):
            try:
                await context.bot.send_message(uid, broadcast_message_text(broadcast_text), parse_mode="HTML")
                success += 1
            except Exception:
                fail += 1
        context.user_data["broadcast_text"] = None
        await query.edit_message_text(
            broadcast_done_text(success, fail), reply_markup=admin_back_kb()
        , parse_mode="HTML")
        return

    if data == "admin_view_users":
        await query.edit_message_text(view_users_text(), reply_markup=admin_back_kb(), parse_mode="HTML")
        return

    if data == "admin_price_menu":
        await query.edit_message_text(ADMIN_PRICE_MENU_TEXT, reply_markup=admin_price_menu_kb(), parse_mode="HTML")
        return

    if data == "admin_price_menu_back":
        context.user_data["state"] = None
        await query.edit_message_text(ADMIN_PRICE_MENU_TEXT, reply_markup=admin_price_menu_kb(), parse_mode="HTML")
        return

    if data == "admin_price_giftnft":
        await query.answer("این بخش بزودی فعال می‌شود ⏳", show_alert=True)
        return

    if data == "admin_price_stars":
        await query.edit_message_text(admin_stars_price_text(), reply_markup=admin_stars_price_kb(), parse_mode="HTML")
        return

    if data == "admin_change_stars_price":
        context.user_data["state"] = "admin_awaiting_stars_price"
        await query.edit_message_text(
            admin_ask_stars_price_text(), reply_markup=admin_stars_price_ask_kb()
        , parse_mode="HTML")
        return

    if data == "admin_price_stars_back":
        context.user_data["state"] = None
        await query.edit_message_text(admin_stars_price_text(), reply_markup=admin_stars_price_kb(), parse_mode="HTML")
        return

    if data == "admin_price_ton":
        await query.edit_message_text(admin_ton_price_text(), reply_markup=admin_ton_price_kb(), parse_mode="HTML")
        return

    if data == "admin_change_ton_price":
        context.user_data["state"] = "admin_awaiting_ton_price"
        await query.edit_message_text(
            admin_ask_ton_price_text(), reply_markup=admin_ton_price_ask_kb()
        , parse_mode="HTML")
        return

    if data == "admin_price_ton_back":
        context.user_data["state"] = None
        await query.edit_message_text(admin_ton_price_text(), reply_markup=admin_ton_price_kb(), parse_mode="HTML")
        return

    if data == "admin_price_premium":
        await query.edit_message_text(admin_premium_price_text(), reply_markup=admin_premium_price_kb(), parse_mode="HTML")
        return

    if data == "admin_change_premium_price":
        await query.edit_message_text(
            ADMIN_PREMIUM_PLAN_SELECT_TEXT, reply_markup=admin_premium_plan_select_kb()
        , parse_mode="HTML")
        return

    if data == "admin_price_premium_back":
        context.user_data["state"] = None
        await query.edit_message_text(admin_premium_price_text(), reply_markup=admin_premium_price_kb(), parse_mode="HTML")
        return

    if data in ("admin_premium_plan_3", "admin_premium_plan_6", "admin_premium_plan_12"):
        plan = data.split("_")[-1]
        context.user_data["state"] = f"admin_awaiting_premium_price_{plan}"
        await query.edit_message_text(
            admin_ask_premium_price_text(plan), reply_markup=admin_premium_price_ask_kb()
        , parse_mode="HTML")
        return

    if data == "admin_premium_plan_select_back":
        context.user_data["state"] = None
        await query.edit_message_text(
            ADMIN_PREMIUM_PLAN_SELECT_TEXT, reply_markup=admin_premium_plan_select_kb()
        , parse_mode="HTML")
        return

    if data == "admin_price_giftstars":
        await query.edit_message_text(ADMIN_GIFT_PRICE_LIST_TEXT, reply_markup=admin_gift_price_list_kb(), parse_mode="HTML")
        return

    if data == "admin_gift_price_list_back":
        context.user_data["state"] = None
        await query.edit_message_text(ADMIN_GIFT_PRICE_LIST_TEXT, reply_markup=admin_gift_price_list_kb(), parse_mode="HTML")
        return

    if data.startswith("admin_gift_price_detail_back_"):
        key = data[len("admin_gift_price_detail_back_"):]
        context.user_data["state"] = None
        await query.edit_message_text(
            admin_gift_price_detail_text(key), reply_markup=admin_gift_price_detail_kb(key)
        , parse_mode="HTML")
        return

    if data.startswith("admin_change_gift_price_"):
        key = data[len("admin_change_gift_price_"):]
        context.user_data["state"] = f"admin_awaiting_gift_price_{key}"
        await query.edit_message_text(
            admin_ask_gift_price_text(key), reply_markup=admin_gift_price_ask_kb(key)
        , parse_mode="HTML")
        return

    if data.startswith("admin_gift_price_"):
        key = data[len("admin_gift_price_"):]
        if key in GIFTS:
            await query.edit_message_text(
                admin_gift_price_detail_text(key), reply_markup=admin_gift_price_detail_kb(key)
            , parse_mode="HTML")
        return

    if data == "admin_gift_management":
        await query.edit_message_text(
            "🎀 مدیریت گیفت‌ها\n\n"
            "از گزینه‌های زیر برای مدیریت گیفت‌ها استفاده کنید:",
            reply_markup=admin_gift_management_kb()
        , parse_mode="HTML")
        return

    if data == "admin_gift_management_back":
        await query.edit_message_text(
            "🎀 مدیریت گیفت‌ها\n\n"
            "از گزینه‌های زیر برای مدیریت گیفت‌ها استفاده کنید:",
            reply_markup=admin_gift_management_kb()
        , parse_mode="HTML")
        return

    if data == "admin_add_gift":
        await query.edit_message_text(
            "➕ افزودن گیفت جدید\n\n"
            "فرمت ارسال:\n"
            "<code>key|name|emoji|stars</code>\n\n"
            "مثال:\n"
            "<code>new_gift|هدیه جدید|🎁|30</code>\n\n"
            "⚠️ دقت کنید که key باید یکتا باشد.",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_gift_management_back", "dark"),
            ], row_width=1),
            parse_mode="HTML"
        )
        context.user_data["state"] = "admin_awaiting_add_gift"
        return

    if data == "admin_delete_gift":
        await query.edit_message_text(
            "❌ حذف گیفت\n\n"
            "لطفاً گیفت مورد نظر برای حذف را انتخاب کنید:",
            reply_markup=admin_delete_gift_kb()
        , parse_mode="HTML")
        return

    if data == "admin_delete_gift_back":
        await query.edit_message_text(
            "❌ حذف گیفت\n\n"
            "لطفاً گیفت مورد نظر برای حذف را انتخاب کنید:",
            reply_markup=admin_delete_gift_kb()
        , parse_mode="HTML")
        return

    if data.startswith("admin_delete_gift_"):
        key = data[len("admin_delete_gift_"):]
        if key in GIFTS:
            g = GIFTS[key]
            await query.edit_message_text(
                f"⚠️ آیا از حذف گیفت زیر مطمئن هستید؟\n\n"
                f"{g['emoji']} {g['name']} (⭐️ {g['stars']})\n"
                f"💰 قیمت: {fmt(g['price'])} تومان\n\n"
                "این عمل برگشت‌ناپذیر است.",
                reply_markup=admin_confirm_delete_gift_kb(key)
            , parse_mode="HTML")
        return

    if data.startswith("admin_confirm_delete_"):
        key = data[len("admin_confirm_delete_"):]
        if key in GIFTS:
            g = GIFTS.pop(key)
            save_data()
            await query.edit_message_text(
                f"✅ گیفت {g['emoji']} {g['name']} با موفقیت حذف شد.",
                reply_markup=admin_gift_management_kb()
            , parse_mode="HTML")
        return

    if data == "admin_card_settings":
        await query.edit_message_text(
            "💳 تنظیمات شماره کارت\n\n"
            f"شماره کارت فعلی: <code>{CARD_NUMBER}</code>\n"
            f"نام صاحب کارت: {CARD_HOLDER}\n\n"
            "از گزینه‌های زیر برای تغییر استفاده کنید:",
            reply_markup=admin_card_settings_kb(),
            parse_mode="HTML"
        )
        return

    if data == "admin_change_card_number":
        context.user_data["state"] = "admin_awaiting_card_number"
        await query.edit_message_text(
            "✏️ شماره کارت جدید را وارد کنید:\n\n"
            "مثال: 6037xxxxxxxxxxxx",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_card_settings", "dark"),
            ], row_width=1)
        , parse_mode="HTML")
        return

    if data == "admin_change_card_holder":
        context.user_data["state"] = "admin_awaiting_card_holder"
        await query.edit_message_text(
            "✏️ نام صاحب کارت جدید را وارد کنید:",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_card_settings", "dark"),
            ], row_width=1)
        , parse_mode="HTML")
        return

    if data == "admin_support_settings":
        await query.edit_message_text(
            "💬 تنظیمات پشتیبانی\n\n"
            f"یوزرنیم پشتیبانی ربات: @{SUPPORT_BOT_USERNAME}\n"
            f"یوزرنیم پشتیبانی مالی: @{SUPPORT_FINANCIAL_USERNAME}\n\n"
            "از گزینه‌های زیر برای تغییر استفاده کنید:",
            reply_markup=admin_support_settings_kb(),
            parse_mode="HTML"
        )
        return

    if data == "admin_change_support_bot":
        context.user_data["state"] = "admin_awaiting_support_bot_username"
        await query.edit_message_text(
            "✏️ یوزرنیم پشتیبانی ربات را بدون @ وارد کنید:\n\n"
            "مثال: Eli_as13",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_support_settings", "dark"),
            ], row_width=1)
        , parse_mode="HTML")
        return

    if data == "admin_change_support_financial":
        context.user_data["state"] = "admin_awaiting_support_financial_username"
        await query.edit_message_text(
            "✏️ یوزرنیم پشتیبانی مالی را بدون @ وارد کنید:\n\n"
            "مثال: Eli_as13",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_support_settings", "dark"),
            ], row_width=1)
        , parse_mode="HTML")
        return

    if data == "admin_join_settings":
        await query.edit_message_text(
            "📢 تنظیمات کانال‌ها\n\n"
            f"کانال جوین اجباری: @{REQUIRED_CHANNEL}\n"
            f"کانال گزارشات: @{REPORTS_CHANNEL}\n\n"
            "از گزینه‌های زیر برای تغییر استفاده کنید:",
            reply_markup=admin_join_settings_kb()
        , parse_mode="HTML")
        return

    if data == "admin_change_join_channel":
        context.user_data["state"] = "admin_awaiting_join_channel"
        await query.edit_message_text(
            "✏️ نام کانال جوین اجباری جدید را وارد کنید:\n\n"
            "مثال: GiftIx_1\n"
            "(بدون @ وارد کنید)",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_join_settings", "dark"),
            ], row_width=1)
        , parse_mode="HTML")
        return

    if data == "admin_change_reports_channel":
        context.user_data["state"] = "admin_awaiting_reports_channel"
        await query.edit_message_text(
            "✏️ نام کانال گزارشات جدید را وارد کنید:\n\n"
            "مثال: GiftIx1_Reports\n"
            "(بدون @ وارد کنید)",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_join_settings", "dark"),
            ], row_width=1)
        , parse_mode="HTML")
        return

    if data == "admin_show_join_channel":
        await query.answer(f"کانال فعلی: @{REQUIRED_CHANNEL}", show_alert=True)
        return

    if data == "admin_add_admin":
        context.user_data["state"] = "admin_awaiting_add_admin_id"
        admins_list = "\n".join(f"• <code>{aid}</code>" for aid in sorted(ADMIN_IDS))
        await query.edit_message_text(
            "➕ افزودن ادمین جدید\n\n"
            "آیدی عددی کاربر مورد نظر رو بفرست (یا پیامش رو فوروارد کن).\n"
            "برای گرفتن آیدی عددی می‌تونی از ربات‌هایی مثل @userinfobot کمک بگیری.\n\n"
            f"👑 ادمین‌های فعلی:\n{admins_list}",
            reply_markup=glass_kb([
                glass_button("🔙 بازگشت", "admin_panel_back", "primary"),
            ], row_width=1),
            parse_mode="HTML"
        )
        return

    if data == "admin_user_management":
        context.user_data["state"] = "admin_awaiting_user_manage_id"
        await query.edit_message_text(
            ADMIN_UM_ASK_ID_TEXT,
            reply_markup=admin_back_kb(),
         parse_mode="HTML")
        return

    if data.startswith("admin_um_refresh_"):
        uid = int(data[len("admin_um_refresh_"):])
        await query.edit_message_text(
            user_manage_text(uid), reply_markup=admin_user_manage_kb(uid), parse_mode="HTML"
        )
        return

    if data.startswith("admin_um_setbalance_"):
        uid = int(data[len("admin_um_setbalance_"):])
        context.user_data["state"] = f"admin_um_awaiting_balance_{uid}"
        await query.edit_message_text(
            f"💰 موجودی جدید کاربر <code>{uid}</code> را وارد کنید (تومان):",
            reply_markup=admin_um_back_kb(uid),
            parse_mode="HTML",
        )
        return

    if data.startswith("admin_um_setdiscount_"):
        uid = int(data[len("admin_um_setdiscount_"):])
        context.user_data["state"] = f"admin_um_awaiting_discount_{uid}"
        await query.edit_message_text(
            f"🏷 موجودی تخفیف جدید کاربر <code>{uid}</code> را وارد کنید (تومان):",
            reply_markup=admin_um_back_kb(uid),
            parse_mode="HTML",
        )
        return

    if data.startswith("admin_um_setscore_"):
        uid = int(data[len("admin_um_setscore_"):])
        context.user_data["state"] = f"admin_um_awaiting_score_{uid}"
        await query.edit_message_text(
            f"⭐ امتیاز جدید کاربر <code>{uid}</code> را وارد کنید:",
            reply_markup=admin_um_back_kb(uid),
            parse_mode="HTML",
        )
        return

    if data.startswith("admin_um_toggleban_"):
        uid = int(data[len("admin_um_toggleban_"):])
        u = get_user(uid)
        u["banned"] = not u.get("banned", False)
        save_data()
        await query.edit_message_text(
            user_manage_text(uid), reply_markup=admin_user_manage_kb(uid), parse_mode="HTML"
        )
        return

    if data.startswith("admin_um_toggleadmin_"):
        uid = int(data[len("admin_um_toggleadmin_"):])
        if uid == ADMIN_CHAT_ID:
            await query.answer("❌ نمی‌توان مالک اصلی ربات را از ادمین‌ها حذف کرد.", show_alert=True)
            return
        if uid in ADMIN_IDS:
            ADMIN_IDS.discard(uid)
        else:
            ADMIN_IDS.add(uid)
        save_data()
        await query.edit_message_text(
            user_manage_text(uid), reply_markup=admin_user_manage_kb(uid), parse_mode="HTML"
        )
        return

    if data.startswith("admin_um_orders_"):
        uid = int(data[len("admin_um_orders_"):])
        u = get_user(uid)
        order_ids = u.get("orders", [])
        if not order_ids:
            order_text = f"🧾 کاربر <code>{uid}</code> تاکنون سفارشی ثبت نکرده است."
        else:
            lines = []
            for oid in order_ids[-30:]:
                o = ORDERS.get(oid)
                if o:
                    lines.append(f"• {oid} | {o.get('type', '-')} | {o.get('status', '-')}")
                else:
                    lines.append(f"• {oid}")
            order_text = f"🧾 سفارشات کاربر <code>{uid}</code> ({len(order_ids)} سفارش):\n\n" + "\n".join(lines)
            if len(order_text) > 4000:
                order_text = order_text[:4000] + "\n...و بقیه (بریده شد)"
        await query.edit_message_text(
            order_text, reply_markup=admin_um_back_kb(uid), parse_mode="HTML"
        )
        return

    if data.startswith("admin_um_reset_confirm_"):
        uid = int(data[len("admin_um_reset_confirm_"):])
        if uid in USERS:
            del USERS[uid]
        get_user(uid)
        save_data()
        await query.edit_message_text(
            f"✅ اطلاعات کاربر <code>{uid}</code> ریست شد.\n\n" + user_manage_text(uid),
            reply_markup=admin_user_manage_kb(uid),
            parse_mode="HTML",
        )
        return

    if data.startswith("admin_um_reset_"):
        uid = int(data[len("admin_um_reset_"):])
        await query.edit_message_text(
            f"⚠️ آیا مطمئنید می‌خواهید تمام اطلاعات کاربر <code>{uid}</code> "
            "(موجودی، امتیاز، سفارشات و...) ریست شود؟\n"
            "این عمل برگشت‌ناپذیر است.",
            reply_markup=glass_kb([
                glass_button("✅ بله، ریست شود", f"admin_um_reset_confirm_{uid}", "primary"),
                glass_button("❌ نه، برگرد", f"admin_um_refresh_{uid}", "primary"),
            ], row_width=1),
            parse_mode="HTML",
        )
        return

    if data == "support_direct":
        await query.answer(
            f"ارتباط مستقیم با پشتیبانی از طریق @{SUPPORT_USERNAME}",
            show_alert=True
        )
        return

    if data == "join_channel":
        await query.answer(
            f"لطفاً در کانال @{REQUIRED_CHANNEL} عضو شوید",
            show_alert=True
        )
        return

    if data == "buy_now":
        await query.answer(
            f"برای خرید به ربات @{BOT_USERNAME} مراجعه کنید",
            show_alert=True
        )
        return

async def reset_daily_limits_job(context: ContextTypes.DEFAULT_TYPE) -> None:
    today = today_str()
    for u in USERS.values():
        u["daily_topup_used"] = 0
        u["daily_topup_date"] = today
    logging.info("سقف مجاز شارژ روزانه همه کاربران ریست شد.")

async def update_prices_job(context: ContextTypes.DEFAULT_TYPE) -> None:
    global BASE_TON_PRICE
    if not HAS_HTTPX:
        return
    try:
        async with httpx.AsyncClient(timeout=8) as client:
            r = await client.get(TON_PRICE_API_URL)
            data = r.json()
            price_rls = float(data["stats"]["ton-rls"]["latest"])
            new_base = round(price_rls / 10)
            if new_base > 0 and new_base != BASE_TON_PRICE:
                BASE_TON_PRICE = new_base
                recalc_prices()
                logging.info(f"قیمت تون بروز شد: {fmt(BASE_TON_PRICE)} تومان (پایه) ← {fmt(TON_PRICE)} تومان (فروش)")
    except Exception as e:
        logging.warning(f"خطا در دریافت قیمت تون از API: {e}")

async def update_stars_premium_prices_job(context: ContextTypes.DEFAULT_TYPE) -> None:
    global BASE_STARS_PRICE, BASE_PREMIUM_PRICES
    if not HAS_HTTPX:
        return
    try:
        async with httpx.AsyncClient(timeout=8) as client:
            r = await client.get(USD_TOMAN_API_URL)
            data = r.json()
            usdt_rls = float(data["stats"]["usdt-rls"]["latest"])
            usdt_toman = usdt_rls / 10
        changed = False
        new_stars_base = round(STAR_USD_PRICE * usdt_toman)
        if new_stars_base > 0 and new_stars_base != BASE_STARS_PRICE:
            BASE_STARS_PRICE = new_stars_base
            changed = True
        for plan, usd in PREMIUM_USD_PRICES.items():
            new_val = round(usd * usdt_toman)
            if new_val > 0 and new_val != BASE_PREMIUM_PRICES.get(plan):
                BASE_PREMIUM_PRICES[plan] = new_val
                changed = True
        if changed:
            recalc_prices()
            logging.info(f"قیمت استارز/پرمیوم بروز شد (نرخ دلار: {fmt(round(usdt_toman))} تومان)")
    except Exception as e:
        logging.warning(f"خطا در دریافت نرخ دلار برای آپدیت قیمت استارز/پرمیوم: {e}")

async def autosave_job(context: ContextTypes.DEFAULT_TYPE) -> None:
    save_data()

def main() -> None:
    load_data()
    enable_premium_emojis()

    app = Application.builder().token(BOT_TOKEN).build()
    app.add_handler(CommandHandler("start", start))
    app.add_handler(MessageHandler(filters.CONTACT, contact_handler))
    app.add_handler(MessageHandler(filters.PHOTO, photo_handler))
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, text_handler))
    app.add_handler(CallbackQueryHandler(callback_router))

    if app.job_queue:
        app.job_queue.run_daily(
            reset_daily_limits_job,
            time=dt_time(hour=0, minute=0, second=0, tzinfo=TEHRAN_TZ),
        )

        app.job_queue.run_repeating(autosave_job, interval=120, first=60)

        app.job_queue.run_repeating(update_prices_job, interval=10, first=5)

        app.job_queue.run_repeating(update_stars_premium_prices_job, interval=60, first=8)
    else:
        logging.warning(
            "JobQueue در دسترس نیست؛ ریست خودکار سقف روزانه و ذخیره خودکار فعال نشد. "
            "برای فعال‌سازی نصب کن: pip install \"python-telegram-bot[job-queue]\" --upgrade"
        )

    print("ربات 𝗕𝗹𝗮𝗰𝗸 𝗦𝘁𝗮𝗿𝘀 | گیفت و استارز در حال اجراست... برای توقف Ctrl+C بزن.")
    print(f"داده‌ها در فایل ذخیره می‌شن: {DATA_FILE}")
    app.run_polling()
    save_data()

if __name__ == "__main__":
    main()