import requests
import re
from datetime import datetime
from bs4 import BeautifulSoup
import time
from telegram import Update
from telegram.ext import Application, MessageHandler, filters, ContextTypes

# ============================================================
# 🔑 توکن ربات تلگرام
# ============================================================
TOKEN = "8919061426:AAHl23NSZ0iLkFmRvbumtkcPv9yTx7NgysE"

# ============================================================
# 🔑 توکن API مارکت‌اپ (برای NFT) – از https://marketapp.ws/api-token بگیر
# ============================================================
API_TOKEN_MARKETAPP = "487741-1e85870eb858d02a554fd06bd01a0cb1-1782543375"
BASE_URL = "https://api.marketapp.ws"

# ============================================================
# 🌍 دیکشنری نام‌های مستعار ارزها (همه‌ی موارد قبلی)
# ============================================================
ALIASES = {
    # ارزهای فیات
    "usd": "USD", "دلار": "USD", "دولار": "USD",
    "eur": "EUR", "یورو": "EUR",
    "try": "TRY", "لیر": "TRY",
    
    # ارزهای دیجیتال با نام کوتاه
    "btc": "BTC", "بیت‌کوین": "BTC",
    "eth": "ETH", "اتریوم": "ETH",
    "ltc": "LTC", "لایت": "LTC",
    "xrp": "XRP", "ریپل": "XRP",
    "bch": "BCH", "بیت‌کوین کش": "BCH",
    "bnb": "BNB", "بی‌ان‌بی": "BNB",
    "doge": "DOGE", "داوج": "DOGE",
    "xlm": "XLM", "استلار": "XLM",
    "trx": "TRX", "ترون": "TRX",
    "ada": "ADA", "کاردانو": "ADA",
    "xmr": "XMR", "مونرو": "XMR",
    "etc": "ETC", "اتریوم کلاسیک": "ETC",
    "link": "LINK", "چین لینک": "LINK",
    "dai": "DAI", "دای": "DAI",
    "dot": "DOT", "پولکادات": "DOT",
    "uni": "UNI", "یونی": "UNI",
    "aave": "AAVE", "آوی": "AAVE",
    "sol": "SOL", "سولانا": "SOL",
    "fil": "FIL", "فایل کوین": "FIL",
    "grt": "GRT", "گراف": "GRT",
    "atom": "ATOM", "کازموس": "ATOM",
    "avax": "AVAX", "آوالانچ": "AVAX",
    "axs": "AXS", "اکسی": "AXS",
    "bat": "BAT", "بت": "BAT",
    "mask": "MASK", "ماسک": "MASK",
    "near": "NEAR", "نیر": "NEAR",
    "snx": "SNX", "سینتکسیس": "SNX",
    "yfi": "YFI", "ایفای": "YFI",
    "mana": "MANA", "مانا": "MANA",
    "sand": "SAND", "سند": "SAND",
    "ape": "APE", "ایپ": "APE",
    "wbtc": "WBTC", "رپ بیت‌کوین": "WBTC",
    "usdc": "USDC", "یواس‌دی‌سی": "USDC",
    "algo": "ALGO", "الگورند": "ALGO",
    "gmt": "GMT", "جی‌ام‌تی": "GMT",
    "chz": "CHZ", "چیلیز": "CHZ",
    "qnt": "QNT", "کوانت": "QNT",
    "flow": "FLOW", "فلو": "FLOW",
    "hbar": "HBAR", "هدرا": "HBAR",
    "enj": "ENJ", "انجین": "ENJ",
    "crv": "CRV", "کرو": "CRV",
    "ldo": "LDO", "ال‌دی‌او": "LDO",
    "dydx": "DYDX", "دی‌وای‌دی‌ایکس": "DYDX",
    "apt": "APT", "اپتوس": "APT",
    "bal": "BAL", "بالانسر": "BAL",
    "comp": "COMP", "کامپاند": "COMP",
    "lrc": "LRC", "لوپ رینگ": "LRC",
    "sushi": "SUSHI", "سوشی": "SUSHI",
    "ens": "ENS", "ای‌ان‌اس": "ENS",
    "lpt": "LPT", "لایوپیر": "LPT",
    "one": "ONE", "هارمونی": "ONE",
    "glm": "GLM", "گولم": "GLM",
    "api3": "API3", "ای‌پی‌آی۳": "API3",
    "cvc": "CVC", "سی‌وی‌سی": "CVC",
    "nmr": "NMR", "نامریک": "NMR",
    "storj": "STORJ", "استورج": "STORJ",
    "snt": "SNT", "استATUS": "SNT",
    "slp": "SLP", "اس‌ال‌پی": "SLP",
    "zrx": "ZRX", "زیروایکس": "ZRX",
    "egld": "EGLD", "الیوند": "EGLD",
    "imx": "IMX", "ایمکس": "IMX",
    "blur": "BLUR", "بلور": "BLUR",
    "celr": "CELR", "سلر": "CELR",
    "arb": "ARB", "آربیتروم": "ARB",
    "magic": "MAGIC", "مجیک": "MAGIC",
    "gmx": "GMX", "جی‌ام‌ایکس": "GMX",
    "band": "BAND", "باند": "BAND",
    "cvx": "CVX", "کانوکس": "CVX",
    "gram": "GRAM", "گرام": "GRAM",
    "mdt": "MDT", "ام‌دی‌تی": "MDT",
    "ssv": "SSV", "اس‌اس‌وی": "SSV",
    "wld": "WLD", "ورلدکوین": "WLD",
    "omg": "OMG", "اوام‌جی": "OMG",
    "rdnt": "RDNT", "آردنت": "RDNT",
    "jst": "JST", "جی‌اس‌تی": "JST",
    "bico": "BICO", "بیکو": "BICO",
    "woo": "WOO", "وو": "WOO",
    "skl": "SKL", "اس‌کی‌ال": "SKL",
    "not": "NOT", "نات": "NOT",
    "trb": "TRB", "تی‌آر‌بی": "TRB",
    "agld": "AGLD", "ای‌جی‌ال‌دی": "AGLD",
    "rsr": "RSR", "آر‌اس‌آر": "RSR",
    "ethfi": "ETHFI", "اتریفای": "ETHFI",
    "fet": "FET", "فچ": "FET",
    "aevo": "AEVO", "ایوو": "AEVO",
    "meme": "MEME", "میم": "MEME",
    "uma": "UMA", "یو‌ام‌ای": "UMA",
    "zro": "ZRO", "زیرو": "ZRO",
    "dogs": "DOGS", "داگز": "DOGS",
    "render": "RENDER", "رندر": "RENDER",
    "pol": "POL", "پول": "POL",
    "ondo": "ONDO", "اندو": "ONDO",
    "cati": "CATI", "کتی": "CATI",
    "hmstr": "HMSTR", "هامستر": "HMSTR",
    "eigen": "EIGEN", "ایگن": "EIGEN",
    "paxg": "PAXG", "پکس گلد": "PAXG",
    "xaut": "XAUT", "اکس ات": "XAUT",
    "xtz": "XTZ", "تزوس": "XTZ",
    "ena": "ENA", "ای‌ان‌ای": "ENA",
    "pendle": "PENDLE", "پندل": "PENDLE",
    "ankr": "ANKR", "انکر": "ANKR",
    "jasmy": "JASMY", "جاسمی": "JASMY",
    "super": "SUPER", "سوپر": "SUPER",
    "cake": "CAKE", "کیک": "CAKE",
    "hot": "HOT", "هات": "HOT",
    "edu": "EDU", "ادو": "EDU",
    "major": "MAJOR", "میجر": "MAJOR",
    "safe": "SAFE", "سیف": "SAFE",
    "banana": "BANANA", "بانانا": "BANANA",
    "move": "MOVE", "موو": "MOVE",
    "zil": "ZIL", "زیل": "ZIL",
    "strk": "STRK", "استارک": "STRK",
    "metis": "METIS", "متیس": "METIS",
    "turbo": "TURBO", "توربو": "TURBO",
    "cookie": "COOKIE", "کوکی": "COOKIE",
    "cgpt": "CGPT", "سی‌جی‌پی‌تی": "CGPT",
    "zec": "ZEC", "زیکش": "ZEC",
    "inj": "INJ", "اینکشن": "INJ",
    "dexe": "DEXE", "دکس": "DEXE",
    "ath": "ATH", "ای‌تی‌اچ": "ATH",
    "neiro": "NEIRO", "نیرو": "NEIRO",
    "morpho": "MORPHO", "مورفو": "MORPHO",
    "wif": "WIF", "وی‌آی‌اف": "WIF",
    "ray": "RAY", "ری": "RAY",
    "tnsr": "TNSR", "تی‌ان‌اس‌آر": "TNSR",
    "aixbt": "AIXBT", "ای‌ایکس‌بی‌تی": "AIXBT",
    "kaito": "KAITO", "کایتو": "KAITO",
    "pengu": "PENGU", "پنگو": "PENGU",
    "jup": "JUP", "جی‌یو‌پی": "JUP",
    "pump": "PUMP", "پامپ": "PUMP",
    "layer": "LAYER", "لیر": "LAYER",
    "pnut": "PNUT", "پینات": "PNUT",
    "orca": "ORCA", "اورکا": "ORCA",
    "bome": "BOME", "بوم": "BOME",
    "pyth": "PYTH", "پایت": "PYTH",
    "sui": "SUI", "سوی": "SUI",
    "jto": "JTO", "جی‌تی‌او": "JTO",
    "sei": "SEI", "سی": "SEI",
    "zen": "ZEN", "زن": "ZEN",
    "prom": "PROM", "پرام": "PROM",
    "beamx": "BEAMX", "بیم‌ایکس": "BEAMX",
    "moodeng": "MOODENG", "مودنگ": "MOODENG",
    "hype": "HYPE", "هایپ": "HYPE",
    "zk": "ZK", "زی‌کی": "ZK",
    "dash": "DASH", "دش": "DASH",
    "grass": "GRASS", "گرس": "GRASS",
    "xvs": "XVS", "اکس‌وی‌اس": "XVS",
    "dusk": "DUSK", "داسک": "DUSK",
    "coti": "COTI", "کوتی": "COTI",
    "syn": "SYN", "سین": "SYN",
    "op": "OP", "آپتیمیزم": "OP",
    "usde": "USDE", "یواس‌دی‌ای": "USDE",
    "toshi": "TOSHI", "توشی": "TOSHI",
    "1k_shib": "1K_SHIB",
    "1inch": "1INCH",
    "100k_floki": "100K_FLOKI",
    "1b_babydoge": "1B_BABYDOGE",
    "1m_btt": "1M_BTT",
    "1m_nft": "1M_NFT",
    "1m_pepe": "1M_PEPE",
    "1k_bonk": "1K_BONK",
    "1k_cat": "1K_CAT",
    "1k_cheems": "1K_CHEEMS",
    
    # ارزهای خاص
    "usdt": "USDT", "تتر": "USDT",
    "gold": "GOLD", "طلا": "GOLD",
    "stars": "STARS", "استارز": "STARS",
    "premium": "PREMIUM", "پرمیوم": "PREMIUM"
}

