"""Default exercise library and training programs."""
from telegram import Update, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.ext import (
    ContextTypes, ConversationHandler,
    MessageHandler, CallbackQueryHandler, filters,
)
import database.db as db
from config.settings import DEF_EX_NAME, DEF_PROG_NAME, DEF_PROG_SETS, DEF_PROG_REPS, DEF_PROG_SEARCH_EX, DEF_EX_VIEW_SEARCH, EX_ADD_PHOTO, EX_ADD_VIDEO, EX_ADD_DESC
from utils.keyboards import (
    MAIN_COACH_KB, BACK_KB, SEARCH_EX_KB,
    default_training_menu_kb, exercises_list_kb, exercises_library_kb, paginated_exercises_kb,
    default_programs_kb, program_detail_kb, save_or_add_kb,
)
from utils.helpers import go_main_menu, track_message, delete_bot_messages


async def _cancel(update, context):
    await go_main_menu(update, context)
    return ConversationHandler.END


async def default_training_menu(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await delete_bot_messages(context, update.effective_chat.id)
    sent = await update.message.reply_text(
        "🏋️ *تمرین پیش‌فرض*\nیکی از گزینه‌ها را انتخاب کن:",
        reply_markup=default_training_menu_kb(), parse_mode="Markdown")
    track_message(context, update.effective_chat.id, sent.message_id)


async def def_ex_add_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text("🏃 نام حرکت را وارد کن:", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]]))
    track_message(context, chat_id, sent.message_id)
    return DEF_EX_NAME


async def def_ex_got_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
    name = update.message.text.strip()
    db.create_exercise(name)
    await delete_bot_messages(context, update.effective_chat.id)
    sent = await update.message.reply_text(f"✅ حرکت *«{name}»* به کتابخانه اضافه شد! 💪",
                                           reply_markup=MAIN_COACH_KB, parse_mode="Markdown")
    track_message(context, update.effective_chat.id, sent.message_id)
    return ConversationHandler.END



def _lib_kb(page=0, exercises=None):
    if exercises is None:
        exercises = db.get_all_exercises()
    return paginated_exercises_kb(
        exercises, prefix="view_ex", page=page, nav_cb="exlibpg",
        back_cb="default_training_menu", show_content_emoji=True)


def _prog_ex_kb(page=0, exercises=None):
    if exercises is None:
        exercises = db.get_all_exercises()
    return paginated_exercises_kb(
        exercises, prefix="prog_ex", page=page, nav_cb="progexpg",
        search_callback="def_search_ex", back_cb="default_training_menu")


async def def_ex_lib_page(update, context):
    query = update.callback_query; await query.answer()
    page = int(query.data.split("_")[-1])
    try:
        await query.message.edit_reply_markup(reply_markup=_lib_kb(page))
    except Exception:
        pass


async def def_prog_ex_page(update, context):
    query = update.callback_query; await query.answer()
    page = int(query.data.split("_")[-1])
    try:
        await query.message.edit_reply_markup(reply_markup=_prog_ex_kb(page))
    except Exception:
        pass
    return DEF_PROG_SETS

