# -*- coding: utf-8 -*-
"""
███████╗██╗     ██████╗  ██████╗ ██████╗ ██╗ █████╗
██╔════╝██║     ██╔══██╗██╔═══██╗██╔══██╗██║██╔══██╗
█████╗  ██║     ██║  ██║██║   ██║██████╔╝██║███████║
██╔══╝  ██║     ██║  ██║██║   ██║██╔══██╗██║██╔══██║
███████╗███████╗██████╔╝╚██████╔╝██║  ██║██║██║  ██║
╚══════╝╚══════╝╚═════╝  ╚═════╝ ╚═╝  ╚═╝╚═╝╚═╝  ╚═╝
Eldoria MMORPG - Telegram Bot Ultimate v3.0
"""
import logging, random, sqlite3, json, time, datetime, os, base64, struct, requests, math, re , shutil
from telegram import (Update, InlineKeyboardButton, InlineKeyboardMarkup, ParseMode,
                      InputMediaPhoto, ChatAction)
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters,
                          CallbackContext, CallbackQueryHandler)

# ==================== CONFIG ====================
TOKEN = "8624438275:AAH5RbMgQ6WtITdx7m9PP7CgwUz8vGajmBg"
DB_FILE = "/home/wallethu/public_html/bot/eldoria.db"
TON_WALLET = "UQDhL6gaizQEthKHHko2LjYtPmItkb0x-QIbbu5EO654X93t"  # 🔴 آدرس Tonkeeper خود را جایگزین کن
ADMIN_IDS = [8360438534]              # 🔴 عدد تلگرام خود را جایگزین کن
LANGUAGES = ["fa", "en"]
DEFAULT_LANG = "en"

logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger("Eldoria")

# ==================== MULTILANG ====================
# فقط کلیدهای استفاده‌شده در قطعه ۱
TEXTS = {
    "welcome": {"fa": "🏰 به اِلدوریا خوش آمدی، {name}!", "en": "🏰 Welcome to Eldoria, {name}!"},
    "main_menu": {
        "fa": "📍 *{zone}*\n❤️ {hp}/{max_hp}  💧 {mp}/{max_mp}  ⚡ {stamina}%\n⚔️ {atk}  🛡️ {def}\n💰 {gold} طلا  💎 {gems} الماس\n😴 خستگی: {fatigue}%",
        "en": "📍 *{zone}*\n❤️ {hp}/{max_hp}  💧 {mp}/{max_mp}  ⚡ {stamina}%\n⚔️ {atk}  🛡️ {def}\n💰 {gold} gold  💎 {gems} gems\n😴 Fatigue: {fatigue}%"
    },
    "rest_street": {"fa": "😴 روی سنگفرش خوابیدی... ۳۰٪ خستگی کم شد اما ۱۰٪ احتمال دزدی!", "en": "😴 Slept on street... -30% fatigue, 10% theft chance!"},
    "rest_inn": {"fa": "🛏️ در مسافرخانه خوابیدی. خستگی کامل رفع شد. (-{cost} طلا)", "en": "🛏️ Rested at inn. Fatigue fully restored. (-{cost} gold)"},
    # ... بعداً گسترش می‌یابد
}

def t(uid, key, **kwargs):
    """ترجمه بر اساس زبان کاربر"""
    p = get_player(uid)
    lang = p[38] if p and len(p) > 38 and p[38] in LANGUAGES else DEFAULT_LANG
    return TEXTS.get(key, {}).get(lang, key).format(**kwargs)

# ==================== DATABASE ====================
def init_db():
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    # جدول بازیکنان
    c.execute('''CREATE TABLE IF NOT EXISTS players (
        user_id INTEGER PRIMARY KEY, username TEXT,
        class TEXT DEFAULT "شاگرد", subclass TEXT DEFAULT "",
        level INTEGER DEFAULT 1, xp INTEGER DEFAULT 0,
        hp INTEGER DEFAULT 100, max_hp INTEGER DEFAULT 100,
        mp INTEGER DEFAULT 50, max_mp INTEGER DEFAULT 50,
        stamina INTEGER DEFAULT 100, max_stamina INTEGER DEFAULT 100,
        fatigue INTEGER DEFAULT 0,         -- 0 تا 100
        attack INTEGER DEFAULT 10, defense INTEGER DEFAULT 5,
        agility INTEGER DEFAULT 5, intelligence INTEGER DEFAULT 5,
        luck INTEGER DEFAULT 5,
        stat_points INTEGER DEFAULT 0, skill_points INTEGER DEFAULT 0,
        gold INTEGER DEFAULT 100, gems INTEGER DEFAULT 0,
        zone TEXT DEFAULT "ریچ‌تاون", pos_x INTEGER DEFAULT 0, pos_y INTEGER DEFAULT 0,
        weapon TEXT DEFAULT "خنجر فرسوده", armor TEXT DEFAULT "پیراهن کهنه",
        helmet TEXT DEFAULT "", boots TEXT DEFAULT "", ring TEXT DEFAULT "", amulet TEXT DEFAULT "",
        inventory TEXT DEFAULT '[]', quest_log TEXT DEFAULT '[]', quest_progress TEXT DEFAULT '{}',
        skills TEXT DEFAULT '[]', skill_tree TEXT DEFAULT '{}',
        companion TEXT DEFAULT '{}', companion_name TEXT DEFAULT '',
        guild TEXT DEFAULT "", guild_rank TEXT DEFAULT "",
        seed_words TEXT DEFAULT '[]', killed_bosses TEXT DEFAULT '[]',
        last_rest TEXT, last_daily TEXT,
        vip_until TEXT, lens INTEGER DEFAULT 0, keys INTEGER DEFAULT 0,
        loot_boxes_common INTEGER DEFAULT 0, loot_boxes_rare INTEGER DEFAULT 0,
        loot_boxes_legendary INTEGER DEFAULT 0,
        achievements TEXT DEFAULT '[]', titles TEXT DEFAULT '[]',
        language TEXT DEFAULT 'fa', register_date TEXT
    )''')
    # جدول پرداخت‌ها
    c.execute('''CREATE TABLE IF NOT EXISTS payments (
        id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER,
        item TEXT, amount REAL, status TEXT DEFAULT 'pending',
        created_at TEXT, tx_hash TEXT, payment_id TEXT UNIQUE
    )''')
    # جدول گیلدها
    c.execute('''CREATE TABLE IF NOT EXISTS guilds (
        name TEXT PRIMARY KEY, leader INTEGER, members TEXT DEFAULT '[]',
        treasury INTEGER DEFAULT 0, level INTEGER DEFAULT 1
    )''')
    # جدول بازار
    c.execute('''CREATE TABLE IF NOT EXISTS market (
        id INTEGER PRIMARY KEY AUTOINCREMENT, seller_id INTEGER, item_name TEXT,
        item_data TEXT, price INTEGER, listed_at TEXT, sold INTEGER DEFAULT 0
    )''')
    # جدول تصاویر (برای کش کردن)
    c.execute('''CREATE TABLE IF NOT EXISTS images (
        name TEXT PRIMARY KEY, file_id TEXT, upload_date TEXT
    )''')
    conn.commit()
    conn.close()

def get_player(uid):
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT * FROM players WHERE user_id=?", (uid,))
    row = c.fetchone()
    conn.close()
    return row

def create_player(uid, username):
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    now = datetime.datetime.now().isoformat()
    try:
        c.execute("INSERT INTO players (user_id, username, last_rest, last_daily, register_date) VALUES (?,?,?,?,?)",
                  (uid, username, now, now, now))
        conn.commit()
    except:
        pass
    conn.close()

def update_player(uid, **kwargs):
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    for k, v in kwargs.items():
        if k in ('inventory','quest_log','quest_progress','skills','skill_tree','companion',
                 'seed_words','killed_bosses','achievements','titles'):
            v = json.dumps(v, ensure_ascii=False)
        c.execute(f"UPDATE players SET {k} = ? WHERE user_id = ?", (v, uid))
    conn.commit()
    conn.close()

# ==================== GAME DATA (حداقلی) ====================
# مناطق (۳ منطقه اصلی + شهر)
WORLD_MAP = {
    (0,0): {"name_fa":"ریچ‌تاون","name_en":"Richtown","emoji":"🏰","safe":True,
            "image":"richtown.jpg",  # بعداً file_id جایگزین می‌شود
            "inn_cost":10},
    (1,0): {"name_fa":"جنگل زمزمه‌ها","name_en":"Whispering Woods","emoji":"🌲",
            "monsters":["گرگ وحشی","گابلین"],"boss":"دروید خائن","word":"کلمه۱",
            "image":"woods.jpg"},
    (-1,0): {"name_fa":"دشت سوخته","name_en":"Scorched Plains","emoji":"🔥",
             "monsters":["اسکلت آتشین"],"boss":"دیو خاکستر","word":"کلمه۲",
             "image":"plains.jpg"},
    (0,1): {"name_fa":"باتلاق نفرین","name_en":"Cursed Swamp","emoji":"🕷️",
            "monsters":["زالوی غول‌پیکر"],"boss":"ساحره مرداب","word":"کلمه۳",
            "image":"swamp.jpg"},
}

# هیولاها (فقط ۵ نوع)
MONSTERS = {
    "گرگ وحشی": {"name_en":"Wild Wolf","hp":40,"att":12,"def":3,"xp":20,"gold":12,
                 "element":"عادی","loot":["پوست گرگ"]},
    "گابلین": {"name_en":"Goblin","hp":35,"att":14,"def":2,"xp":18,"gold":15,"loot":["گوشواره"]},
    "اسکلت آتشین": {"name_en":"Fire Skeleton","hp":45,"att":16,"def":4,"xp":25,"gold":18,
                     "element":"آتش","loot":["استخوان جادویی"]},
    "زالوی غول‌پیکر": {"name_en":"Giant Leech","hp":55,"att":13,"def":3,"xp":22,"gold":16,
                        "loot":["خون غلیظ"]},
    "عنصر خاکستر": {"name_en":"Ash Elemental","hp":50,"att":10,"def":6,"xp":28,"gold":20,
                     "element":"آتش","loot":["ذغال جادو"]},
}