# ============================================================
# 📋 مپ کامل نوبیتکس (همه جفت‌ارزهای پشتیبانی‌شده)
# ============================================================
NOBITEX_PAIRS = {
    "BTC": "BTCIRT",
    "ETH": "ETHIRT",
    "LTC": "LTCIRT",
    "XRP": "XRPIRT",
    "BCH": "BCHIRT",
    "BNB": "BNBIRT",
    "DOGE": "DOGEIRT",
    "XLM": "XLMIRT",
    "TRX": "TRXIRT",
    "ADA": "ADAIRT",
    "XMR": "XMRIRT",
    "ETC": "ETCIRT",
    "LINK": "LINKIRT",
    "DAI": "DAIIRT",
    "DOT": "DOTIRT",
    "UNI": "UNIIRT",
    "AAVE": "AAVEIRT",
    "SOL": "SOLIRT",
    "FIL": "FILIRT",
    "GRT": "GRTIRT",
    "ATOM": "ATOMIRT",
    "AVAX": "AVAXIRT",
    "AXS": "AXSIRT",
    "BAT": "BATIRT",
    "MASK": "MASKIRT",
    "NEAR": "NEARIRT",
    "SNX": "SNXIRT",
    "YFI": "YFIIRT",
    "MANA": "MANAIRT",
    "SAND": "SANDIRT",
    "APE": "APEIRT",
    "WBTC": "WBTCIRT",
    "USDC": "USDCIRT",
    "ALGO": "ALGOIRT",
    "GMT": "GMTIRT",
    "CHZ": "CHZIRT",
    "QNT": "QNTIRT",
    "FLOW": "FLOWIRT",
    "HBAR": "HBARIRT",
    "ENJ": "ENJIRT",
    "CRV": "CRVIRT",
    "LDO": "LDOIRT",
    "DYDX": "DYDXIRT",
    "APT": "APTIRT",
    "BAL": "BALIRT",
    "COMP": "COMPIRT",
    "LRC": "LRCIRT",
    "SUSHI": "SUSHIIRT",
    "ENS": "ENSIRT",
    "LPT": "LPTIRT",
    "ONE": "ONEIRT",
    "GLM": "GLMIRT",
    "API3": "API3IRT",
    "CVC": "CVCIRT",
    "NMR": "NMRIRT",
    "STORJ": "STORJIRT",
    "SNT": "SNTIRT",
    "SLP": "SLPIRT",
    "ZRX": "ZRXIRT",
    "EGLD": "EGLDIRT",
    "IMX": "IMXIRT",
    "BLUR": "BLURIRT",
    "CELR": "CELRIRT",
    "ARB": "ARBIRT",
    "MAGIC": "MAGICIRT",
    "GMX": "GMXIRT",
    "BAND": "BANDIRT",
    "CVX": "CVXIRT",
    "GRAM": "GRAMIRT",
    "MDT": "MDTIRT",
    "SSV": "SSVIRT",
    "WLD": "WLDIRT",
    "OMG": "OMGIRT",
    "RDNT": "RDNTIRT",
    "JST": "JSTIRT",
    "BICO": "BICOIRT",
    "WOO": "WOOIRT",
    "SKL": "SKLIRT",
    "NOT": "NOTIRT",
    "TRB": "TRBIRT",
    "AGLD": "AGLDIRT",
    "RSR": "RSRIRT",
    "ETHFI": "ETHFIIRT",
    "FET": "FETIRT",
    "AEVO": "AEVOIRT",
    "MEME": "MEMEIRT",
    "UMA": "UMAIRT",
    "ZRO": "ZROIRT",
    "DOGS": "DOGSIRT",
    "RENDER": "RENDERIRT",
    "POL": "POLIRT",
    "ONDO": "ONDOIRT",
    "CATI": "CATIIRT",
    "HMSTR": "HMSTRIRT",
    "EIGEN": "EIGENIRT",
    "PAXG": "PAXGIRT",
    "XAUT": "XAUTIRT",
    "XTZ": "XTZIRT",
    "ENA": "ENAIRT",
    "PENDLE": "PENDLEIRT",
    "ANKR": "ANKRIRT",
    "JASMY": "JASMYIRT",
    "SUPER": "SUPERIRT",
    "CAKE": "CAKEIRT",
    "HOT": "HOTIRT",
    "EDU": "EDUIRT",
    "MAJOR": "MAJORIRT",
    "SAFE": "SAFEIRT",
    "BANANA": "BANANAIRT",
    "MOVE": "MOVEIRT",
    "ZIL": "ZILIRT",
    "STRK": "STRKIRT",
    "METIS": "METISIRT",
    "TURBO": "TURBOIRT",
    "COOKIE": "COOKIEIRT",
    "CGPT": "CGPTIRT",
    "ZEC": "ZECIRT",
    "INJ": "INJIRT",
    "DEXE": "DEXEIRT",
    "ATH": "ATHIRT",
    "NEIRO": "NEIROIRT",
    "MORPHO": "MORPHOIRT",
    "WIF": "WIFIRT",
    "RAY": "RAYIRT",
    "TNSR": "TNSRIRT",
    "AIXBT": "AIXBTIRT",
    "KAITO": "KAITOIRT",
    "PENGU": "PENGUIRT",
    "JUP": "JUPIRT",
    "PUMP": "PUMPIRT",
    "LAYER": "LAYERIRT",
    "PNUT": "PNUTIRT",
    "ORCA": "ORCAIRT",
    "BOME": "BOMEIRT",
    "PYTH": "PYTHIRT",
    "SUI": "SUIIRT",
    "JTO": "JTOIRT",
    "SEI": "SEIIRT",
    "ZEN": "ZENIRT",
    "PROM": "PROMIRT",
    "BEAMX": "BEAMXIRT",
    "MOODENG": "MOODENGIRT",
    "HYPE": "HYPEIRT",
    "ZK": "ZKIRT",
    "DASH": "DASHIRT",
    "GRASS": "GRASSIRT",
    "XVS": "XVSIRT",
    "DUSK": "DUSKIRT",
    "COTI": "COTIIRT",
    "SYN": "SYNIRT",
    "OP": "OPIRT",
    "USDE": "USDEIRT",
    "TOSHI": "TOSHIIRT",
    "1K_SHIB": "1K_SHIBIRT",
    "1INCH": "1INCHIRT",
    "100K_FLOKI": "100K_FLOKIIRT",
    "1B_BABYDOGE": "1B_BABYDOGEIRT",
    "1M_BTT": "1M_BTTIRT",
    "1M_NFT": "1M_NFTIRT",
    "1M_PEPE": "1M_PEPEIRT",
    "1K_BONK": "1K_BONKIRT",
    "1K_CAT": "1K_CATIRT",
    "1K_CHEEMS": "1K_CHEEMSIRT",
    "USDT": "USDTIRT",
}