async def def_ex_list(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    exercises = db.get_all_exercises()
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    if not exercises:
        sent = await query.message.reply_text(
            "❌ هیچ حرکتی ثبت نشده.",
            reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🏠 بازگشت", callback_data="main_menu")]]))
        track_message(context, chat_id, sent.message_id)
        return
    kb = _lib_kb(0, exercises)
    sent = await query.message.reply_text(
        f"🗒 *لیست حرکات کتابخانه* — {len(exercises)} حرکت\n\n"
        f"📌 = حرکاتی که عکس/فیلم/توضیح دارند\n\nروی یک حرکت بزن:",
        parse_mode="Markdown", reply_markup=kb)
    track_message(context, chat_id, sent.message_id)
    s2 = await query.message.reply_text("یا جستجو کن 👇", reply_markup=SEARCH_EX_KB)
    track_message(context, chat_id, s2.message_id)


async def def_ex_view_detail(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """نمایش جزئیات یک حرکت از کتابخانه به همراه دکمه‌های ویرایش محتوا (مخصوص پنل مربی)."""
    query = update.callback_query; await query.answer()
    exercise_id = int(query.data.split("_")[-1])
    context.user_data["editing_exercise_id"] = exercise_id
    ex = db.get_exercise(exercise_id)
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)

    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("📷 افزودن/تغییر عکس", callback_data=f"exadd_photo_{exercise_id}"),
         InlineKeyboardButton("🎬 افزودن/تغییر فیلم", callback_data=f"exadd_video_{exercise_id}")],
        [InlineKeyboardButton("📝 افزودن/تغییر توضیحات", callback_data=f"exadd_desc_{exercise_id}")],
        [InlineKeyboardButton("🔙 بازگشت به لیست", callback_data="def_ex_list")],
    ])

    caption = f"💪 *{ex['name']}*"
    if ex.get("description"):
        caption += f"\n\n📝 {ex['description']}"

    # اولویت نمایش: ویدیو > عکس > گیف > فقط متن
    if ex.get("video_file_id"):
        sent = await query.message.reply_video(
            video=ex["video_file_id"], caption=caption, parse_mode="Markdown", reply_markup=kb)
    elif ex.get("photo_file_id"):
        sent = await query.message.reply_photo(
            photo=ex["photo_file_id"], caption=caption, parse_mode="Markdown", reply_markup=kb)
    elif ex.get("gif_url"):
        try:
            sent = await query.message.reply_animation(
                animation=ex["gif_url"], caption=caption, parse_mode="Markdown", reply_markup=kb)
        except Exception:
            sent = await query.message.reply_text(caption, parse_mode="Markdown", reply_markup=kb)
    else:
        caption += "\n\n_هنوز محتوایی برای این حرکت ثبت نشده._"
        sent = await query.message.reply_text(caption, parse_mode="Markdown", reply_markup=kb)

    track_message(context, chat_id, sent.message_id)


async def def_ex_add_photo_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    exercise_id = int(query.data.split("_")[-1])
    context.user_data["editing_exercise_id"] = exercise_id
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text(
        "📷 عکس این حرکت را ارسال کن:",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 انصراف", callback_data="def_ex_list")]]))
    track_message(context, chat_id, sent.message_id)
    return EX_ADD_PHOTO


async def def_ex_add_photo_got(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message.photo:
        sent = await update.message.reply_text("❗️ لطفاً یک عکس ارسال کن.")
        track_message(context, update.effective_chat.id, sent.message_id)
        return EX_ADD_PHOTO
    exercise_id = context.user_data.get("editing_exercise_id")
    file_id = update.message.photo[-1].file_id
    db.set_exercise_photo(exercise_id, file_id)
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    sent = await update.message.reply_text(
        "✅ عکس ذخیره شد!",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="def_ex_list")]]))
    track_message(context, chat_id, sent.message_id)
    return ConversationHandler.END


async def def_ex_add_video_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    exercise_id = int(query.data.split("_")[-1])
    context.user_data["editing_exercise_id"] = exercise_id
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text(
        "🎬 فیلم آموزش این حرکت را ارسال کن:",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 انصراف", callback_data="def_ex_list")]]))
    track_message(context, chat_id, sent.message_id)
    return EX_ADD_VIDEO


async def def_ex_add_video_got(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not update.message.video:
        sent = await update.message.reply_text("❗️ لطفاً یک فیلم ارسال کن.")
        track_message(context, update.effective_chat.id, sent.message_id)
        return EX_ADD_VIDEO
    exercise_id = context.user_data.get("editing_exercise_id")
    file_id = update.message.video.file_id
    db.set_exercise_video(exercise_id, file_id)
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    sent = await update.message.reply_text(
        "✅ فیلم ذخیره شد!",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="def_ex_list")]]))
    track_message(context, chat_id, sent.message_id)
    return ConversationHandler.END


async def def_ex_add_desc_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    exercise_id = int(query.data.split("_")[-1])
    context.user_data["editing_exercise_id"] = exercise_id
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text(
        "📝 توضیحات این حرکت را بنویس:",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 انصراف", callback_data="def_ex_list")]]))
    track_message(context, chat_id, sent.message_id)
    return EX_ADD_DESC


async def def_ex_add_desc_got(update: Update, context: ContextTypes.DEFAULT_TYPE):
    exercise_id = context.user_data.get("editing_exercise_id")
    db.set_exercise_description(exercise_id, update.message.text.strip())
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    sent = await update.message.reply_text(
        "✅ توضیحات ذخیره شد!",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="def_ex_list")]]))
    track_message(context, chat_id, sent.message_id)
    return ConversationHandler.END


async def def_ex_view_search_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """جستجوی حرکت از داخل لیست کتابخانه (فقط مشاهده، نه افزودن به برنامه)."""
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    sent = await update.message.reply_text(
        "🔍 نام حرکت را بنویس:",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="def_ex_list")]]))
    track_message(context, chat_id, sent.message_id)
    return DEF_EX_VIEW_SEARCH