# باس‌ها (۳ باس)
BOSSES = {
    "دروید خائن": {"name_en":"Treant Druid","hp":200,"att":25,"def":12,
        "phases":[
            {"hp_percent":1.0,"skills":["ریشه‌های خشم"]},
            {"hp_percent":0.5,"skills":["نفرین طبیعت"]},
            {"hp_percent":0.25,"skills":["خشم جنگل"]}
        ],"xp":300,"gold":150,"word":"کلمه۱","loot":["چوب جادو"],"image":"druid.jpg"},
    "دیو خاکستر": {"name_en":"Ash Demon","hp":250,"att":30,"def":10,
        "phases":[
            {"hp_percent":1.0,"skills":["نفس آتش"]},
            {"hp_percent":0.5,"skills":["سپر خاکستر"]}
        ],"xp":350,"gold":180,"word":"کلمه۲","loot":["قلب خاکستر"],"image":"demon.jpg"},
    "ساحره مرداب": {"name_en":"Swamp Witch","hp":220,"att":22,"def":8,
        "phases":[
            {"hp_percent":1.0,"skills":["نفرین مرداب"]},
            {"hp_percent":0.5,"skills":["احضار زالو"]}
        ],"xp":320,"gold":160,"word":"کلمه۳","loot":["گردنبند"],"image":"witch.jpg"},
}

# کلاس‌ها (۲ کلاس برای شروع)
CLASSES = {
    "نکرومانسر": {"fa":"نکرومانسر","en":"Necromancer","desc_fa":"احضارگر مرگ",
                  "skills":["استخوان خاردار","نفرین ضعف"]},
    "پالادین": {"fa":"پالادین","en":"Paladin","desc_fa":"جنگجوی مقدس",
                "skills":["ضربه مقدس","سپر ایمان"]},
}

SKILLS_DB = {
    "استخوان خاردار": {"mp":15,"dmg_mult":1.8,"effect":"bleed","cooldown":0},
    "نفرین ضعف": {"mp":20,"dmg_mult":0.5,"effect":"weak","cooldown":2},
    "ضربه مقدس": {"mp":12,"dmg_mult":1.6,"effect":None,"cooldown":0},
    "سپر ایمان": {"mp":25,"dmg_mult":0,"effect":"shield","cooldown":3},
}

# لوت‌باکس‌ها
LOOT_BOXES = {
    "common": {"name_fa":"جعبه معمولی","name_en":"Common Box","price_ton":0.5,"price_gold":200,
               "drops":["معجون کوچک","سکه نقره","گردنبند","پوست","سنگ آهن"]},
    "rare": {"name_fa":"جعبه کمیاب","name_en":"Rare Box","price_ton":1.5,"price_gold":600,
             "drops":["شمشیر آهنی","زره چرمی","معجون بزرگ","حلقه قدرت"]},
    "legendary": {"name_fa":"جعبه افسانه‌ای","name_en":"Legendary Box","price_ton":5,"price_gold":2000,
                  "drops":["شمشیر اژدها","زره اژدها","تخم اژدها","کتاب مهارت"]},
}

# مأموریت‌ها (۱ مأموریت نمونه)
QUESTS = [
    {"id":"q1","title_fa":"گرگ‌های گرسنه","title_en":"Hungry Wolves",
     "desc_fa":"۵ گرگ در جنگل بکش.","objective":{"type":"kill","target":"گرگ وحشی","count":5},
     "reward_xp":100,"reward_gold":50,"reward_item":"شمشیر آهنی"},
]

# ==================== HELPER: IMAGE ====================
def get_image_file_id(name):
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT file_id FROM images WHERE name=?", (name,))
    row = c.fetchone()
    conn.close()
    return row[0] if row else None

def set_image_file_id(name, file_id):
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("REPLACE INTO images (name, file_id, upload_date) VALUES (?,?,?)",
              (name, file_id, datetime.datetime.now().isoformat()))
    conn.commit()
    conn.close()

# ==================== FATIGUE & REST ====================
def apply_fatigue(uid, amount):
    """افزایش خستگی (۰ تا ۱۰۰)"""
    p = get_player(uid)
    new_fatigue = min(100, p[16] + amount)
    update_player(uid, fatigue=new_fatigue)
    # اگر خستگی > 80، کاهش استقامت
    if new_fatigue >= 80:
        stamina_penalty = int(p[8] * 0.2)
        update_player(uid, stamina=max(10, p[8] - stamina_penalty))
    return new_fatigue

def rest(uid, place="street"):
    """استراحت در مکان مشخص"""
    p = get_player(uid)
    if place == "inn":
        zone = WORLD_MAP.get((p[17], p[18]))
        cost = zone.get("inn_cost", 10) if zone else 10
        if p[13] < cost:
            return "💰 پول کافی نداری!"
        update_player(uid, gold=p[13]-cost, fatigue=0, stamina=p[8])  # بازیابی کامل
        return f"🛏️ در مسافرخانه استراحت کردی. خستگی برطرف شد. (-{cost} طلا)"
    else:  # street
        new_fatigue = max(0, p[16] - 30)
        update_player(uid, fatigue=new_fatigue)
        msg = "😴 روی سنگفرش خوابیدی. خستگی ۳۰٪ کم شد."
        if random.random() < 0.1:  # 10% دزدی
            stolen = int(p[13] * 0.2)
            new_gold = max(0, p[13] - stolen)
            update_player(uid, gold=new_gold)
            msg += f"\n⚠️ دزدها {stolen} طلا دزدیدند!"
        return msg

# ==================== CORE HANDLERS ====================
def start(update: Update, context: CallbackContext):
    uid = update.effective_user.id
    uname = update.effective_user.username or "ماجراجو"
    if not get_player(uid):
        create_player(uid, uname)
    # ارسال پیام خوش‌آمدگویی با تصویر (در صورت وجود)
    welcome_text = t(uid, "welcome", name=uname)
    # تلاش برای ارسال عکس ریچ‌تاون
    image_id = get_image_file_id("richtown.jpg")
    if image_id:
        context.bot.send_photo(chat_id=update.effective_chat.id, photo=image_id, caption=welcome_text)
    else:
        update.message.reply_text(welcome_text)
    show_main_v5(update, context)

def show_main_v5(update: Update, context: CallbackContext, edit=False):
    uid = update.effective_user.id
    p = get_player(uid)
    if not p: return
    zone_data = WORLD_MAP.get((p[17], p[18]), WORLD_MAP[(0,0)])
    lang = p[38] if p[38] else DEFAULT_LANG
    zone_name = zone_data.get(f"name_{lang}", zone_data["name_fa"])
    emoji = zone_data["emoji"]
    text = t(uid, "main_menu",
             zone=f"{emoji} {zone_name}",
             hp=p[6], max_hp=p[7], mp=p[8], max_mp=p[9],
             stamina=p[10], atk=p[12], def_stat=p[13],
             gold=p[15], gems=p[16], fatigue=p[16])
    # کیبورد
    kb = []
    if zone_data.get("safe"):
        kb.extend([
            [InlineKeyboardButton("🧭 کاوش", callback_data="move_menu")],
            [InlineKeyboardButton("😴 استراحت", callback_data="rest_menu")],
            [InlineKeyboardButton("📦 جعبه‌ها", callback_data="lootbox_menu")],
            [InlineKeyboardButton("⚒️ کاردستی", callback_data="craft")],
            [InlineKeyboardButton("📜 مأموریت", callback_data="quests")],
            [InlineKeyboardButton("🏪 فروشگاه", callback_data="store")],
            [InlineKeyboardButton("⚔️ آرنا (بزودی)", callback_data="arena")],
            [InlineKeyboardButton("👤 پروفایل", callback_data="profile")],
        ])
    else:
        kb.extend([
            [InlineKeyboardButton("⚔️ شکار", callback_data="hunt")],
            [InlineKeyboardButton("🧭 حرکت", callback_data="move_menu")],
            [InlineKeyboardButton("🏃 بازگشت سریع", callback_data="recall")],
            [InlineKeyboardButton("😴 چرت کوتاه", callback_data="rest_street")],
        ])
    reply_markup = InlineKeyboardMarkup(kb)
    if edit and update.callback_query:
        update.callback_query.edit_message_text(text, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN)
    else:
        update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN)