# ============================================================
# 💰 دریافت قیمت از نوبیتکس
# ============================================================
def get_nobitex_price(symbol, retry=2):
    """دریافت قیمت از نوبیتکس با تلاش مجدد"""
    for attempt in range(retry):
        try:
            url = f"https://apiv2.nobitex.ir/v3/orderbook/{symbol}"
            r = requests.get(url, timeout=15)
            
            if r.status_code == 200:
                data = r.json()
                return {
                    "last": float(data["lastTradePrice"]),
                    "buy": float(data["bids"][0][0]),
                    "sell": float(data["asks"][0][0]),
                }
        except Exception as e:
            print(f"Attempt {attempt+1} failed for {symbol}: {e}")
            time.sleep(1)
    
    return None

# ============================================================
# 💵 قیمت دلار به تومان
# ============================================================
def get_usd_toman():
    """دریافت قیمت دلار از نوبیتکس"""
    try:
        data = get_nobitex_price("USDTIRT")
        if data and data["last"] > 0:
            price = data["last"]
            if price > 1000000:
                price = price / 10
            return price
    except:
        pass
    
    return 60000

# ============================================================
# 💰 قیمت ارز دیجیتال به تومان
# ============================================================
def get_crypto_price_toman(symbol):
    """دریافت قیمت ارز دیجیتال از نوبیتکس به تومان"""
    try:
        pair = NOBITEX_PAIRS.get(symbol)
        if not pair:
            return None
        
        data = get_nobitex_price(pair)
        if not data:
            return None
        
        return data["last"]
        
    except Exception as e:
        print(f"Error getting crypto price for {symbol}: {e}")
        return None