async def def_ex_view_search_got(update: Update, context: ContextTypes.DEFAULT_TYPE):
    q = update.message.text.strip()
    results = db.search_exercises(q)
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    if not results:
        results = db.get_all_exercises()
        sent = await update.message.reply_text(
            f"❌ حرکتی با «{q}» پیدا نشد. لیست کامل:",
            reply_markup=paginated_exercises_kb(results, prefix="view_ex", page=0, nav_cb="exlibpg", back_cb="default_training_menu", show_content_emoji=True))
        track_message(context, chat_id, sent.message_id)
        s2 = await update.message.reply_text("یا جستجو کن 👇", reply_markup=SEARCH_EX_KB)
        track_message(context, chat_id, s2.message_id)
        return ConversationHandler.END
    sent = await update.message.reply_text(
        f"🔍 نتایج «{q}»:",
        reply_markup=paginated_exercises_kb(results, prefix="view_ex", page=0, nav_cb="exlibpg", back_cb="default_training_menu", show_content_emoji=True))
    track_message(context, chat_id, sent.message_id)
    s2 = await update.message.reply_text("یا جستجو کن 👇", reply_markup=SEARCH_EX_KB)
    track_message(context, chat_id, s2.message_id)
    return ConversationHandler.END


async def def_prog_list(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    programs = db.get_all_default_programs()
    if not programs:
        sent = await query.message.reply_text("❌ هیچ برنامه‌ای ثبت نشده.")
        track_message(context, query.message.chat_id, sent.message_id)
        return
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text("📋 *برنامه‌های تمرینی پیش‌فرض:*",
                                          reply_markup=default_programs_kb(programs), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


async def def_prog_view(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    program_id = int(query.data.split("_")[-1])
    context.user_data["viewing_prog"] = program_id
    program = db.get_default_program(program_id)
    exercises = db.get_default_program_exercises(program_id)
    if not exercises:
        text = f"📋 *{program['name']}*\n\nهیچ حرکتی ثبت نشده."
    else:
        lines = [f"📋 *برنامه: {program['name']}*\n"]
        for i, ex in enumerate(exercises, 1):
            lines.append(f"*{i}\\. {ex['exercise_name']}*")
            lines.append(f"   🔄 ست: {ex['sets']}   |   🔢 تکرار: {ex['reps']}")
        text = "\n".join(lines)
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text(text, reply_markup=program_detail_kb(program_id), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


async def def_prog_delete(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    program_id = int(query.data.split("_")[-1])
    prog = db.get_default_program(program_id)
    db.delete_default_program(program_id)
    await delete_bot_messages(context, query.message.chat_id)
    sent = await query.message.reply_text(f"🗑 برنامه *«{prog['name']}»* حذف شد.",
                                          reply_markup=MAIN_COACH_KB, parse_mode="Markdown")
    track_message(context, query.message.chat_id, sent.message_id)


async def def_prog_create_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query
    if query:
        await query.answer()
        chat_id = query.message.chat_id
        await delete_bot_messages(context, chat_id)
        sent = await query.message.reply_text("📝 نام برنامه تمرینی جدید را وارد کن:", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]]))
    else:
        chat_id = update.effective_chat.id
        await delete_bot_messages(context, chat_id)
        sent = await update.message.reply_text("📝 نام برنامه تمرینی جدید را وارد کن:", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]]))
    track_message(context, chat_id, sent.message_id)
    return DEF_PROG_NAME


async def def_prog_got_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
    name = update.message.text.strip()
    program_id = db.create_default_program(name)
    context.user_data["new_prog_id"] = program_id
    exercises = db.get_all_exercises()
    if not exercises:
        sent = await update.message.reply_text("❌ ابتدا باید حرکاتی در کتابخانه ثبت کنی.", reply_markup=MAIN_COACH_KB)
        track_message(context, update.effective_chat.id, sent.message_id)
        return ConversationHandler.END
    await delete_bot_messages(context, update.effective_chat.id)
    sent = await update.message.reply_text(
        f"✅ برنامه *«{name}»* ساخته شد.\n\n🏃 اولین حرکت را انتخاب کن:",
        reply_markup=_prog_ex_kb(0, exercises), parse_mode="Markdown")
    track_message(context, update.effective_chat.id, sent.message_id)
    s2 = await update.message.reply_text("یا جستجو کن 👇", reply_markup=SEARCH_EX_KB)
    track_message(context, update.effective_chat.id, s2.message_id)
    return DEF_PROG_SETS