def button_handler(update: Update, context: CallbackContext):
    query = update.callback_query
    query.answer()
    data = query.data
    uid = query.from_user.id
    p = get_player(uid)
    if not p: return

    if data == "move_menu":
        # نمایش دکمه‌های حرکت (در قطعه بعد کامل می‌شود)
        pass
    elif data == "rest_menu":
        # منوی استراحت
        kb = [
            [InlineKeyboardButton("🛏️ مسافرخانه (۱۰ طلا)", callback_data="rest_inn")],
            [InlineKeyboardButton("😴 خیابان (رایگان)", callback_data="rest_street")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("کجا استراحت می‌کنی؟", reply_markup=InlineKeyboardMarkup(kb))
    elif data == "rest_inn":
        msg = rest(uid, "inn")
        query.edit_message_text(msg)
    elif data == "rest_street":
        msg = rest(uid, "street")
        query.edit_message_text(msg)
    elif data == "lootbox_menu":
        # نمایش جعبه‌ها
        kb = [
            [InlineKeyboardButton("📦 جعبه معمولی (0.5 TON)", callback_data="buy_loot_common")],
            [InlineKeyboardButton("📦 جعبه کمیاب (1.5 TON)", callback_data="buy_loot_rare")],
            [InlineKeyboardButton("📦 جعبه افسانه‌ای (5 TON)", callback_data="buy_loot_legendary")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("🎁 یک جعبه انتخاب کن:", reply_markup=InlineKeyboardMarkup(kb))
    elif data.startswith("buy_loot_"):
        box_type = data.split("_")[2]
        # روند پرداخت TON (در قطعه بعد پیاده‌سازی می‌شود)
        query.edit_message_text(f"پرداخت برای {box_type}...")
    elif data == "back_main":
        show_main_v5(update, context, edit=True)
    else:
        query.edit_message_text("این بخش در دست ساخت است...")
    # ==================== قطعه ۲: حرکت، نبرد، باس‌ها، لوت‌باکس و فروشگاه ====================
# این بخش باید پس از قطعه ۱ (پایان تابع main) قرار گیرد، اما توابع را قبل از main اضافه کنید.
# برای سادگی، توابع جدید را اینجا می‌نویسم. در فایل خود، آن‌ها را به بخش مناسب منتقل کنید.

# -------------------- حرکت روی نقشه --------------------
def move_menu(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    x, y = p[17], p[18]
    kb = [
        [InlineKeyboardButton("⬆️ شمال", callback_data=f"move_{x}_{y-1}"),
         InlineKeyboardButton("⬇️ جنوب", callback_data=f"move_{x}_{y+1}")],
        [InlineKeyboardButton("⬅️ غرب", callback_data=f"move_{x-1}_{y}"),
         InlineKeyboardButton("شرق ➡️", callback_data=f"move_{x+1}_{y}")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    query.edit_message_text("🧭 به کدام سو می‌روی؟", reply_markup=InlineKeyboardMarkup(kb))

def move(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    _, new_x, new_y = query.data.split("_")
    new_x, new_y = int(new_x), int(new_y)
    zone = WORLD_MAP.get((new_x, new_y))
    if not zone:
        query.edit_message_text("🚫 این راه مسدود است.")
        return
    # انتقال
    update_player(uid, pos_x=new_x, pos_y=new_y, zone=zone["name_fa"])
    # اگر منطقه امن نیست، کمی خستگی اضافه شود
    if not zone.get("safe"):
        apply_fatigue(uid, 5)  # ۵٪ خستگی برای سفر
    show_main_v5(update, context, edit=True)

# -------------------- سیستم نبرد --------------------
def hunt(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    if p[10] <= 0:  # stamina
        query.edit_message_text("😴 خیلی خسته‌ای! اول استراحت کن.")
        return
    zone = WORLD_MAP.get((p[17], p[18]), {})
    # شانس باس ۱۰٪
    if "boss" in zone and random.random() < 0.1:
        boss_name = zone["boss"]
        boss = BOSSES[boss_name].copy()
        boss["name"] = boss_name
        boss["current_hp"] = boss["hp"]
        boss["is_boss"] = True
        context.user_data["monster"] = boss
        text = f"💀 *{boss_name}* (BOSS) ظاهر شد!\n❤️ {boss['hp']} | ⚔️ {boss['att']}\nچه می‌کنی؟"
    else:
        monster_name = random.choice(zone.get("monsters", ["موجود ناشناخته"]))
        monster = MONSTERS[monster_name].copy()
        monster["name"] = monster_name
        monster["current_hp"] = monster["hp"]
        monster["is_boss"] = False
        context.user_data["monster"] = monster
        text = f"⚔️ یک *{monster_name}* ظاهر شد.\n❤️ {monster['hp']} | ⚔️ {monster['att']}\nچه می‌کنی؟"
    # مصرف استقامت
    update_player(uid, stamina=max(0, p[10]-10))
    keyboard = [
        [InlineKeyboardButton("⚡ حمله", callback_data="combat_attack")],
        [InlineKeyboardButton("🔥 مهارت", callback_data="skill_menu")],
        [InlineKeyboardButton("🧪 آیتم", callback_data="combat_item")],
        [InlineKeyboardButton("🏃 فرار", callback_data="combat_flee")]
    ]
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode=ParseMode.MARKDOWN)

def skill_menu(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    skills = json.loads(p[24]) if p[24] else []
    if not skills:
        query.edit_message_text("هنوز مهارتی یاد نگرفتی! در آموزشگاه (بزودی) می‌توانی یاد بگیری.")
        return
    kb = []
    for skill_name in skills:
        skill = SKILLS_DB.get(skill_name)
        if skill:
            kb.append([InlineKeyboardButton(f"{skill_name} (MP:{skill['mp']})", callback_data=f"use_skill_{skill_name}")])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="back_combat")])
    query.edit_message_text("🔥 مهارتت را انتخاب کن:", reply_markup=InlineKeyboardMarkup(kb))

def combat_action(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    data = query.data
    if data == "combat_attack":
        msg, ended = combat_turn(uid, "attack", context=context)
    elif data.startswith("use_skill_"):
        skill = data.replace("use_skill_", "")
        msg, ended = combat_turn(uid, "skill", skill_name=skill, context=context)
    elif data == "combat_item":
        msg, ended = combat_turn(uid, "item", context=context)
    elif data == "combat_flee":
        msg, ended = combat_turn(uid, "flee", context=context)
    else:
        return
    if ended:
        keyboard = [[InlineKeyboardButton("🔙 ادامه", callback_data="back_main")]]
    else:
        keyboard = [
            [InlineKeyboardButton("⚡ حمله", callback_data="combat_attack")],
            [InlineKeyboardButton("🔥 مهارت", callback_data="skill_menu")],
            [InlineKeyboardButton("🧪 آیتم", callback_data="combat_item")],
            [InlineKeyboardButton("🏃 فرار", callback_data="combat_flee")]
        ]
    query.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode=ParseMode.MARKDOWN)

def combat_turn(uid, action, skill_name=None, context=None):
    p = get_player(uid)
    monster = context.user_data.get("monster")
    if not monster:
        return "⚔️ نبرد تمام شده است.", True

    # مقادیر بازیکن
    player = {
        "hp": p[6], "max_hp": p[7], "mp": p[8], "max_mp": p[9],
        "att": p[10], "def": p[11], "agi": p[12], "int": p[13], "luck": p[14],
        "status": json.loads(p[24]) if p[24] else {}  # وضعیت‌ها (فعلاً ساده)
    }
    monster_status = monster.get("status", {})

    msg = ""
    # نوبت بازیکن
    if action == "attack":
        dmg, result = calculate_damage(player, monster)
        monster["current_hp"] -= dmg
        msg = f"⚡ حمله {dmg} ({result}) ❤️ هیولا: {monster['current_hp']}/{monster['hp']}"
        if monster["current_hp"] <= 0:
            return end_combat(uid, context, True), True
    elif action == "skill":
        skill = SKILLS_DB.get(skill_name)
        if not skill:
            return "مهارت نامعتبر.", False
        if player["mp"] < skill["mp"]:
            return "⛔ مانا کافی نیست.", False
        dmg, result = calculate_damage(player, monster, skill)
        monster["current_hp"] -= dmg
        new_mp = player["mp"] - skill["mp"]
        update_player(uid, mp=new_mp)
        msg = f"🔥 *{skill_name}* : {dmg} ({result}) ❤️ هیولا: {monster['current_hp']}/{monster['hp']} (-{skill['mp']} MP)"
        if skill["effect"]:
            apply_status(monster, skill["effect"])
        if monster["current_hp"] <= 0:
            return end_combat(uid, context, True), True
    elif action == "item":
        inv = json.loads(p[22])
        if "معجون سلامتی" in inv:
            heal = 40
            new_hp = min(player["hp"] + heal, player["max_hp"])
            update_player(uid, hp=new_hp)
            inv.remove("معجون سلامتی")
            update_player(uid, inventory=inv)
            msg = f"🧪 معجون نوشیدی. +{heal} ❤️ {new_hp}/{player['max_hp']}"
        else:
            return "معجونی نداری!", False
    elif action == "flee":
        if random.random() < 0.3:
            context.user_data.pop("monster", None)
            return "🏃 فرار کردی!", True
        else:
            msg = "❌ فرار ناموفق!"
            # هیولا حمله می‌کند (مانند زیر)
            m_dmg, _ = calculate_damage(monster, player)
            new_hp = player["hp"] - m_dmg
            update_player(uid, hp=new_hp)
            msg += f"\n👊 {monster['name']} {m_dmg} ضربه زد. ❤️ تو: {new_hp}/{player['max_hp']}"
            if new_hp <= 0:
                update_player(uid, hp=0)
                context.user_data.pop("monster", None)
                # جریمه مرگ: ۲۰٪ طلا
                penalty = int(p[13] * 0.2)
                update_player(uid, gold=p[13] - penalty)
                return f"💀 مُردی! {penalty} طلا از دست دادی و به شهر برگشتی.", True
            return msg, False

    # نوبت هیولا
    if monster.get("status", {}).get("stun", 0) > 0:
        monster["status"]["stun"] -= 1
        msg += "\n💫 هیولا گیج است."
    else:
        m_dmg, _ = calculate_damage(monster, player)
        new_hp = player["hp"] - m_dmg
        update_player(uid, hp=new_hp)
        msg += f"\n👊 {monster['name']} {m_dmg} ضربه زد. ❤️ تو: {new_hp}/{player['max_hp']}"
        if new_hp <= 0:
            update_player(uid, hp=0)
            context.user_data.pop("monster", None)
            penalty = int(p[13] * 0.2)
            update_player(uid, gold=p[13] - penalty)
            return f"💀 مُردی! {penalty} طلا از دست دادی و به شهر برگشتی.", True
    context.user_data["monster"] = monster
    return msg, False

def calculate_damage(attacker, defender, skill=None):
    # محاسبه خسارت پایه
    atk = attacker["att"]
    defense = defender.get("def", 0)
    dmg_mult = 1.0
    if skill:
        dmg_mult = skill.get("dmg_mult", 1.0)
    crit = False
    if random.random() < 0.1 + attacker.get("luck", 5) * 0.01:
        dmg_mult *= 1.5
        crit = True
    raw = max(1, (atk - defense * 0.5) * dmg_mult)
    return int(raw), "crit" if crit else "normal"

def apply_status(target, effect):
    status = target.get("status", {})
    if effect == "bleed":
        status["bleed"] = 3
    elif effect == "poison":
        status["poison"] = 3
    elif effect == "stun":
        status["stun"] = 1
    elif effect == "shield":
        status["shield"] = 3
    target["status"] = status

def end_combat(uid, context, victory):
    p = get_player(uid)
    monster = context.user_data.pop("monster", None)
    if not monster:
        return "خطا"
    if not victory:
        return "شکست خوردی..."
    xp = monster["xp"]
    gold = monster["gold"]
    # بررسی باس و کلمه
    boss = None
    for coord, zone in WORLD_MAP.items():
        if zone.get("boss") == monster["name"]:
            boss = zone
            break
    if boss and "word" in boss:
        seed_words = json.loads(p[23])
        if boss["word"] not in seed_words:
            seed_words.append(boss["word"])
            update_player(uid, seed_words=seed_words)
    # افزایش XP و طلا
    new_xp = p[5] + xp
    lvl_up = False
    if new_xp >= p[4] * 100:
        new_xp -= p[4] * 100
        new_level = p[4] + 1
        update_player(uid, level=new_level, xp=new_xp,
                      stat_points=p[14] + 5, skill_points=p[15] + 2,
                      hp=p[7], mp=p[9])  # بازیابی کامل
        lvl_up = True
    else:
        update_player(uid, xp=new_xp, gold=p[13] + gold)
    # افزایش خستگی بعد از نبرد
    apply_fatigue(uid, 10)
    msg = f"🎉 {monster['name']} کشته شد! +{xp} XP, +{gold} طلا."
    if lvl_up:
        msg += f"\n🌟 سطح {new_level}! ۵ امتیاز آمار و ۲ امتیاز مهارت دریافت کردی."
    if boss and "word" in boss:
        msg += f"\n🔮 کلمه گنج *{boss['word']}* را به دست آوردی!"
    return msg

# -------------------- لوت‌باکس و فروشگاه TON --------------------
def buy_lootbox(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    box_type = query.data.split("_")[2]  # common, rare, legendary
    box = LOOT_BOXES[box_type]
    price = box["price_ton"]
    payment_id = base64.b64encode(random.getrandbits(128).to_bytes(16, 'big')).decode()[:16]
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("INSERT INTO payments (user_id, item, amount, payment_id, created_at) VALUES (?,?,?,?,?)",
              (uid, f"lootbox_{box_type}", price, payment_id, datetime.datetime.now().isoformat()))
    conn.commit()
    conn.close()
    msg = (f"💸 *پرداخت TON برای {box['name_fa']}*\n"
           f"مبلغ: `{price}` TON\n"
           f"آدرس: `{TON_WALLET}`\n"
           f"کد پیگیری: `{payment_id}`\n\n"
           "بعد از پرداخت، دکمه زیر را بزن.")
    keyboard = [[InlineKeyboardButton("✅ پرداخت کردم", callback_data=f"check_loot_{box_type}_{payment_id}")],
                [InlineKeyboardButton("🔙 لغو", callback_data="back_main")]]
    query.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode=ParseMode.MARKDOWN)

def check_lootbox_payment(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    data = query.data.split("_")
    box_type = data[2]
    payment_id = data[3]
    # بررسی تراکنش (مشابه قبل، اما اینجا ساده شده)
    # این بخش از کد بررسی تراکنش TON Center v2 را فرض می‌کنیم که موجود است
    paid = check_ton_payment(payment_id, LOOT_BOXES[box_type]["price_ton"])
    if paid:
        # اعطای آیتم تصادفی
        drops = LOOT_BOXES[box_type]["drops"]
        item_won = random.choice(drops)
        inv = json.loads(get_player(uid)[22])
        inv.append(item_won)
        update_player(uid, inventory=inv)
        # به‌روزرسانی payment
        conn = sqlite3.connect(DB_FILE)
        c = conn.cursor()
        c.execute("UPDATE payments SET status='paid' WHERE payment_id=?", (payment_id,))
        conn.commit()
        conn.close()
        query.edit_message_text(f"🎁 جعبه باز شد! *{item_won}* به اینونتوری اضافه شد.")
    else:
        query.edit_message_text("⏳ پرداخت هنوز تأیید نشده. صبر کن یا دوباره تلاش کن.")

def check_ton_payment(payment_id, expected_amount):
    url = f"https://toncenter.com/api/v2/getTransactions?address={TON_WALLET}&limit=20&to_lt=0&archival=false"
    try:
        r = requests.get(url, timeout=10)
        txs = r.json().get("result", [])
    except:
        return False
    for tx in txs:
        in_msg = tx.get("in_msg", {})
        if not in_msg: continue
        value = int(in_msg.get("value", "0")) / 1e9
        comment = ""
        msg_body = in_msg.get("message")
        if msg_body:
            try:
                raw = base64.b64decode(msg_body)
                if len(raw) >= 4 and struct.unpack(">I", raw[:4])[0] == 0:
                    comment = raw[4:].decode('utf-8', 'ignore')
            except:
                pass
        if comment == payment_id and abs(value - expected_amount) < 0.01:
            return True
    return False

# -------------------- اینونتوری و تجهیز --------------------
def show_inventory(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    inv = json.loads(p[22])
    if not inv:
        query.edit_message_text("🎒 کوله‌پشتی خالی است.")
        return
    text = "🎒 *کوله‌پشتی:*\n"
    for idx, item in enumerate(inv):
        text += f"{idx+1}. {item}\n"
    # افزودن دکمه برای تجهیز (در صورت قابل تجهیز بودن)
    kb = []
    for item in inv:
        if item in ["شمشیر آهنی", "زره چرمی", "حلقه قدرت"]:  # فرضی
            kb.append([InlineKeyboardButton(f"⚔️ تجهیز {item}", callback_data=f"equip_{item}")])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")])
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def equip_item(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    item_name = query.data.replace("equip_", "")
    p = get_player(uid)
    inv = json.loads(p[22])
    if item_name not in inv:
        query.edit_message_text("این آیتم در کوله‌پشتی نیست.")
        return
    # تجهیز اسلحه یا زره (ساده)
    if "شمشیر" in item_name:
        old_weapon = p[19]
        update_player(uid, weapon=item_name)
        inv.remove(item_name)
        if old_weapon != "خنجر فرسوده":
            inv.append(old_weapon)
    elif "زره" in item_name:
        old_armor = p[20]
        update_player(uid, armor=item_name)
        inv.remove(item_name)
        if old_armor != "پیراهن کهنه":
            inv.append(old_armor)
    elif "حلقه" in item_name:
        old_ring = p[22]  # ring field index? نیاز به تطبیق دارد، اینجا ساده‌سازی می‌کنیم
        # ...
        pass
    update_player(uid, inventory=inv)
    query.edit_message_text(f"✅ {item_name} تجهیز شد.")

# -------------------- به‌روزرسانی button_handler --------------------
# در تابع button_handler موجود، این شرط‌ها باید اضافه شوند (یا جایگزین):
# (کد زیر را می‌توانید به button_handler قبلی اضافه کنید)

def extended_button_handler(update, context):
    query = update.callback_query
    query.answer()
    data = query.data
    uid = query.from_user.id
    p = get_player(uid)
    if not p: return

    if data == "move_menu":
        move_menu(update, context)
    elif data.startswith("move_"):
        move(update, context)
    elif data == "hunt":
        hunt(update, context)
    elif data == "skill_menu":
        skill_menu(update, context)
    elif data.startswith("use_skill_"):
        combat_action(update, context)
    elif data.startswith("combat_"):
        combat_action(update, context)
    elif data == "rest_menu":
        # از قطعه اول
        kb = [
            [InlineKeyboardButton("🛏️ مسافرخانه (۱۰ طلا)", callback_data="rest_inn")],
            [InlineKeyboardButton("😴 خیابان (رایگان)", callback_data="rest_street")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("کجا استراحت می‌کنی؟", reply_markup=InlineKeyboardMarkup(kb))
    elif data in ("rest_inn", "rest_street"):
        place = "inn" if data == "rest_inn" else "street"
        msg = rest(uid, place)
        query.edit_message_text(msg)
    elif data == "lootbox_menu":
        kb = [
            [InlineKeyboardButton("📦 جعبه معمولی (0.5 TON)", callback_data="buy_loot_common")],
            [InlineKeyboardButton("📦 جعبه کمیاب (1.5 TON)", callback_data="buy_loot_rare")],
            [InlineKeyboardButton("📦 جعبه افسانه‌ای (5 TON)", callback_data="buy_loot_legendary")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("🎁 یک جعبه انتخاب کن:", reply_markup=InlineKeyboardMarkup(kb))
    elif data.startswith("buy_loot_"):
        buy_lootbox(update, context)
    elif data.startswith("check_loot_"):
        check_lootbox_payment(update, context)
    elif data == "inventory":
        show_inventory(update, context)
    elif data.startswith("equip_"):
        equip_item(update, context)
    elif data == "back_main":
        show_main_v5(update, context, edit=True)
    else:
        query.edit_message_text("این بخش در دست ساخت است...")
        
    # ==================== قطعه ۳: آموزشگاه، کاردستی، مأموریت و بازار ====================

# -------------------- آموزشگاه جادو --------------------
def mage_guild(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    if not p: return
    # دریافت کلاس فعلی
    player_class = p[3]
    if player_class == "شاگرد":
        query.edit_message_text("🎓 ابتدا باید یک کلاس انتخاب کنی! (بزودی)")
        return
    # مهارت‌های قابل یادگیری (آنهایی که در مهارت‌های کلاس وجود دارند اما بازیکن ندارد)
    class_skills = CLASSES.get(player_class, {}).get("skills", [])
    learned = json.loads(p[24])
    learnable = [s for s in class_skills if s not in learned]
    if not learnable:
        query.edit_message_text("📚 تمام مهارت‌های کلاس خود را فرا گرفته‌ای!")
        return
    text = "🎓 *آموزشگاه جادو*\n"
    text += f"💰 طلا: {p[13]} | ⚜️ امتیاز مهارت: {p[15]}\n\n"
    kb = []
    for skill in learnable:
        skill_info = SKILLS_DB.get(skill, {})
        cost = skill_info.get("level_req", 1) * 50  # هزینه یادگیری: سطح × 50 طلا
        sp_cost = 1  # هزینه امتیاز مهارت
        text += f"🔹 {skill} – {cost} طلا + {sp_cost} SP\n"
        kb.append([InlineKeyboardButton(f"یادگیری {skill}", callback_data=f"learn_{skill}")])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")])
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def learn_skill(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    skill_name = query.data.replace("learn_", "")
    p = get_player(uid)
    if not p: return
    skill_info = SKILLS_DB.get(skill_name)
    if not skill_info:
        query.edit_message_text("مهارت نامعتبر.")
        return
    cost = skill_info.get("level_req", 1) * 50
    sp_cost = 1
    if p[13] < cost:
        query.edit_message_text("💰 طلا کافی نداری!")
        return
    if p[15] < sp_cost:
        query.edit_message_text("⚜️ امتیاز مهارت کافی نداری!")
        return
    # یادگیری مهارت
    skills = json.loads(p[24])
    skills.append(skill_name)
    update_player(uid, gold=p[13]-cost, skill_points=p[15]-sp_cost, skills=skills)
    query.edit_message_text(f"✅ مهارت *{skill_name}* را آموختی!")

# -------------------- کاردستی (آهنگری و کیمیاگری) --------------------
def craft_menu(update, context):
    query = update.callback_query
    query.answer()
    kb = [
        [InlineKeyboardButton("⚒️ آهنگری", callback_data="craft_blacksmith")],
        [InlineKeyboardButton("🧪 کیمیاگری", callback_data="craft_alchemy")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    query.edit_message_text("🛠️ *کاردستی* – چه می‌سازی؟", reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def craft_blacksmith(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    # فقط دستورهای آهنگری
    recipes = {k:v for k,v in CRAFT_RECIPES.items() if v.get("type") == "آهنگری"}
    text = "⚒️ *آهنگری*\nمواد اولیه در کوله‌پشتی:\n"
    inv = json.loads(p[22])
    for name, rec in recipes.items():
        mats = rec["materials"]
        can_craft = all(inv.count(m) >= mats[m] for m in mats)
        status = "✅" if can_craft else "❌"
        text += f"{status} {name} – نیاز: {', '.join(f'{v} {k}' for k,v in mats.items())}\n"
    kb = []
    for name in recipes:
        kb.append([InlineKeyboardButton(f"ساخت {name}", callback_data=f"make_{name}")])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="craft_menu")])
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def craft_alchemy(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    recipes = {k:v for k,v in CRAFT_RECIPES.items() if v.get("type") == "کیمیاگری"}
    text = "🧪 *کیمیاگری*\nمواد اولیه در کوله‌پشتی:\n"
    inv = json.loads(p[22])
    for name, rec in recipes.items():
        mats = rec["materials"]
        can_craft = all(inv.count(m) >= mats[m] for m in mats)
        status = "✅" if can_craft else "❌"
        text += f"{status} {name} – نیاز: {', '.join(f'{v} {k}' for k,v in mats.items())}\n"
    kb = []
    for name in recipes:
        kb.append([InlineKeyboardButton(f"ساخت {name}", callback_data=f"make_{name}")])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="craft_menu")])
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def make_item(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    item_name = query.data.replace("make_", "")
    p = get_player(uid)
    recipe = CRAFT_RECIPES.get(item_name)
    if not recipe:
        query.edit_message_text("دستور ساخت نامعتبر.")
        return
    inv = json.loads(p[22])
    mats = recipe["materials"]
    # بررسی مواد
    for mat, count in mats.items():
        if inv.count(mat) < count:
            query.edit_message_text(f"❌ مواد کافی برای {mat} نداری!")
            return
    # حذف مواد
    for mat, count in mats.items():
        for _ in range(count):
            inv.remove(mat)
    # افزودن محصول
    inv.append(item_name)
    update_player(uid, inventory=inv)
    query.edit_message_text(f"✅ {item_name} با موفقیت ساخته شد!")

# -------------------- مأموریت‌ها --------------------
def quest_menu(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    lang = p[38] if p[38] else DEFAULT_LANG
    quests_taken = json.loads(p[21])
    progress = json.loads(p[22]) if p[22] else {}
    text = "📜 *مأموریت‌ها*\n"
    kb = []
    for quest in QUESTS:
        qid = quest["id"]
        title = quest.get(f"title_{lang}", quest["title_fa"])
        if qid in quests_taken:
            # در حال انجام
            obj = quest["objective"]
            current = progress.get(qid, 0)
            text += f"🔄 {title}: {current}/{obj['count']}\n"
            kb.append([InlineKeyboardButton(f"ادامه {title}", callback_data=f"quest_progress_{qid}")])
        else:
            text += f"❗ {title}\n"
            kb.append([InlineKeyboardButton(f"پذیرش {title}", callback_data=f"quest_accept_{qid}")])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")])
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def quest_accept(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    qid = query.data.replace("quest_accept_", "")
    p = get_player(uid)
    quests_taken = json.loads(p[21])
    if qid in quests_taken:
        query.edit_message_text("این مأموریت را قبلاً پذیرفته‌ای.")
        return
    quests_taken.append(qid)
    progress = json.loads(p[22]) if p[22] else {}
    progress[qid] = 0
    update_player(uid, quest_log=quests_taken, quest_progress=progress)
    query.edit_message_text("✅ مأموریت پذیرفته شد! حالا برو و هیولاها را شکار کن.")

def quest_progress(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    qid = query.data.replace("quest_progress_", "")
    p = get_player(uid)
    progress = json.loads(p[22]) if p[22] else {}
    current = progress.get(qid, 0)
    quest = next((q for q in QUESTS if q["id"] == qid), None)
    if not quest:
        query.edit_message_text("مأموریت نامعتبر.")
        return
    obj = quest["objective"]
    if current >= obj["count"]:
        # تکمیل مأموریت
        quests_taken = json.loads(p[21])
        quests_taken.remove(qid)
        del progress[qid]
        # پاداش
        reward_xp = quest["reward_xp"]
        reward_gold = quest["reward_gold"]
        new_xp = p[5] + reward_xp
        lvl_up = False
        if new_xp >= p[4]*100:
            new_xp -= p[4]*100
            new_level = p[4]+1
            update_player(uid, level=new_level, xp=new_xp, stat_points=p[14]+5, skill_points=p[15]+2)
            lvl_up = True
        else:
            update_player(uid, xp=new_xp, gold=p[13]+reward_gold, quest_log=quests_taken, quest_progress=progress)
        if "reward_item" in quest:
            inv = json.loads(p[22])
            inv.append(quest["reward_item"])
            update_player(uid, inventory=inv)
        msg = f"🎉 مأموریت کامل شد! +{reward_xp} XP, +{reward_gold} طلا"
        if lvl_up: msg += f"\n🌟 سطح {new_level}!"
        query.edit_message_text(msg)
    else:
        query.edit_message_text(f"🔄 پیشرفت: {current}/{obj['count']}")

# -------------------- بازار بازیکنان --------------------
def market_menu(update, context):
    query = update.callback_query
    query.answer()
    kb = [
        [InlineKeyboardButton("📦 خرید آیتم", callback_data="market_buy")],
        [InlineKeyboardButton("💰 فروش آیتم", callback_data="market_sell")],
        [InlineKeyboardButton("📋 لیست فروش‌ها", callback_data="market_listings")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    query.edit_message_text("🏪 *بازار اِلدوریا*\nاینجا می‌تونی آیتم بخری و بفروشی!", reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def market_listings(update, context):
    query = update.callback_query
    query.answer()
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT id, seller_id, item_name, price FROM market WHERE sold=0 ORDER BY id DESC LIMIT 10")
    rows = c.fetchall()
    conn.close()
    if not rows:
        query.edit_message_text("📭 هیچ آیتمی برای فروش نیست.")
        return
    text = "📋 *آیتم‌های فروشی*\n"
    kb = []
    for row in rows:
        lid, seller, item, price = row
        text += f"🔹 {item} – {price} طلا (فروشنده: {seller})\n"
        kb.append([InlineKeyboardButton(f"خرید {item}", callback_data=f"market_buy_{lid}")])
    kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="market_menu")])
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def market_sell(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    # دریافت قیمت و آیتم از کاربر (در این نسخه ساده، از یک آیتم فرضی استفاده می‌کنیم)
    # برای تعامل بهتر، می‌توان از ForceReply یا state استفاده کرد اما فعلاً ساده می‌گیریم.
    query.edit_message_text("💰 برای فروش، از دستور /sell <نام آیتم> <قیمت> استفاده کن.\nمثال: `/sell شمشیر آهنی 500`")

def market_sell_command(update, context):
    # هندلر برای /sell
    uid = update.effective_user.id
    args = context.args
    if len(args) < 2:
        update.message.reply_text("استفاده: /sell <نام آیتم> <قیمت>")
        return
    item_name = " ".join(args[:-1])
    try:
        price = int(args[-1])
    except:
        update.message.reply_text("قیمت باید عدد باشد.")
        return
    p = get_player(uid)
    inv = json.loads(p[22])
    if item_name not in inv:
        update.message.reply_text("این آیتم در کوله‌پشتی تو نیست.")
        return
    inv.remove(item_name)
    update_player(uid, inventory=inv)
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("INSERT INTO market (seller_id, item_name, price, listed_at) VALUES (?,?,?,?)",
              (uid, item_name, price, datetime.datetime.now().isoformat()))
    conn.commit()
    conn.close()
    update.message.reply_text(f"✅ {item_name} به قیمت {price} طلا در بازار لیست شد.")

def market_buy(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    lid = int(query.data.replace("market_buy_", ""))
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT seller_id, item_name, price FROM market WHERE id=? AND sold=0", (lid,))
    row = c.fetchone()
    if not row:
        query.edit_message_text("این آیتم قبلاً فروخته شده است.")
        conn.close()
        return
    seller_id, item_name, price = row
    buyer = get_player(uid)
    if buyer[13] < price:
        query.edit_message_text("💰 طلا کافی نداری!")
        conn.close()
        return
    # انتقال طلا
    update_player(uid, gold=buyer[13]-price)
    seller = get_player(seller_id)
    if seller:
        update_player(seller_id, gold=seller[13]+price)
    # انتقال آیتم
    buyer_inv = json.loads(buyer[22])
    buyer_inv.append(item_name)
    update_player(uid, inventory=buyer_inv)
    c.execute("UPDATE market SET sold=1 WHERE id=?", (lid,))
    conn.commit()
    conn.close()
    query.edit_message_text(f"✅ {item_name} را به قیمت {price} طلا خریدی!")

# -------------------- به‌روزرسانی button_handler --------------------
def extended_button_handler_v3(update, context):
    query = update.callback_query
    query.answer()
    data = query.data
    uid = query.from_user.id
    p = get_player(uid)
    if not p: return

    if data == "move_menu":
        move_menu(update, context)
    elif data.startswith("move_"):
        move(update, context)
    elif data == "hunt":
        hunt(update, context)
    elif data == "skill_menu":
        skill_menu(update, context)
    elif data.startswith("use_skill_"):
        combat_action(update, context)
    elif data.startswith("combat_"):
        combat_action(update, context)
    elif data == "rest_menu":
        kb = [
            [InlineKeyboardButton("🛏️ مسافرخانه (۱۰ طلا)", callback_data="rest_inn")],
            [InlineKeyboardButton("😴 خیابان (رایگان)", callback_data="rest_street")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("کجا استراحت می‌کنی؟", reply_markup=InlineKeyboardMarkup(kb))
    elif data in ("rest_inn", "rest_street"):
        place = "inn" if data == "rest_inn" else "street"
        msg = rest(uid, place)
        query.edit_message_text(msg)
    elif data == "lootbox_menu":
        kb = [
            [InlineKeyboardButton("📦 جعبه معمولی (0.5 TON)", callback_data="buy_loot_common")],
            [InlineKeyboardButton("📦 جعبه کمیاب (1.5 TON)", callback_data="buy_loot_rare")],
            [InlineKeyboardButton("📦 جعبه افسانه‌ای (5 TON)", callback_data="buy_loot_legendary")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("🎁 یک جعبه انتخاب کن:", reply_markup=InlineKeyboardMarkup(kb))
    elif data.startswith("buy_loot_"):
        buy_lootbox(update, context)
    elif data.startswith("check_loot_"):
        check_lootbox_payment(update, context)
    elif data == "inventory":
        show_inventory(update, context)
    elif data.startswith("equip_"):
        equip_item(update, context)
    elif data == "mage_guild":
        mage_guild(update, context)
    elif data.startswith("learn_"):
        learn_skill(update, context)
    elif data == "craft":
        craft_menu(update, context)
    elif data == "craft_blacksmith":
        craft_blacksmith(update, context)
    elif data == "craft_alchemy":
        craft_alchemy(update, context)
    elif data.startswith("make_"):
        make_item(update, context)
    elif data == "quests":
        quest_menu(update, context)
    elif data.startswith("quest_accept_"):
        quest_accept(update, context)
    elif data.startswith("quest_progress_"):
        quest_progress(update, context)
    elif data == "market":
        market_menu(update, context)
    elif data == "market_listings":
        market_listings(update, context)
    elif data == "market_sell":
        market_sell(update, context)
    elif data.startswith("market_buy_"):
        market_buy(update, context)
    elif data == "back_main":
        show_main_v5(update, context, edit=True)
    else:
        query.edit_message_text("این بخش در دست ساخت است...")
        
    # ==================== قطعه ۴: گیلد، همراهان و آرنا ====================

# -------------------- سیستم گیلد --------------------
def guild_menu(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    if not p: return
    guild_name = p[25]
    if guild_name:
        # منوی اعضا
        conn = sqlite3.connect(DB_FILE)
        c = conn.cursor()
        c.execute("SELECT * FROM guilds WHERE name=?", (guild_name,))
        guild = c.fetchone()
        conn.close()
        if not guild:
            update_player(uid, guild="", guild_rank="")
            query.edit_message_text("گیلد شما حذف شده است.")
            return
        members = json.loads(guild[3])
        rank = p[26]
        text = f"🏰 *گیلد {guild_name}*\n"
        text += f"💰 خزانه: {guild[4]} طلا | ⭐ سطح: {guild[5]}\n"
        text += f"👥 اعضا: {len(members)}\n"
        text += f"🎖️ رتبه شما: {rank}\n"
        kb = []
        if rank == "رهبر":
            kb.append([InlineKeyboardButton("💰 واریز به خزانه", callback_data="guild_deposit")])
            kb.append([InlineKeyboardButton("📋 مدیریت اعضا", callback_data="guild_manage")])
            kb.append([InlineKeyboardButton("⚔️ اعلام جنگ", callback_data="guild_war")])
        else:
            kb.append([InlineKeyboardButton("💰 کمک به خزانه", callback_data="guild_deposit")])
        kb.append([InlineKeyboardButton("🚪 ترک گیلد", callback_data="guild_leave")])
        kb.append([InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")])
        query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)
    else:
        kb = [
            [InlineKeyboardButton("🏰 ساخت گیلد", callback_data="guild_create")],
            [InlineKeyboardButton("🔍 پیوستن به گیلد", callback_data="guild_join")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("🏰 *گیلدها* – هنوز عضو گیلدی نیستی.", reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def guild_create(update, context):
    query = update.callback_query
    query.answer()
    # برای سادگی، نام گیلد را از state می‌گیریم؛ فعلاً با پیام راهنما
    query.edit_message_text("برای ساخت گیلد از دستور `/createguild <نام>` استفاده کن.\nهزینه: ۵۰۰ طلا")

def guild_create_command(update, context):
    uid = update.effective_user.id
    args = context.args
    if not args:
        update.message.reply_text("استفاده: /createguild <نام گیلد>")
        return
    name = " ".join(args)
    if len(name) > 20:
        update.message.reply_text("نام گیلد حداکثر ۲۰ کاراکتر.")
        return
    p = get_player(uid)
    if p[25]:
        update.message.reply_text("شما قبلاً عضو یک گیلد هستید.")
        return
    if p[13] < 500:
        update.message.reply_text("💰 حداقل ۵۰۰ طلا برای ساخت گیلد نیاز است.")
        return
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT * FROM guilds WHERE name=?", (name,))
    if c.fetchone():
        conn.close()
        update.message.reply_text("این نام قبلاً انتخاب شده.")
        return
    update_player(uid, gold=p[13]-500, guild=name, guild_rank="رهبر")
    c.execute("INSERT INTO guilds (name, leader, members, treasury, level) VALUES (?,?,?,?,?)",
              (name, uid, json.dumps([uid]), 0, 1))
    conn.commit()
    conn.close()
    update.message.reply_text(f"🏰 گیلد *{name}* با موفقیت ساخته شد!")

def guild_join(update, context):
    query = update.callback_query
    query.answer()
    query.edit_message_text("برای پیوستن به گیلد، از دستور `/joinguild <نام گیلد>` استفاده کن.")

def guild_join_command(update, context):
    uid = update.effective_user.id
    args = context.args
    if not args:
        update.message.reply_text("استفاده: /joinguild <نام گیلد>")
        return
    name = " ".join(args)
    p = get_player(uid)
    if p[25]:
        update.message.reply_text("شما قبلاً عضو یک گیلد هستید.")
        return
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT * FROM guilds WHERE name=?", (name,))
    guild = c.fetchone()
    if not guild:
        conn.close()
        update.message.reply_text("گیلد مورد نظر یافت نشد.")
        return
    members = json.loads(guild[3])
    if uid in members:
        conn.close()
        update.message.reply_text("شما قبلاً عضو این گیلد هستید.")
        return
    members.append(uid)
    c.execute("UPDATE guilds SET members=? WHERE name=?", (json.dumps(members), name))
    conn.commit()
    conn.close()
    update_player(uid, guild=name, guild_rank="عضو")
    update.message.reply_text(f"✅ به گیلد *{name}* پیوستی!")

def guild_deposit(update, context):
    query = update.callback_query
    query.answer()
    query.edit_message_text("برای واریز به خزانه از `/guilddeposit <مبلغ>` استفاده کن.")

def guild_deposit_command(update, context):
    uid = update.effective_user.id
    args = context.args
    if not args:
        update.message.reply_text("مبلغ را وارد کنید. مثال: `/guilddeposit 200`")
        return
    try:
        amount = int(args[0])
    except:
        update.message.reply_text("مبلغ معتبر نیست.")
        return
    if amount <= 0:
        update.message.reply_text("مبلغ مثبت وارد کنید.")
        return
    p = get_player(uid)
    if not p[25]:
        update.message.reply_text("شما عضو گیلدی نیستید.")
        return
    if p[13] < amount:
        update.message.reply_text("طلا کافی نداری.")
        return
    update_player(uid, gold=p[13]-amount)
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("UPDATE guilds SET treasury = treasury + ? WHERE name=?", (amount, p[25]))
    conn.commit()
    conn.close()
    update.message.reply_text(f"💰 {amount} طلا به خزانه گیلد واریز شد.")

def guild_leave(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    if not p[25]:
        query.edit_message_text("شما عضو گیلدی نیستید.")
        return
    guild_name = p[25]
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT * FROM guilds WHERE name=?", (guild_name,))
    guild = c.fetchone()
    if not guild:
        conn.close()
        update_player(uid, guild="", guild_rank="")
        query.edit_message_text("گیلد شما حذف شده است.")
        return
    members = json.loads(guild[3])
    if uid in members:
        members.remove(uid)
    if len(members) == 0:
        # حذف گیلد
        c.execute("DELETE FROM guilds WHERE name=?", (guild_name,))
    else:
        c.execute("UPDATE guilds SET members=? WHERE name=?", (json.dumps(members), guild_name))
    conn.commit()
    conn.close()
    update_player(uid, guild="", guild_rank="")
    query.edit_message_text("🚪 از گیلد خارج شدی.")

# -------------------- همراهان --------------------
def companion_menu(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    companion = json.loads(p[27]) if p[27] else {}
    if not companion:
        kb = [
            [InlineKeyboardButton("🥚 جوجه‌کشی تخم", callback_data="hatch_egg")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("🐺 هنوز همراهی نداری. تخم‌هایت را اینجا جوجه‌کشی کن.", reply_markup=InlineKeyboardMarkup(kb))
        return
    name = companion.get("name", "همراه")
    level = companion.get("level", 1)
    hp = companion.get("hp", 30)
    att = companion.get("att", 5)
    text = f"🐺 *{name}* (سطح {level})\n❤️ {hp} ⚔️ {att}\n"
    kb = [
        [InlineKeyboardButton("🍖 غذا دادن", callback_data="feed_companion")],
        [InlineKeyboardButton("⬆️ تکامل", callback_data="evolve_companion")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def hatch_egg(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    inv = json.loads(p[22])
    # بررسی وجود تخم
    for item in inv:
        if "تخم" in item:
            inv.remove(item)
            # تعیین نوع همراه
            if "اژدها" in item:
                companion = {"type":"اژدها","name":"اژدهای کوچک","level":1,"hp":50,"att":10,"xp":0}
            elif "گرگ" in item:
                companion = {"type":"گرگ","name":"توله گرگ","level":1,"hp":30,"att":8,"xp":0}
            else:
                companion = {"type":"ناشناخته","name":"جوجه","level":1,"hp":20,"att":4,"xp":0}
            update_player(uid, inventory=inv, companion=companion)
            query.edit_message_text(f"🎉 یک {companion['name']} از تخم بیرون آمد!")
            return
    query.edit_message_text("❌ هیچ تخمی در کوله‌پشتی نداری!")

def feed_companion(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    companion = json.loads(p[27]) if p[27] else {}
    if not companion:
        query.edit_message_text("همراهی نداری.")
        return
    # نیاز به غذا (آیتم فرضی "گوشت")
    inv = json.loads(p[22])
    if "گوشت" in inv:
        inv.remove("گوشت")
        companion["xp"] += 10
        update_player(uid, inventory=inv, companion=companion)
        query.edit_message_text("🍖 همراهت تغذیه شد. +۱۰ XP")
    else:
        query.edit_message_text("❌ گوشت نداری! از شکار گرگ‌ها می‌تونی گوشت بگیری.")

def evolve_companion(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    p = get_player(uid)
    companion = json.loads(p[27]) if p[27] else {}
    if not companion:
        query.edit_message_text("همراهی نداری.")
        return
    req_xp = companion["level"] * 50
    if companion["xp"] >= req_xp:
        companion["level"] += 1
        companion["hp"] += 10
        companion["att"] += 3
        companion["xp"] -= req_xp
        update_player(uid, companion=companion)
        query.edit_message_text(f"🎉 همراهت به سطح {companion['level']} تکامل یافت!")
    else:
        query.edit_message_text(f"XP کافی نیست. نیاز: {req_xp} (فعلی: {companion['xp']})")

# -------------------- آرنا --------------------
def arena_menu(update, context):
    query = update.callback_query
    query.answer()
    uid = query.from_user.id
    kb = [
        [InlineKeyboardButton("⚔️ دوئل سریع", callback_data="arena_duel")],
        [InlineKeyboardButton("🏆 رتبه‌بندی", callback_data="arena_ranking")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
    ]
    query.edit_message_text("⚔️ *آرنا اِلدوریا*\nاینجا می‌تونی با دیگر ماجراجویان مبارزه کنی!", reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.MARKDOWN)

def arena_duel(update, context):
    query = update.callback_query
    query.answer()
    # پیدا کردن حریف تصادفی (از بازیکنان آنلاین – اینجا ساده‌سازی می‌کنیم)
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT user_id, username, level, hp, attack, defense FROM players WHERE user_id != ? ORDER BY RANDOM() LIMIT 1",
              (query.from_user.id,))
    opponent = c.fetchone()
    conn.close()
    if not opponent:
        query.edit_message_text("هیچ حریفی برای دوئل پیدا نشد.")
        return
    opp_id, opp_name, opp_lvl, opp_hp, opp_atk, opp_def = opponent
    # شروع دوئل ساده (نبرد خودکار)
    p = get_player(query.from_user.id)
    player_hp = p[6]
    player_atk = p[10]
    player_def = p[11]
    # نبرد تا مرگ یکی
    while player_hp > 0 and opp_hp > 0:
        # نوبت بازیکن
        dmg = max(1, player_atk - opp_def + random.randint(-3,3))
        opp_hp -= dmg
        if opp_hp <= 0: break
        # نوبت حریف
        dmg = max(1, opp_atk - player_def + random.randint(-3,3))
        player_hp -= dmg
    if player_hp > 0:
        reward = 50 + opp_lvl * 10
        update_player(query.from_user.id, gold=p[13]+reward, hp=player_hp)
        query.edit_message_text(f"🎉 برنده شدی! +{reward} طلا\n❤️ سلامت باقی‌مانده: {player_hp}")
    else:
        update_player(query.from_user.id, hp=0)
        query.edit_message_text(f"💀 شکست خوردی... به شهر برمی‌گردی.")

def arena_ranking(update, context):
    query = update.callback_query
    query.answer()
    conn = sqlite3.connect(DB_FILE)
    c = conn.cursor()
    c.execute("SELECT username, level, attack FROM players ORDER BY level DESC, attack DESC LIMIT 10")
    rows = c.fetchall()
    conn.close()
    text = "🏆 *برترین مبارزان*\n"
    for i, (name, lvl, atk) in enumerate(rows, 1):
        medal = "🥇" if i==1 else "🥈" if i==2 else "🥉" if i==3 else "🔹"
        text += f"{medal} {name}: Lv.{lvl} ⚔️{atk}\n"
    query.edit_message_text(text, parse_mode=ParseMode.MARKDOWN)

# -------------------- به‌روزرسانی button_handler --------------------
def extended_button_handler_v4(update, context):
    query = update.callback_query
    query.answer()
    data = query.data
    uid = query.from_user.id
    p = get_player(uid)
    if not p: return

    if data == "move_menu":
        move_menu(update, context)
    elif data.startswith("move_"):
        move(update, context)
    elif data == "hunt":
        hunt(update, context)
    elif data == "skill_menu":
        skill_menu(update, context)
    elif data.startswith("use_skill_"):
        combat_action(update, context)
    elif data.startswith("combat_"):
        combat_action(update, context)
    elif data == "rest_menu":
        kb = [
            [InlineKeyboardButton("🛏️ مسافرخانه (۱۰ طلا)", callback_data="rest_inn")],
            [InlineKeyboardButton("😴 خیابان (رایگان)", callback_data="rest_street")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("کجا استراحت می‌کنی؟", reply_markup=InlineKeyboardMarkup(kb))
    elif data in ("rest_inn", "rest_street"):
        place = "inn" if data == "rest_inn" else "street"
        msg = rest(uid, place)
        query.edit_message_text(msg)
    elif data == "lootbox_menu":
        kb = [
            [InlineKeyboardButton("📦 جعبه معمولی (0.5 TON)", callback_data="buy_loot_common")],
            [InlineKeyboardButton("📦 جعبه کمیاب (1.5 TON)", callback_data="buy_loot_rare")],
            [InlineKeyboardButton("📦 جعبه افسانه‌ای (5 TON)", callback_data="buy_loot_legendary")],
            [InlineKeyboardButton("🔙 بازگشت", callback_data="back_main")]
        ]
        query.edit_message_text("🎁 یک جعبه انتخاب کن:", reply_markup=InlineKeyboardMarkup(kb))
    elif data.startswith("buy_loot_"):
        buy_lootbox(update, context)
    elif data.startswith("check_loot_"):
        check_lootbox_payment(update, context)
    elif data == "inventory":
        show_inventory(update, context)
    elif data.startswith("equip_"):
        equip_item(update, context)
    elif data == "mage_guild":
        mage_guild(update, context)
    elif data.startswith("learn_"):
        learn_skill(update, context)
    elif data == "craft":
        craft_menu(update, context)
    elif data == "craft_blacksmith":
        craft_blacksmith(update, context)
    elif data == "craft_alchemy":
        craft_alchemy(update, context)
    elif data.startswith("make_"):
        make_item(update, context)
    elif data == "quests":
        quest_menu(update, context)
    elif data.startswith("quest_accept_"):
        quest_accept(update, context)
    elif data.startswith("quest_progress_"):
        quest_progress(update, context)
    elif data == "market":
        market_menu(update, context)
    elif data == "market_listings":
        market_listings(update, context)
    elif data == "market_sell":
        market_sell(update, context)
    elif data.startswith("market_buy_"):
        market_buy(update, context)
    # گیلد
    elif data == "guild":
        guild_menu(update, context)
    elif data == "guild_create":
        guild_create(update, context)
    elif data == "guild_join":
        guild_join(update, context)
    elif data == "guild_deposit":
        guild_deposit(update, context)
    elif data == "guild_leave":
        guild_leave(update, context)
    # همراه
    elif data == "companion":
        companion_menu(update, context)
    elif data == "hatch_egg":
        hatch_egg(update, context)
    elif data == "feed_companion":
        feed_companion(update, context)
    elif data == "evolve_companion":
        evolve_companion(update, context)
    # آرنا
    elif data == "arena":
        arena_menu(update, context)
    elif data == "arena_duel":
        arena_duel(update, context)
    elif data == "arena_ranking":
        arena_ranking(update, context)
    elif data == "back_main":
        show_main_v5(update, context, edit=True)
    else:
        query.edit_message_text("این بخش در دست ساخت است...")
    
     # ==================== قطعه ۵: رویدادها، آب‌وهوا، پنل ادمین و امنیت ====================

# -------------------- رویدادهای فصلی --------------------
SEASONAL_EVENTS = {
    "harvest_festival": {
        "name_fa": "جشنواره برداشت",
        "name_en": "Harvest Festival",
        "start": "10-20",  # mm-dd
        "end": "11-05",
        "boss": "کدوی غول‌آسا",
        "special_items": ["آب‌نبات جادویی", "کیک کدو"],
        "description": "مزرعه‌ها پر از کدوهای غول‌پیکر شده‌اند. باس ویژه را شکست بده تا آیتم‌های انحصاری بگیری!"
    }
}

def get_active_event():
    """بررسی می‌کند که آیا رویداد فصلی فعال است یا خیر"""
    today = datetime.datetime.now()
    for event_id, event in SEASONAL_EVENTS.items():
        start = datetime.datetime.strptime(f"{today.year}-{event['start']}", "%Y-%m-%d")
        end = datetime.datetime.strptime(f"{today.year}-{event['end']}", "%Y-%m-%d")
        if start <= today <= end:
            return event_id, event
    return None, None

def event_hunt(update, context):
    """شکار باس رویداد فصلی"""
    query = update.callback_query
    query.answer()
    event_id, event = get_active_event()
    if not event:
        query.edit_message_text("❌ در حال حاضر رویداد فصلی فعال نیست.")
        return
    boss_name = event["boss"]
    boss = BOSSES.get(boss_name)  # باید در BOSSES تعریف شده باشد
    if not boss:
        query.edit_message_text("خطا: باس رویداد تعریف نشده.")
        return
    # مشابه تابع hunt، اما با باس رویداد
    context.user_data["monster"] = {**boss, "name": boss_name, "current_hp": boss["hp"], "is_boss": True, "event": True}
    text = f"🎃 *رویداد: {event['name_fa']}*\n💀 {boss_name} ظاهر شد!\n❤️ {boss['hp']} | ⚔️ {boss['att']}"
    keyboard = [
        [InlineKeyboardButton("⚡ حمله", callback_data="combat_attack")],
        [InlineKeyboardButton("🔥 مهارت", callback_data="skill_menu")],
        [InlineKeyboardButton("🧪 آیتم", callback_data="combat_item")],
        [InlineKeyboardButton("🏃 فرار", callback_data="combat_flee")]
    ]
    query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode=ParseMode.MARKDOWN)

# -------------------- سیستم آب‌وهوا --------------------
WEATHER_TYPES = {
    "sunny": {"name_fa":"آفتابی","name_en":"Sunny","effect":None},
    "rain": {"name_fa":"بارانی","name_en":"Rain","effect":"water_boost"},
    "fog": {"name_fa":"مه‌آلود","name_en":"Foggy","effect":"accuracy_down"},
    "storm": {"name_fa":"طوفانی","name_en":"Stormy","effect":"lightning_dmg"}
}

current_weather = "sunny"  # متغیر گلوبال (در نسخه کامل، در دیتابیس ذخیره می‌شود)

def change_weather(context: CallbackContext = None):
    """هر یک ساعت آب‌وهوا را عوض می‌کند (در job_queue اجرا می‌شود)"""
    global current_weather
    new_weather = random.choice(list(WEATHER_TYPES.keys()))
    current_weather = new_weather
    logger.info(f"آب‌وهوا به {WEATHER_TYPES[new_weather]['name_fa']} تغییر کرد.")

def apply_weather_effect(monster, player=None):
    """افکت آب‌وهوا بر نبرد"""
    weather = WEATHER_TYPES[current_weather]
    effect = weather["effect"]
    if effect == "water_boost" and monster.get("element") == "آب":
        monster["att"] = int(monster["att"] * 1.2)
    elif effect == "accuracy_down":
        # شانس خطا برای بازیکن
        if player and random.random() < 0.15:
            return True  # حمله خطا رفت
    elif effect == "lightning_dmg":
        if random.random() < 0.1:
            monster["current_hp"] -= 10  # صاعقه اضافی
    return False

# -------------------- پنل ادمین --------------------
def admin_panel(update, context):
    """دستور /admin برای مدیریت"""
    uid = update.effective_user.id
    if uid not in ADMIN_IDS:
        update.message.reply_text("⛔ شما دسترسی ادمین ندارید.")
        return
    args = context.args
    if not args:
        update.message.reply_text(
            "دستورات ادمین:\n"
            "/admin addgold <uid> <amount>\n"
            "/admin setlevel <uid> <level>\n"
            "/admin spawnboss <zone>\n"
            "/admin announce <message>\n"
            "/admin backup\n"
        )
        return
    cmd = args[0].lower()
    if cmd == "addgold":
        if len(args) < 3:
            update.message.reply_text("کاربرد: /admin addgold <user_id> <amount>")
            return
        target_uid = int(args[1])
        amount = int(args[2])
        p = get_player(target_uid)
        if not p:
            update.message.reply_text("کاربر یافت نشد.")
            return
        update_player(target_uid, gold=p[13]+amount)
        update.message.reply_text(f"💰 {amount} طلا به {target_uid} اضافه شد.")
    elif cmd == "setlevel":
        if len(args) < 3:
            update.message.reply_text("کاربرد: /admin setlevel <user_id> <level>")
            return
        target_uid = int(args[1])
        level = int(args[2])
        p = get_player(target_uid)
        if not p: return
        update_player(target_uid, level=level, xp=0, hp=p[7], mp=p[9])  # reset xp, heal
        update.message.reply_text(f"⭐ سطح {target_uid} به {level} تغییر یافت.")
    elif cmd == "spawnboss":
        if len(args) < 2:
            update.message.reply_text("کاربرد: /admin spawnboss <zone> (مثل '1_0')")
            return
        zone_coords = tuple(map(int, args[1].split("_")))
        zone = WORLD_MAP.get(zone_coords)
        if not zone or "boss" not in zone:
            update.message.reply_text("منطقه یا باس نامعتبر.")
            return
        # ارسال پیام به همه (در عمل باید به کانال یا گروه بفرستد، اما اینجا ساده‌سازی)
        context.bot.send_message(ADMIN_IDS[0], f"⚔️ باس {zone['boss']} در {zone['name_fa']} احضار شد!")
    elif cmd == "announce":
        if len(args) < 2:
            update.message.reply_text("پیام را وارد کنید.")
            return
        message = " ".join(args[1:])
        # ارسال به همه کاربران (در عمل نیاز به ذخیره user_id ها دارد، فعلاً فقط به ادمین‌ها)
        for admin_id in ADMIN_IDS:
            context.bot.send_message(admin_id, f"📢 اطلاعیه: {message}")
    elif cmd == "backup":
        backup_db()
        update.message.reply_text("✅ بک‌آپ دیتابیس گرفته شد.")

# -------------------- بک‌آپ و امنیت --------------------
def backup_db():
    """تهیه نسخه پشتیبان از دیتابیس"""
    if not os.path.exists("backups"):
        os.makedirs("backups")
    timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
    backup_path = f"backups/eldoria_{timestamp}.db"
    shutil.copy(DB_FILE, backup_path)
    # حذف بک‌آپ‌های قدیمی‌تر از ۷ روز
    for f in os.listdir("backups"):
        full_path = os.path.join("backups", f)
        if os.path.isfile(full_path) and time.time() - os.path.getmtime(full_path) > 7*86400:
            os.remove(full_path)

# -------------------- Rate Limiting (ضد اسپم) --------------------
user_last_action = {}  # دیکشنری موقت برای نرخ‌دهی

def rate_limit(uid):
    """بررسی نرخ درخواست (حداکثر ۳ درخواست در ثانیه)"""
    now = time.time()
    if uid in user_last_action:
        if now - user_last_action[uid] < 0.3:  # 300ms
            return False
    user_last_action[uid] = now
    return True

def safe_button_handler(update, context):
    """نسخه امن button_handler با rate limit"""
    query = update.callback_query
    uid = query.from_user.id
    if not rate_limit(uid):
        query.answer("⏳ زیادی سریع کلیک کردی. کمی صبر کن.")
        return
    # فراخوانی button_handler اصلی
    extended_button_handler_v4(update, context)

# -------------------- ذخیره و بازیابی نشست --------------------
def save_session(uid):
    """در صورت نیاز، داده‌های نشست را در دیتابیس یا فایل ذخیره کن (می‌تواند برای بازیابی استفاده شود)"""
    # اینجا فقط یک نمونه ساده از ذخیره context.user_data در دیتابیس (در صورت crash)
    # در سیستم واقعی، از job_queue استفاده می‌شود
    pass

# -------------------- پاداش روزانه --------------------
def daily_reward(update, context):
    uid = update.effective_user.id
    p = get_player(uid)
    if not p: return
    last_daily = p[29]  # last_daily
    today = datetime.datetime.now().strftime("%Y-%m-%d")
    if last_daily == today:
        update.message.reply_text("🎁 پاداش روزانه را قبلاً گرفتی! فردا دوباره بیا.")
        return
    # پاداش: ۵۰ طلا + ۱ معجون کوچک
    update_player(uid, gold=p[13]+50, last_daily=today)
    inv = json.loads(p[22])
    inv.append("معجون کوچک")
    update_player(uid, inventory=inv)
    update.message.reply_text("🎁 پاداش روزانه: ۵۰ طلا + معجون کوچک دریافت کردی!")

# -------------------- به‌روزرسانی button_handler --------------------
def extended_button_handler_v5(update, context):
    query = update.callback_query
    query.answer()
    data = query.data
    uid = query.from_user.id
    p = get_player(uid)
    if not p: return

    if data == "event_hunt":
        event_hunt(update, context)
        return
    # بقیه شرط‌ها مشابه v4، اما در اینجا خلاصه شده (در فایل نهایی همه هستند)
    # ... (تمام case های قبلی)
    elif data == "daily_reward":
        daily_reward(update, context)
        return
    # اضافه کردن دکمه‌های رویداد به منوی اصلی
    elif data == "back_main":
        show_main_v5(update, context, edit=True)
    else:
        # فراخوانی v4 برای پشتیبانی از دستورات قبلی
        extended_button_handler_v4(update, context)

# -------------------- اضافه کردن دکمه‌های رویداد و پاداش به منوی اصلی --------------------
def show_main_v5(update, context, edit=False):
    uid = update.effective_user.id
    p = get_player(uid)
    zone_data = WORLD_MAP.get((p[17], p[18]), WORLD_MAP[(0,0)])
    lang = p[38] if p[38] else DEFAULT_LANG
    zone_name = zone_data.get(f"name_{lang}", zone_data["name_fa"])
    emoji = zone_data["emoji"]
    text = t(uid, "main_menu",
             zone=f"{emoji} {zone_name}",
             hp=p[6], max_hp=p[7], mp=p[8], max_mp=p[9],
             stamina=p[10], atk=p[12], def_stat=p[13],
             gold=p[15], gems=p[16], fatigue=p[16])
    kb = []
    if zone_data.get("safe"):
        kb.extend([
            [InlineKeyboardButton("🧭 کاوش", callback_data="move_menu")],
            [InlineKeyboardButton("😴 استراحت", callback_data="rest_menu")],
            [InlineKeyboardButton("📦 جعبه‌ها", callback_data="lootbox_menu")],
            [InlineKeyboardButton("⚒️ کاردستی", callback_data="craft")],
            [InlineKeyboardButton("📜 مأموریت", callback_data="quests")],
            [InlineKeyboardButton("🏪 فروشگاه", callback_data="store")],
            [InlineKeyboardButton("🏰 گیلد", callback_data="guild")],
            [InlineKeyboardButton("🐺 همراه", callback_data="companion")],
            [InlineKeyboardButton("⚔️ آرنا", callback_data="arena")],
        ])
        # اضافه کردن دکمه رویداد در صورت فعال بودن
        event_id, event = get_active_event()
        if event:
            kb.append([InlineKeyboardButton(f"🎃 {event['name_fa']}", callback_data="event_hunt")])
        kb.append([InlineKeyboardButton("🎁 پاداش روزانه", callback_data="daily_reward")])
        kb.append([InlineKeyboardButton("👤 پروفایل", callback_data="profile")])
    else:
        kb.extend([
            [InlineKeyboardButton("⚔️ شکار", callback_data="hunt")],
            [InlineKeyboardButton("🧭 حرکت", callback_data="move_menu")],
            [InlineKeyboardButton("🏃 بازگشت سریع", callback_data="recall")],
            [InlineKeyboardButton("😴 چرت کوتاه", callback_data="rest_street")],
        ])
        # در منطقه وحشی هم می‌توان رویداد را نشان داد
        if event_id:
            kb.append([InlineKeyboardButton(f"🎃 {event['name_fa']}", callback_data="event_hunt")])
    reply_markup = InlineKeyboardMarkup(kb)
    if edit and update.callback_query:
        update.callback_query.edit_message_text(text, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN)
    else:
        update.message.reply_text(text, reply_markup=reply_markup, parse_mode=ParseMode.MARKDOWN)
        
def main():
    init_db()
    updater = Updater(TOKEN, use_context=True)
    dp = updater.dispatcher

    # Job Queue
    jq = updater.job_queue
    jq.run_repeating(change_weather, interval=3600, first=10)
    jq.run_daily(lambda ctx: backup_db(), time=datetime.time(hour=3, minute=0))
    jq.run_daily(lambda ctx: reset_daily_attempts(ctx), time=datetime.time(hour=0, minute=0))

    # دستورات
    dp.add_handler(CommandHandler("start", start))
    dp.add_handler(CommandHandler("admin", admin_panel, pass_args=True))
    dp.add_handler(CommandHandler("daily", daily_reward))
    dp.add_handler(CommandHandler("createguild", guild_create_command, pass_args=True))
    dp.add_handler(CommandHandler("joinguild", guild_join_command, pass_args=True))
    dp.add_handler(CommandHandler("guilddeposit", guild_deposit_command, pass_args=True))
    dp.add_handler(CommandHandler("sell", market_sell_command, pass_args=True))

    # دکمه‌ها – از نسخه امن استفاده می‌کنیم
    dp.add_handler(CallbackQueryHandler(safe_button_handler))

    dp.add_error_handler(error_handler)

    logger.info("🌌 اِلدوریا نسخه نهایی – بیدار شد...")
    updater.start_polling()
    updater.idle()    
# ==================== ERROR ====================
def error_handler(update, context):
    logger.error(f"Error: {context.error}")

# ==================== MAIN ====================
def main():
    init_db()
    updater = Updater(TOKEN, use_context=True)
    dp = updater.dispatcher

    # Job Queue
    jq = updater.job_queue
    jq.run_repeating(change_weather, interval=3600, first=10)
    jq.run_daily(lambda ctx: backup_db(), time=datetime.time(hour=3, minute=0))
    jq.run_daily(lambda ctx: reset_daily_attempts(ctx), time=datetime.time(hour=0, minute=0))

    # دستورات
    dp.add_handler(CommandHandler("start", start))
    dp.add_handler(CommandHandler("admin", admin_panel, pass_args=True))
    dp.add_handler(CommandHandler("daily", daily_reward))
    dp.add_handler(CommandHandler("createguild", guild_create_command, pass_args=True))
    dp.add_handler(CommandHandler("joinguild", guild_join_command, pass_args=True))
    dp.add_handler(CommandHandler("guilddeposit", guild_deposit_command, pass_args=True))
    dp.add_handler(CommandHandler("sell", market_sell_command, pass_args=True))

    # دکمه‌ها – از نسخه امن استفاده می‌کنیم
    dp.add_handler(CallbackQueryHandler(safe_button_handler))

    dp.add_error_handler(error_handler)

    logger.info("🌌 اِلدوریا نسخه نهایی – بیدار شد...")
    updater.start_polling()
    updater.idle()

if __name__ == "__main__":
    main()