# ============================================================
# 📊 دریافت تغییرات قیمت (ساعتی/روزانه)
# ============================================================
def get_price_change(symbol):
    """دریافت درصد تغییرات قیمت در 24 ساعت گذشته"""
    try:
        # دریافت قیمت فعلی
        current_price = get_crypto_price_toman(symbol)
        if not current_price:
            return None
        
        # دریافت قیمت 24 ساعت قبل (از نوبیتکس)
        url = f"https://apiv2.nobitex.ir/v3/stats?srcCurrency={symbol}&dstCurrency=IRT"
        r = requests.get(url, timeout=10)
        
        if r.status_code == 200:
            data = r.json()
            if "stats" in data and data["stats"]:
                # قیمت 24 ساعت قبل
                yesterday_price = float(data["stats"]["24h"]["open"])
                
                # محاسبه درصد تغییرات
                if yesterday_price > 0:
                    change_percent = ((current_price - yesterday_price) / yesterday_price) * 100
                    
                    return {
                        "current": current_price,
                        "yesterday": yesterday_price,
                        "change_percent": change_percent,
                        "change_toman": current_price - yesterday_price
                    }
        
        return None
    except:
        return None

# ============================================================
# 🪙 قیمت طلا به تومان
# ============================================================
def get_gold_price():
    try:
        url = "https://www.tgju.org/profile/geram18"
        headers = {"User-Agent": "Mozilla/5.0"}
        
        r = requests.get(url, headers=headers, timeout=10)
        soup = BeautifulSoup(r.text, "html.parser")
        
        price_span = soup.find("span", {"data-col": "info.last_trade.PDrCotVal"})
        if not price_span:
            price_span = soup.find("td", {"class": "current-price"})
        
        if price_span:
            price_text = price_span.get_text(strip=True)
            return int(price_text.replace(",", "")) / 10
    except:
        pass
    return None