async def def_prog_exercise_chosen(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    exercise_id = int(query.data.split("_")[-1])
    context.user_data["tmp_exercise_id"] = exercise_id
    ex = db.get_exercise(exercise_id)
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    kb = InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]])
    gif_url = ex.get("gif_url") if ex else None
    if gif_url:
        try:
            sent = await query.message.reply_animation(
                animation=gif_url,
                caption=f"💪 حرکت: *{ex['name']}*\n\nچند ست؟",
                parse_mode="Markdown", reply_markup=kb)
            track_message(context, chat_id, sent.message_id)
            return DEF_PROG_SETS
        except Exception:
            pass
    if ex.get("is_cardio"):
        context.user_data["tmp_sets"] = 0
        sent = await query.message.reply_text(
            f"🏃 *{ex['name']}* (هوازی)\n\n⏱ چند دقیقه؟",
            parse_mode="Markdown", reply_markup=kb)
        track_message(context, chat_id, sent.message_id)
        return DEF_PROG_REPS
    sent = await query.message.reply_text(
        f"💪 حرکت: *{ex['name']}*\n\nچند ست؟",
        parse_mode="Markdown", reply_markup=kb)
    track_message(context, chat_id, sent.message_id)
    return DEF_PROG_SETS


async def def_prog_got_sets(update: Update, context: ContextTypes.DEFAULT_TYPE):
    from utils.helpers import normalize_digits
    text = normalize_digits(update.message.text.strip())
    if not text.isdigit():
        sent = await update.message.reply_text("❗️ فقط عدد وارد کن.")
        track_message(context, update.effective_chat.id, sent.message_id)
        return DEF_PROG_SETS
    context.user_data["tmp_sets"] = int(text)
    sent = await update.message.reply_text("🔢 چند تایی (تعداد تکرار)؟", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]]))
    track_message(context, update.effective_chat.id, sent.message_id)
    return DEF_PROG_REPS


async def def_prog_got_reps(update: Update, context: ContextTypes.DEFAULT_TYPE):
    from utils.helpers import normalize_digits as _nd
    reps = update.message.text.strip()
    sets = context.user_data["tmp_sets"]
    if sets == 0:
        reps = _nd(reps)
        if not reps.isdigit():
            sent = await update.message.reply_text("❗️ فقط عدد (دقیقه) وارد کن.")
            track_message(context, update.effective_chat.id, sent.message_id)
            return DEF_PROG_REPS
    db.add_exercise_to_default_program(
        context.user_data["new_prog_id"],
        context.user_data["tmp_exercise_id"],
        sets, reps)
    ex = db.get_exercise(context.user_data["tmp_exercise_id"])
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    label = (f"⏱ {reps} دقیقه" if sets == 0 else f"{sets} ست × {reps} تکرار")
    sent = await update.message.reply_text(
        f"✅ *{ex['name']}* — {label} اضافه شد.\n\nبعدی؟",
        reply_markup=save_or_add_kb(), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)
    return DEF_PROG_REPS


async def def_prog_save(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    prog_id = context.user_data.get("new_prog_id")
    prog = db.get_default_program(prog_id)
    context.user_data.clear()
    await delete_bot_messages(context, query.message.chat_id)
    sent = await query.message.reply_text(
        f"🎉 برنامه *«{prog['name']}»* با موفقیت ذخیره شد!",
        reply_markup=MAIN_COACH_KB, parse_mode="Markdown")
    track_message(context, query.message.chat_id, sent.message_id)
    return ConversationHandler.END


async def def_prog_add_more(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    exercises = db.get_all_exercises()
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text(
        "🏃 یک حرکت دیگر انتخاب کن:",
        reply_markup=_prog_ex_kb(0, exercises))
    track_message(context, chat_id, sent.message_id)
    s2 = await query.message.reply_text("یا جستجو کن 👇", reply_markup=SEARCH_EX_KB)
    track_message(context, chat_id, s2.message_id)
    return DEF_PROG_SETS


add_exercise_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(def_ex_add_start, pattern="^def_ex_add$")],
    states={DEF_EX_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, def_ex_got_name)]},
    fallbacks=[
        CallbackQueryHandler(_cancel, pattern="^main_menu$"),
    ],
    per_message=False,
)