# ============================================================
# 🌍 قیمت فیات به تومان
# ============================================================
def get_fiat_price_toman(symbol):
    try:
        r = requests.get("https://api.exchangerate.host/latest?base=USD", timeout=10).json()
        rate = r["rates"].get(symbol)
        if not rate:
            return None
        usd_toman = get_usd_toman()
        return rate * usd_toman
    except:
        return None

# ============================================================
# 💎 قیمت پرمیوم (نسخه Fragment با تخفیف)
# ============================================================
def get_premium_prices():
    """قیمت پرمیوم از Fragment (با تخفیف)"""
    
    PREMIUM_DATA = {
        "3 ماهه": {
            "usd": 11.99,
            "ton": 7.605758
        },
        "6 ماهه": {
            "usd": 15.99,
            "ton": 10.143126
        },
        "1 ساله": {
            "usd": 28.99,
            "ton": 18.389569
        }
    }
    
    return PREMIUM_DATA

def format_premium(usd_toman):
    """فرمت‌دهی قیمت پرمیوم"""
    
    premium_data = get_premium_prices()
    ton_price_toman = get_crypto_price_toman("TON")
    
    msg = "⭐ Telegram Premium (Fragment)\n\n"
    msg += f"📅 {datetime.now().strftime('%Y/%m/%d | %H:%M:%S')}\n"
    msg += "─" * 30 + "\n\n"
    
    for plan, data in premium_data.items():
        usd_price = data["usd"]
        ton_amount = data["ton"]
        
        if ton_price_toman:
            final_toman = ton_amount * ton_price_toman
        else:
            final_toman = usd_price * usd_toman
        
        msg += f"""📅 {plan}

💵 ${usd_price:.2f}
☺️ {ton_amount} TON
💰 {int(final_toman):,} تومان
────────────
"""
    
    if ton_price_toman:
        msg += f"\n💡 قیمت TON: {int(ton_price_toman):,} تومان"
    msg += "\n💡 خرید از Fragment با تخفیف ۲۰٪"
    
    return msg

# ============================================================
# 🔤 تشخیص ارز
# ============================================================
def detect_currency(text):
    text = text.lower()
    for k, v in ALIASES.items():
        if k in text and len(k) >= 4:
            return v
    for k, v in ALIASES.items():
        if k in text:
            return v
    return None

# ============================================================
# 🔢 استخراج عدد
# ============================================================
def extract_amount(text):
    nums = re.findall(r"\d+\.?\d*", text)
    return float(nums[0]) if nums else None

# ============================================================
# 🧮 ماشین حساب
# ============================================================
def calc(expr):
    try:
        if re.fullmatch(r"[0-9.+\-*/() ]+", expr):
            return eval(expr)
    except:
        pass
    return None

# ============================================================
# 💬 فرمت خروجی جدید (با تغییرات)
# ============================================================
def fmt_with_change(amount, symbol, toman, usd, change_data=None):
    """فرمت‌دهی خروجی با تغییرات قیمت"""
    
    msg = f"💰 {amount} {symbol} = ${usd:.3f}\n"
    msg += f"💶 {int(toman):,} تومان\n\n"
    
    if change_data:
        change_percent = change_data.get("change_percent", 0)
        
        if change_percent >= 0:
            msg += f"📊 درصد تغییرات: {change_percent:.2f}% 🔼\n"
        else:
            msg += f"📊 درصد تغییرات: {change_percent:.2f}% 🔻\n"
        
        # مقدار تغییر به دلار و تومان
        change_toman = change_data.get("change_toman", 0)
        change_usd = change_toman / get_usd_toman() if get_usd_toman() > 0 else 0
        
        if change_toman >= 0:
            msg += f"✅ مقدار سود: ${abs(change_usd):.3f} / {int(abs(change_toman)):,} تومان\n"
        else:
            msg += f"🔻 مقدار ضرر: ${abs(change_usd):.3f} / {int(abs(change_toman)):,} تومان\n"
    
    msg += f"\n🕒 {datetime.now().strftime('%Y/%m/%d | %H:%M:%S')}"
    
    return msg

# ============================================================
# ⭐ استارز
# ============================================================
def stars(amount, usd_toman):
    usd = amount * 0.015
    toman = usd * usd_toman
    return fmt_with_change(amount, "STARS", toman, usd)

# ============================================================
# 🔍 ولت TON
# ============================================================
def extract_ton_address(text):
    m = re.search(r"(EQ|UQ)[A-Za-z0-9_-]{40,}", text)
    return m.group(0) if m else None

def get_ton_wallet(address):
    try:
        r = requests.get(f"https://tonapi.io/v2/accounts/{address}", timeout=10).json()
        balance = int(r.get("balance", 0)) / 1e9
        
        usd_toman = get_usd_toman()
        ton_price_toman = get_crypto_price_toman("TON") or (usd_toman * 2.5)
        
        toman = balance * ton_price_toman
        usd = toman / usd_toman if usd_toman > 0 else 0
        
        return {
            "balance": balance,
            "usd": usd,
            "toman": toman,
            "last": r.get("last_activity_time", "N/A")
        }
    except:
        return None

# ============================================================
# 🆕 توابع مربوط به NFT (با استفاده از marketapp.ws)
# ============================================================
def extract_serial_from_link(link):
    """استخراج شماره سریال از لینک NFT"""
    patterns = [
        r'-(\d+)$',                    # FlyingBroom-3566
        r'item_number[=/](\d+)',
        r'/(\d{3,})$',                 # آخر لینک
        r'#(\d+)',
        r'[-/](\d{3,})',               # هر جایی بعد - یا /
    ]
    for pattern in patterns:
        match = re.search(pattern, link)
        if match:
            return int(match.group(1))
    # آخرین عدد موجود در لینک
    numbers = re.findall(r'\d{3,}', link)
    if numbers:
        return int(numbers[-1])
    return None

def get_gift_info(serial_number):
    url = f"{BASE_URL}/v1/gifts/onsale/"
    headers = {"Authorization": API_TOKEN_MARKETAPP}
    params = {"item_num_from": serial_number, "item_num_to": serial_number}
    try:
        r = requests.get(url, headers=headers, params=params, timeout=15)
        if r.status_code == 200:
            data = r.json()
            items = data.get("items") or data.get("results") or data.get("data", [])
            return items[0] if items else None
        else:
            print("NFT API error:", r.status_code, r.text[:200])
            return None
    except Exception as e:
        print("NFT API exception:", e)
        return None

def clean_model_name(name):
    if not name:
        return None
    return re.sub(r'\s*#\d+$', '', str(name)).strip()

def get_similar_gifts(model, limit=10):
    if not model:
        return []
    url = f"{BASE_URL}/v1/gifts/onsale/"
    headers = {"Authorization": API_TOKEN_MARKETAPP}
    params = {
        "model": model,
        "limit": limit,
        "sort_by": "min_bid_asc"
    }
    try:
        r = requests.get(url, headers=headers, params=params, timeout=15)
        if r.status_code == 200:
            data = r.json()
            return data.get("items") or data.get("results") or data.get("data", [])
    except:
        pass
    return []