async def def_prog_got_search(update: Update, context: ContextTypes.DEFAULT_TYPE):
    q = update.message.text.strip()
    context.user_data["last_search"] = q
    add_row = [InlineKeyboardButton(f"➕ افزودن «{q}» به حرکات", callback_data="def_addex_new")]
    results = db.search_exercises(q)
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    if not results:
        results = db.get_all_exercises()
        kb = paginated_exercises_kb(results, prefix="prog_ex", page=0, nav_cb="progexpg", search_callback="def_search_ex", back_cb="default_training_menu")
        kb.inline_keyboard.insert(0, add_row)
        sent = await update.message.reply_text(
            f"❌ حرکتی با «{q}» پیدا نشد. می‌تونی اضافه‌اش کنی یا از لیست انتخاب کنی:",
            reply_markup=InlineKeyboardMarkup(kb.inline_keyboard))
        track_message(context, chat_id, sent.message_id)
        s2 = await update.message.reply_text("یا جستجو کن 👇", reply_markup=SEARCH_EX_KB)
        track_message(context, chat_id, s2.message_id)
        return DEF_PROG_SETS
    kb = paginated_exercises_kb(results, prefix="prog_ex", page=0, nav_cb="progexpg", search_callback="def_search_ex", back_cb="default_training_menu")
    kb.inline_keyboard.append(add_row)
    sent = await update.message.reply_text(
        f"🔍 نتایج «{q}»:",
        reply_markup=InlineKeyboardMarkup(kb.inline_keyboard))
    track_message(context, chat_id, sent.message_id)
    s2 = await update.message.reply_text("یا جستجو کن 👇", reply_markup=SEARCH_EX_KB)
    track_message(context, chat_id, s2.message_id)
    return DEF_PROG_SETS


async def def_addex_new(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    name = context.user_data.get("last_search")
    if not name:
        return DEF_PROG_SETS
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("🏋️ قدرتی", callback_data="def_addex_t_0"),
         InlineKeyboardButton("🏃 هوازی", callback_data="def_addex_t_1")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="default_training_menu")],
    ])
    chat_id = query.message.chat_id; await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text(
        f"➕ *{name}*\n\nاین حرکت چه نوعیه؟", parse_mode="Markdown", reply_markup=kb)
    track_message(context, chat_id, sent.message_id)
    return DEF_PROG_SETS


async def def_addex_type(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    is_cardio = int(query.data.split("_")[-1])
    name = context.user_data.pop("last_search", None)
    if not name:
        return DEF_PROG_SETS
    ex_id = db.execute("INSERT INTO default_exercises (name, is_cardio) VALUES (?,?)",
                       (name, is_cardio))
    query.data = f"prog_ex_{ex_id}"
    return await def_prog_exercise_chosen(update, context)


async def def_prog_search_cb(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Search exercise via callback یا دکمه کیبردی."""
    if update.callback_query:
        await update.callback_query.answer()
        chat_id = update.callback_query.message.chat_id
        send_func = update.callback_query.message.reply_text
    else:
        chat_id = update.effective_chat.id
        send_func = update.message.reply_text
    await delete_bot_messages(context, chat_id)
    sent = await send_func(
        "🔍 نام حرکت را بنویس:",
        reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]]))
    track_message(context, chat_id, sent.message_id)
    return DEF_PROG_SEARCH_EX


create_program_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(def_prog_create_start, pattern="^def_prog_create$")],
    states={
        DEF_PROG_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, def_prog_got_name)],
        DEF_PROG_SETS: [
            CallbackQueryHandler(def_addex_new,            pattern="^def_addex_new$"),
            CallbackQueryHandler(def_addex_type,           pattern=r"^def_addex_t_[01]$"),
            CallbackQueryHandler(def_prog_ex_page,         pattern=r"^progexpg_\d+$"),
            CallbackQueryHandler(def_prog_exercise_chosen, pattern=r"^prog_ex_\d+$"),
            CallbackQueryHandler(def_prog_search_cb, pattern="^def_search_ex$"),
            MessageHandler(filters.Regex("^🔍 جستجوی حرکت$"), def_prog_search_cb),
            MessageHandler(filters.TEXT & ~filters.COMMAND, def_prog_got_sets),
        ],
        DEF_PROG_SEARCH_EX: [
            CallbackQueryHandler(def_addex_new,            pattern="^def_addex_new$"),
            CallbackQueryHandler(def_addex_type,           pattern=r"^def_addex_t_[01]$"),
            CallbackQueryHandler(def_prog_ex_page,         pattern=r"^progexpg_\d+$"),
            CallbackQueryHandler(def_prog_exercise_chosen, pattern=r"^prog_ex_\d+$"),
            MessageHandler(filters.Regex("^🔍 جستجوی حرکت$"), def_prog_search_cb),
            MessageHandler(filters.TEXT & ~filters.COMMAND, def_prog_got_search),
        ],
        DEF_PROG_REPS: [
            MessageHandler(filters.TEXT & ~filters.COMMAND, def_prog_got_reps),
            CallbackQueryHandler(def_prog_save,            pattern="^prog_save$"),
            CallbackQueryHandler(def_prog_add_more,        pattern="^prog_add_more$"),
            CallbackQueryHandler(def_prog_exercise_chosen, pattern=r"^prog_ex_\d+$"),
        ],
    },
    fallbacks=[
        CallbackQueryHandler(_cancel, pattern="^main_menu$"),
        CallbackQueryHandler(_cancel, pattern="^default_training_menu$"),
    ],
    per_message=False,
)


def_ex_view_search_conv = ConversationHandler(
    entry_points=[MessageHandler(filters.Regex("^🔍 جستجوی حرکت$"), def_ex_view_search_start)],
    states={
        DEF_EX_VIEW_SEARCH: [
            CallbackQueryHandler(def_ex_view_detail, pattern=r"^view_ex_\d+$"),
            MessageHandler(filters.TEXT & ~filters.COMMAND, def_ex_view_search_got),
        ],
    },
    fallbacks=[CallbackQueryHandler(_cancel, pattern="^main_menu$")],
    per_message=False,
)

def_ex_add_photo_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(def_ex_add_photo_start, pattern=r"^exadd_photo_\d+$")],
    states={EX_ADD_PHOTO: [MessageHandler(filters.PHOTO, def_ex_add_photo_got)]},
    fallbacks=[CallbackQueryHandler(_cancel, pattern="^main_menu$"),
               CallbackQueryHandler(_cancel, pattern="^def_ex_list$")],
    per_message=False,
)

def_ex_add_video_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(def_ex_add_video_start, pattern=r"^exadd_video_\d+$")],
    states={EX_ADD_VIDEO: [MessageHandler(filters.VIDEO, def_ex_add_video_got)]},
    fallbacks=[CallbackQueryHandler(_cancel, pattern="^main_menu$"),
               CallbackQueryHandler(_cancel, pattern="^def_ex_list$")],
    per_message=False,
)

def_ex_add_desc_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(def_ex_add_desc_start, pattern=r"^exadd_desc_\d+$")],
    states={EX_ADD_DESC: [MessageHandler(filters.TEXT & ~filters.COMMAND, def_ex_add_desc_got)]},
    fallbacks=[CallbackQueryHandler(_cancel, pattern="^main_menu$"),
               CallbackQueryHandler(_cancel, pattern="^def_ex_list$")],
    per_message=False,
)


async def _default_training_menu_cb(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """بازگشت به منوی تمرین پیش‌فرض از طریق callback."""
    query = update.callback_query; await query.answer()
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    sent = await query.message.reply_text(
        "🏋️ *تمرین پیش‌فرض*\nیکی از گزینه‌ها را انتخاب کن:",
        reply_markup=default_training_menu_kb(), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


def register(app):
    from telegram.ext import MessageHandler, filters as f
    app.add_handler(MessageHandler(f.Regex("^🏋️ تمرین پیش‌فرض$"), default_training_menu))
    app.add_handler(CallbackQueryHandler(_default_training_menu_cb, pattern="^default_training_menu$"))
    app.add_handler(add_exercise_conv)
    app.add_handler(create_program_conv)
    app.add_handler(def_ex_view_search_conv)
    app.add_handler(def_ex_add_photo_conv)
    app.add_handler(def_ex_add_video_conv)
    app.add_handler(def_ex_add_desc_conv)
    app.add_handler(CallbackQueryHandler(def_ex_list,        pattern="^def_ex_list$"))
    app.add_handler(CallbackQueryHandler(def_ex_lib_page,    pattern=r"^exlibpg_\d+$"))
    app.add_handler(CallbackQueryHandler(def_ex_view_detail, pattern=r"^view_ex_\d+$"))
    app.add_handler(CallbackQueryHandler(def_prog_list,  pattern="^def_prog_list$"))
    app.add_handler(CallbackQueryHandler(def_prog_view,  pattern=r"^def_prog_\d+$"))
    app.add_handler(CallbackQueryHandler(def_prog_delete, pattern=r"^del_def_prog_\d+$"))