# ============================================================
# 🆕 تابع دریافت اطلاعات یوزرنیم از فرگمنت (اضافه شده)
# ============================================================
def get_fragment_username_price(username):
    """دریافت قیمت و وضعیت یوزرنیم از سایت Fragment.com"""
    # تمیز کردن یوزرنیم (اگر کاربر با @ یا لینک کامل وارد کرد)
    username = username.strip().split('/')[-1].replace('@', '')
    
    url = f"https://fragment.com/username/{username}"
    
    # ست کردن User-Agent برای اینکه سایت فرگمنت درخواست رو مسدود نکنه
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Accept-Language': 'en-US,en;q=0.9'
    }
    
    try:
        response = requests.get(url, headers=headers, timeout=10)
        
        if response.status_code == 404:
            return f"❌ یوزرنیم @{username} یافت نشد یا معتبر نیست."
        elif response.status_code != 200:
            return f"❌ خطا در برقراری ارتباط با فرگمنت (کد خطا: {response.status_code})"
            
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # ۱. بررسی وضعیت کلی یوزرنیم (فروخته شده، در حال مزایده، غیرقابل فروش)
        status_element = soup.find('span', class_=re.compile(r'thin-status-value|js-status-value'))
        status_text = status_element.text.strip() if status_element else "نامشخص"
        
        # ۲. پیدا کردن قیمت به TON
        # فرگمنت قیمت‌ها رو معمولاً در المان‌هایی با کلاس icon-ton یا داخل بخش اطلاعات مالی قرار میده
        price_element = soup.find('span', class_='icon-ton')
        
        if price_element:
            # گرفتن متن کنار آیکونِ تون
            price = price_element.parent.text.strip()
            # تمیز کردن متن (حذف کلماتی مثل Bid یا Minimum و فاصله‌های اضافه)
            price = price.replace(' ', ' ').replace('\n', '').strip()
            return f"💎 یوزرنیم: @{username}\n📊 وضعیت: {status_text}\n💰 قیمت/آخرین پیشنهاد: {price}"
            
        # ۳. اگر آیکون مستقیم پیدا نشد، شانس دوم با پیدا کردن متن عددی قیمت
        price_box = soup.find('div', class_='table-cell-value-wide')
        if price_box:
            return f"💎 یوزرنیم: @{username}\n📊 وضعیت: {status_text}\n💰 قیمت: {price_box.text.strip()}"
            
        return f"💎 یوزرنیم: @{username}\n📊 وضعیت: {status_text}\n⚠️ قیمتی برای این یوزرنیم ثبت نشده یا در دسترس نیست (احتمالاً دست صاحبش هست و فروشی نیست)."

    except requests.exceptions.RequestException as e:
        return f"❌ خطا در اتصال به اینترنت: {e}"

# ============================================================
# 🤖 هندلر اصلی (با بخش NFT + تبدیل به تومان + اطلاعات فرگمنت)
# ============================================================
async def handle(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message or not update.message.text:
        return
    
    text = update.message.text.strip()
    
    # =====================================================
    # 1️⃣ بررسی دستور NFT (با پیشوند p یا P)
    # =====================================================
    if text.lower().startswith("p "):
        link = text[2:].strip()
        serial = extract_serial_from_link(link)
        if not serial:
            await update.message.reply_text(
                "❌ شماره سریال در لینک پیدا نشد.\n"
                "مثال: `p https://t.me/nft/FlyingBroom-3566`",
                parse_mode="Markdown"
            )
            return

        result = get_gift_info(serial)
        if not result:
            await update.message.reply_text("🔴 این NFT برای فروش نیست یا اطلاعات آن یافت نشد.")
            return

        price_nano = result.get("price") or result.get("min_bid") or 0
        try:
            price_ton = int(price_nano) / 1_000_000_000
            price_str = f"{price_ton:,.9f} TON"
        except:
            price_ton = 0
            price_str = f"{price_nano}"

        # ======== اضافه شدن قیمت به تومان ========
        ton_price_toman = get_crypto_price_toman("TON")
        if ton_price_toman and price_ton > 0:
            price_toman = price_ton * ton_price_toman
            toman_str = f"💰 قیمت به تومان: {int(price_toman):,} تومان"
        else:
            toman_str = "❌ قیمت TON در دسترس نیست، تومان محاسبه نشد."
        # =========================================

        raw_model = result.get("model") or result.get("name")
        clean_model = clean_model_name(raw_model)

        msg = f"🖼 **اطلاعات NFT**\n"
        msg += f"🔢 شماره سریال: `{serial}`\n"
        msg += f"💰 قیمت: {price_str}\n"
        msg += f"{toman_str}\n"  # اضافه شدن خط تومان
        msg += f"📛 نام: {result.get('name', 'نامشخص')}\n"
        msg += f"👤 فروشنده: `{result.get('seller_address', 'نامشخص')}`\n"
        msg += f"🧩 مدل: `{clean_model}`\n"

        # جستجوی مشابه‌ها
        similars = get_similar_gifts(clean_model, limit=10)
        if similars:
            msg += f"\n🔎 **{len(similars)} مورد مشابه** (ارزان‌ترین):\n"
            for item in similars[:8]:
                p = int(item.get("price") or item.get("min_bid") or 0) / 1_000_000_000
                msg += f"   • #{item.get('item_number')} | {p:,.9f} TON | {item.get('name')}\n"
        else:
            msg += "\n❌ مورد مشابهی پیدا نشد."

        await update.message.reply_text(msg, parse_mode="Markdown")
        return

    # =====================================================
    # 2️⃣ بررسی دستور اطلاعات فرگمنت (با پیشوند info )
    # =====================================================
    if text.lower().startswith("info "):
        # استخراج یوزرنیم بعد از "info "
        match = re.search(r'@?([A-Za-z0-9_]+)', text[5:])  # بعد از "info "
        if match:
            username = match.group(1)
            result = get_fragment_username_price(username)
            await update.message.reply_text(result)
            return
        else:
            await update.message.reply_text("❌ لطفاً یک یوزرنیم معتبر وارد کنید. مثال: `info @euro`", parse_mode="Markdown")
            return

    # =====================================================
    # 3️⃣ ادامه پردازش‌های قبلی (ریاضی، TON، ارز، ...)
    # =====================================================
    try:
        # محاسبه عبارات ریاضی
        c = calc(text)
        if c is not None:
            await update.message.reply_text(f"➡️ {text} = {c}")
            return
        
        # بررسی آدرس TON
        addr = extract_ton_address(text)
        if addr:
            data = get_ton_wallet(addr)
            if not data:
                await update.message.reply_text("❌ ولت پیدا نشد")
                return
            
            msg = f"""🔍 آدرس:

{addr}

☺️ TON: {data['balance']:.8f}

≈ ${data['usd']:.5f} ≈ {int(data['toman']):,} تومان

📊 آخرین تراکنش: {data['last']}
"""
            await update.message.reply_text(msg)
            return
        
        usd_toman = get_usd_toman()
        
        # =========================
        # 🟢 PREMIUM
        # =========================
        if "premium" in text.lower() or "پرمیوم" in text:
            await update.message.reply_text(format_premium(usd_toman))
            return
        
        # بررسی stars
        if "star" in text.lower() or "استار" in text:
            amount = extract_amount(text)
            if amount:
                await update.message.reply_text(stars(amount, usd_toman))
            else:
                await update.message.reply_text("عدد استارز رو وارد کن")
            return
        
        # تشخیص ارز
        symbol = detect_currency(text)
        amount = extract_amount(text)
        
        if not symbol:
            return
        
        # =========================
        # 🟢 GOLD
        # =========================
        if symbol == "GOLD":
            price = get_gold_price()
            if not price:
                await update.message.reply_text("❌ قیمت طلا پیدا نشد")
                return
            
            qty = amount if amount else 1
            total = price * qty
            usd = total / usd_toman if usd_toman > 0 else 0
            
            # دریافت تغییرات طلا
            change_data = get_price_change("GOLD")
            
            await update.message.reply_text(fmt_with_change(qty, "GOLD", total, usd, change_data))
            return
        
        # =========================
        # 🟢 USD / USDT
        # =========================
        if symbol == "USDT" or symbol == "USD":
            qty = amount if amount else 1
            total_toman = usd_toman * qty
            
            await update.message.reply_text(fmt_with_change(qty, "USDT", total_toman, qty))
            return
        
        # =========================
        # 🟢 فیات (EUR, TRY)
        # =========================
        if symbol in ["EUR", "TRY"]:
            price_toman = get_fiat_price_toman(symbol)
            if not price_toman:
                await update.message.reply_text(f"❌ قیمت {symbol} پیدا نشد")
                return
            
            qty = amount if amount else 1
            total_toman = price_toman * qty
            usd = total_toman / usd_toman if usd_toman > 0 else 0
            
            await update.message.reply_text(fmt_with_change(qty, symbol, total_toman, usd))
            return
        
        # =========================
        # 🟢 CRYPTO (همه ارزهای دیجیتال)
        # =========================
        price_toman = get_crypto_price_toman(symbol)
        
        if not price_toman:
            await update.message.reply_text(f"❌ قیمت {symbol} در نوبیتکس پیدا نشد")
            return
        
        qty = amount if amount else 1
        total_toman = price_toman * qty
        usd = total_toman / usd_toman if usd_toman > 0 else 0
        
        # دریافت تغییرات قیمت
        change_data = get_price_change(symbol)
        
        await update.message.reply_text(fmt_with_change(qty, symbol, total_toman, usd, change_data))
        
    except Exception as e:
        print("Error:", e)
        await update.message.reply_text("❌ خطا در پردازش درخواست")

# ============================================================
# 🚀 اجرا
# ============================================================
def main():
    app = Application.builder().token(TOKEN).build()
    app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle))
    
    print("🤖 ربات با موفقیت راه‌اندازی شد!")
    print(f"✅ پشتیبانی از {len(NOBITEX_PAIRS)} جفت‌ارز در نوبیتکس")
    print("✅ نمایش تغییرات قیمت (درصد و مقدار)")
    print("✅ قیمت پرمیوم از Fragment با تخفیف ۲۰٪")
    print("✅ قابلیت NFT با پیشوند `p` یا `P` و نمایش قیمت به تومان")
    print("✅ قابلیت اطلاعات یوزرنیم فرگمنت با `info @username`")
    app.run_polling()

if __name__ == "__main__":
    main()