"""
/start — coach | registered athlete | guest routing.
"""
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
    ContextTypes, CommandHandler, MessageHandler, ConversationHandler,
    filters, CallbackQueryHandler,
)
from config.settings import (
    COACHES, ATH_PHOTO_UPLOAD,
    ATH_EDIT_SELF_AGE, ATH_EDIT_SELF_HEIGHT,
    ATH_EDIT_SELF_WEIGHT, ATH_EDIT_SELF_PHONE,
)
from utils.keyboards import MAIN_COACH_KB, BACK_KB, training_days_kb, day_exercises_kb
from utils.helpers import go_main_menu, track_message, delete_bot_messages, normalize_digits
from utils.jalali import today_jalali, format_jalali
import database.db as db


# ─── Athlete main keyboard ────────────────────────────────────────────────────

def _athlete_main_kb():
    return InlineKeyboardMarkup([
        [InlineKeyboardButton("🏋️ برنامه تمرینی",  callback_data="ath_view_training"),
         InlineKeyboardButton("🥗 برنامه غذایی",   callback_data="ath_view_diet")],
        [InlineKeyboardButton("💊 برنامه مکمل",    callback_data="ath_view_supplement"),
         InlineKeyboardButton("📸 گالری تصاویر",   callback_data="ath_gallery_self")],
        [InlineKeyboardButton("✏️ ویرایش اطلاعات", callback_data="ath_edit_self"),
         InlineKeyboardButton("📄 دریافت PDF",      callback_data="ath_get_pdf")],
        [InlineKeyboardButton("🛒 فروشگاه",         callback_data="ath_shop_menu")],
        [InlineKeyboardButton("💬 ارتباط با مربی",  callback_data="ath_contact_coach")],
        [InlineKeyboardButton("🌐 دریافت کد سایت",  callback_data="get_web_code")],
    ])


def _back_to_panel_btn():
    return InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="ath_back_panel")]])


def _back_to_gallery_btn():
    return InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت به گالری", callback_data="ath_gallery_self")]])


# ─── /start ──────────────────────────────────────────────────────────────────

async def cmd_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    username = (update.effective_user.username or "").upper()
    chat_id = update.effective_chat.id

    if username in [c.upper() for c in COACHES]:
        import config.settings as _cfg
        if _cfg.COACH_CHAT_ID is None:
            _cfg.COACH_CHAT_ID = chat_id
        await delete_bot_messages(context, chat_id)
        sent = await update.message.reply_text(
            "👋 *خوش اومدی به پنل مربی!*\n\nیکی از گزینه‌ها رو انتخاب کن:",
            reply_markup=MAIN_COACH_KB, parse_mode="Markdown")
        track_message(context, chat_id, sent.message_id)
        return

    athlete = db.get_athlete_by_username(update.effective_user.username or "")
    if athlete:
        context.user_data["athlete_user_id"] = athlete["id"]
        # Save telegram_id for broadcasts
        if not athlete.get("telegram_id"):
            db.save_athlete_chat_id(athlete["id"], chat_id)
        await delete_bot_messages(context, chat_id)
        sent = await update.message.reply_text(
            f"👋 سلام *{athlete['full_name']}* عزیز! 🏋️\n\nچی می‌خوای؟",
            reply_markup=_athlete_main_kb(), parse_mode="Markdown")
        track_message(context, chat_id, sent.message_id)
        return

    # مهمان: ثبت‌نام یا فروشگاه
    await delete_bot_messages(context, chat_id)
    sent = await update.message.reply_text(
        "👋 *به باشگاه میلاد خوش اومدی!*\n\n"
        "هنوز ثبت‌نام نکردی. برای دسترسی به پنل شخصی، برنامه تمرینی و رژیم، اول ثبت‌نام کن:",
        reply_markup=InlineKeyboardMarkup([
            [InlineKeyboardButton("📝 ثبت‌نام ورزشکار", callback_data="self_register")],
            [InlineKeyboardButton("🌐 دریافت کد سایت", callback_data="get_web_code")],
            [InlineKeyboardButton("🛒 فروشگاه", callback_data="ath_shop_menu")],
        ]), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


# ─── Athlete panel back ───────────────────────────────────────────────────────

async def ath_back_panel(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    athlete_id = context.user_data.get("athlete_user_id")
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)
    if not athlete_id:
        from handlers.shop import athlete_shop_menu
        await athlete_shop_menu(update, context); return
    athlete = db.get_athlete(athlete_id)
    sent = await query.message.reply_text(
        f"👋 سلام *{athlete['full_name']}* عزیز! 🏋️\n\nچی می‌خوای؟",
        reply_markup=_athlete_main_kb(), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


# ─── View sections ────────────────────────────────────────────────────────────

async def ath_view_training(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """نمایش منوی روزهای تمرین به صورت شیشه‌ای."""
    query = update.callback_query; await query.answer()
    athlete_id = context.user_data.get("athlete_user_id")
    chat_id = query.message.chat_id; await delete_bot_messages(context, chat_id)
    days = db.get_athlete_training_days(athlete_id)
    if not days:
        sent = await query.message.reply_text(
            "🏋️ هنوز برنامه تمرینی ثبت نشده.", reply_markup=_back_to_panel_btn())
        track_message(context, chat_id, sent.message_id); return
    sent = await query.message.reply_text(
        "🏋️ *برنامه تمرینی*\n\nروز تمرین خود را انتخاب کن 👇",
        reply_markup=training_days_kb(days), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


async def ath_view_day(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """نمایش لیست تمرینات یک روز به صورت شیشه‌ای."""
    query = update.callback_query; await query.answer()
    day_num = int(query.data.split("_")[-1])
    context.user_data["ath_viewing_day"] = day_num
    athlete_id = context.user_data.get("athlete_user_id")
    chat_id = query.message.chat_id; await delete_bot_messages(context, chat_id)
    exs = db.get_athlete_day_exercises(athlete_id, day_num)
    if not exs:
        sent = await query.message.reply_text(
            f"📅 روز {day_num} — هیچ تمرینی ثبت نشده.",
            reply_markup=_back_to_panel_btn())
        track_message(context, chat_id, sent.message_id); return
    sent = await query.message.reply_text(
        f"📅 *روز {day_num}*\n\nروی هر حرکت بزن تا محتوا ببینی 👇",
        reply_markup=day_exercises_kb(exs, day_num), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


async def ath_ex_detail(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """نمایش محتوای یک حرکت برای ورزشکار (عکس/فیلم/توضیح)."""
    query = update.callback_query; await query.answer()
    exercise_id = int(query.data.split("_")[-1])
    day_num = context.user_data.get("ath_viewing_day", 1)
    ex = db.get_exercise(exercise_id)
    chat_id = query.message.chat_id; await delete_bot_messages(context, chat_id)
    back_kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("🔙 بازگشت به روز", callback_data=f"ath_view_day_{day_num}")]
    ])
    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=back_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=back_kb)
    elif ex.get("gif_url"):
        try:
            sent = await query.message.reply_animation(
                animation=ex["gif_url"], caption=caption, parse_mode="Markdown", reply_markup=back_kb)
        except Exception:
            sent = await query.message.reply_text(caption, parse_mode="Markdown", reply_markup=back_kb)
    else:
        caption += "\n\n_محتوایی برای این حرکت ثبت نشده._"
        sent = await query.message.reply_text(caption, parse_mode="Markdown", reply_markup=back_kb)
    track_message(context, chat_id, sent.message_id)


async def ath_view_diet(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    athlete_id = context.user_data.get("athlete_user_id")
    chat_id = query.message.chat_id; await delete_bot_messages(context, chat_id)
    diet = db.get_athlete_diet(athlete_id)
    text = f"🥗 *برنامه غذایی شما:*\n\n{diet['diet_text']}" if diet else "🥗 هنوز برنامه غذایی ثبت نشده."
    sent = await query.message.reply_text(text, reply_markup=_back_to_panel_btn(), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


async def ath_view_supplement(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    athlete_id = context.user_data.get("athlete_user_id")
    chat_id = query.message.chat_id; await delete_bot_messages(context, chat_id)
    supp = db.get_athlete_supplement(athlete_id)
    text = f"💊 *برنامه مکمل شما:*\n\n{supp['supplement_text']}" if supp else "💊 هنوز برنامه مکملی ثبت نشده."
    sent = await query.message.reply_text(text, reply_markup=_back_to_panel_btn(), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


# ─── PDF ─────────────────────────────────────────────────────────────────────

async def ath_get_pdf(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    athlete_id = context.user_data.get("athlete_user_id")
    if not athlete_id: return
    chat_id = query.message.chat_id

    loading = await query.message.reply_text("⏳ در حال ساخت PDF...")
    track_message(context, chat_id, loading.message_id)

    try:
        from utils.pdf import generate_athlete_pdf
        import io as _io
        athlete = db.get_athlete(athlete_id)
        days = db.get_athlete_training_days(athlete_id)
        training_days = {d: db.get_athlete_day_exercises(athlete_id, d) for d in days}
        diet_row = db.get_athlete_diet(athlete_id)
        supp_row = db.get_athlete_supplement(athlete_id)
        pdf_bytes = generate_athlete_pdf(
            athlete, training_days,
            diet_row["diet_text"] if diet_row else None,
            supp_row["supplement_text"] if supp_row else None
        )
        if not pdf_bytes:
            raise ValueError("PDF خالی برگشت — pip install matplotlib Pillow numpy")
        try:
            await context.bot.delete_message(chat_id=chat_id, message_id=loading.message_id)
        except Exception: pass
        bio = _io.BytesIO(pdf_bytes); bio.name = f"{athlete['full_name']}.pdf"
        await query.message.reply_document(document=bio, caption=f"📄 پروفایل {athlete['full_name']}")
    except Exception as e:
        try:
            await context.bot.delete_message(chat_id=chat_id, message_id=loading.message_id)
        except Exception: pass
        sent = await query.message.reply_text(
            f"❌ خطا در ساخت PDF:\n`{str(e)[:300]}`\n\n"
            "لطفاً نصب کنید:\n`pip install matplotlib Pillow numpy`",
            reply_markup=_back_to_panel_btn(), parse_mode="Markdown")
        track_message(context, chat_id, sent.message_id)


# ─── Gallery ─────────────────────────────────────────────────────────────────

async def ath_gallery_self(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    athlete_id = context.user_data.get("athlete_user_id")
    photos = db.get_athlete_photos(athlete_id)
    chat_id = query.message.chat_id
    await delete_bot_messages(context, chat_id)

    gallery_kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("📸 ارسال عکس جدید", callback_data="ath_upload_photo")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="ath_back_panel")],
    ])

    if not photos:
        sent = await query.message.reply_text(
            "📸 *گالری تصاویر*\n\nهنوز عکسی ارسال نکردی.\nاولین عکست رو بفرست! 💪",
            reply_markup=gallery_kb, parse_mode="Markdown")
        track_message(context, chat_id, sent.message_id)
        return

    sent = await query.message.reply_text(
        f"📸 *گالری تصاویر* — {len(photos)} عکس:",
        reply_markup=gallery_kb, parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)

    for ph in photos[:10]:
        try:
            caption = f"📅 {format_jalali(ph['jalali_date'])}"
            del_kb = InlineKeyboardMarkup([[
                InlineKeyboardButton(f"🗑 حذف", callback_data=f"ath_del_photo_{ph['id']}")
            ]])
            s = await query.message.reply_photo(
                photo=ph["file_id"], caption=caption, reply_markup=del_kb)
            track_message(context, chat_id, s.message_id)
        except Exception:
            pass


async def ath_del_own_photo(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.callback_query; await query.answer()
    photo_id = int(query.data.split("_")[-1])
    db.delete_athlete_photo(photo_id)
    try:
        await query.message.delete()
    except Exception:
        pass
    sent = await query.message.reply_text(
        "🗑 عکس حذف شد.", reply_markup=_back_to_gallery_btn())
    track_message(context, query.message.chat_id, sent.message_id)


async def ath_upload_photo_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)
    kb = InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="ath_gallery_self")]])
    sent = await query.message.reply_text("📸 عکس خود را ارسال کن:", reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]]))
    track_message(context, chat_id, sent.message_id)
    return ATH_PHOTO_UPLOAD


async def ath_upload_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 ATH_PHOTO_UPLOAD
    athlete_id = context.user_data["athlete_user_id"]
    file_id = update.message.photo[-1].file_id
    jalali = today_jalali()
    db.add_athlete_photo(athlete_id, file_id, jalali)
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("📸 مشاهده گالری", callback_data="ath_gallery_self")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="ath_back_panel")],
    ])
    sent = await update.message.reply_text(
        f"✅ عکس با تاریخ *{format_jalali(jalali)}* ذخیره شد! 📸",
        reply_markup=kb, parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)
    return ConversationHandler.END


async def _cancel_ath(update, context):
    athlete_id = context.user_data.get("athlete_user_id")
    chat_id = update.effective_chat.id
    await delete_bot_messages(context, chat_id)
    if athlete_id:
        athlete = db.get_athlete(athlete_id)
        sent = await update.effective_message.reply_text(
            f"👋 سلام *{athlete['full_name']}*!\n\nچی می‌خوای؟",
            reply_markup=_athlete_main_kb(), parse_mode="Markdown")
        track_message(context, chat_id, sent.message_id)
    return ConversationHandler.END


# ─── Edit self ───────────────────────────────────────────────────────────────

async def ath_edit_self(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)
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("🎂 سن",      callback_data="ath_edit_age"),
         InlineKeyboardButton("📏 قد",      callback_data="ath_edit_height")],
        [InlineKeyboardButton("⚖️ وزن",    callback_data="ath_edit_weight"),
         InlineKeyboardButton("📞 موبایل", callback_data="ath_edit_phone")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="ath_back_panel")],
    ])
    sent = await query.message.reply_text(
        "✏️ *ویرایش اطلاعات*\nکدام مورد را تغییر می‌دهی؟",
        reply_markup=kb, parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)


async def _ath_edit_start(update, context, field, prompt, state):
    query = update.callback_query; await query.answer()
    context.user_data["ath_edit_field"] = field
    chat_id = query.message.chat_id; await delete_bot_messages(context, chat_id)
    kb = InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="ath_edit_self")]])
    sent = await query.message.reply_text(prompt, reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("🔙 بازگشت", callback_data="main_menu")]]))
    track_message(context, chat_id, sent.message_id)
    return state


async def ath_edit_age_start(u, c):    return await _ath_edit_start(u, c, "age",    "🎂 سن جدید را وارد کن:", ATH_EDIT_SELF_AGE)
async def ath_edit_height_start(u, c): return await _ath_edit_start(u, c, "height", "📏 قد جدید را وارد کن (سانتی‌متر):", ATH_EDIT_SELF_HEIGHT)
async def ath_edit_weight_start(u, c): return await _ath_edit_start(u, c, "weight", "⚖️ وزن جدید را وارد کن (کیلوگرم):", ATH_EDIT_SELF_WEIGHT)
async def ath_edit_phone_start(u, c):  return await _ath_edit_start(u, c, "phone",  "📞 شماره موبایل جدید را وارد کن:", ATH_EDIT_SELF_PHONE)


async def _ath_edit_got_value(update: Update, context: ContextTypes.DEFAULT_TYPE):
    text = update.message.text.strip()
    field = context.user_data.get("ath_edit_field")
    athlete_id = context.user_data["athlete_user_id"]
    norm = normalize_digits(text)
    if field in ("age", "height"):
        if not norm.isdigit():
            await update.message.reply_text("❗️ فقط عدد وارد کن."); return
        db.update_athlete_field(athlete_id, field, int(norm))
    elif field == "weight":
        try:
            db.update_athlete_field(athlete_id, field, float(norm.replace(",", ".")))
        except ValueError:
            await update.message.reply_text("❗️ عدد معتبر وارد کن."); return
    elif field == "phone":
        if not (norm.isdigit() and 8 <= len(norm) <= 15):
            await update.message.reply_text("❗️ شماره معتبر نیست."); return
        db.update_athlete_field(athlete_id, field, norm)
    chat_id = update.effective_chat.id; await delete_bot_messages(context, chat_id)
    athlete = db.get_athlete(athlete_id)
    sent = await update.message.reply_text(
        f"✅ اطلاعات به‌روز شد! 👍\n\n👋 سلام *{athlete['full_name']}*!\n\nچی می‌خوای؟",
        reply_markup=_athlete_main_kb(), parse_mode="Markdown")
    track_message(context, chat_id, sent.message_id)
    return ConversationHandler.END


# ─── Conversations ────────────────────────────────────────────────────────────

ath_photo_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(ath_upload_photo_start, pattern="^ath_upload_photo$")],
    states={ATH_PHOTO_UPLOAD: [MessageHandler(filters.PHOTO | (filters.TEXT & ~filters.COMMAND), ath_upload_photo_got)]},
    fallbacks=[MessageHandler(filters.Regex("^🏠 بازگشت به منوی اصلی$"), _cancel_ath),
               CallbackQueryHandler(_cancel_ath, pattern="^main_menu$"),
               CallbackQueryHandler(_cancel_ath, pattern="^ath_back_panel$")],
    per_message=False,
)
ath_edit_age_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(ath_edit_age_start, pattern="^ath_edit_age$")],
    states={ATH_EDIT_SELF_AGE: [MessageHandler(filters.TEXT & ~filters.COMMAND, _ath_edit_got_value)]},
    fallbacks=[MessageHandler(filters.Regex("^🏠 بازگشت به منوی اصلی$"), _cancel_ath),
               CallbackQueryHandler(_cancel_ath, pattern="^main_menu$")],
    per_message=False,
)
ath_edit_height_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(ath_edit_height_start, pattern="^ath_edit_height$")],
    states={ATH_EDIT_SELF_HEIGHT: [MessageHandler(filters.TEXT & ~filters.COMMAND, _ath_edit_got_value)]},
    fallbacks=[MessageHandler(filters.Regex("^🏠 بازگشت به منوی اصلی$"), _cancel_ath),
               CallbackQueryHandler(_cancel_ath, pattern="^main_menu$")],
    per_message=False,
)
ath_edit_weight_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(ath_edit_weight_start, pattern="^ath_edit_weight$")],
    states={ATH_EDIT_SELF_WEIGHT: [MessageHandler(filters.TEXT & ~filters.COMMAND, _ath_edit_got_value)]},
    fallbacks=[MessageHandler(filters.Regex("^🏠 بازگشت به منوی اصلی$"), _cancel_ath),
               CallbackQueryHandler(_cancel_ath, pattern="^main_menu$")],
    per_message=False,
)
ath_edit_phone_conv = ConversationHandler(
    entry_points=[CallbackQueryHandler(ath_edit_phone_start, pattern="^ath_edit_phone$")],
    states={ATH_EDIT_SELF_PHONE: [MessageHandler(filters.TEXT & ~filters.COMMAND, _ath_edit_got_value)]},
    fallbacks=[MessageHandler(filters.Regex("^🏠 بازگشت به منوی اصلی$"), _cancel_ath),
               CallbackQueryHandler(_cancel_ath, pattern="^main_menu$")],
    per_message=False,
)


# ─── Coach back to main ───────────────────────────────────────────────────────

async def back_to_main(update: Update, context: ContextTypes.DEFAULT_TYPE):
    username = (update.effective_user.username or "").upper()
    if username in [c.upper() for c in COACHES]:
        await go_main_menu(update, context)
    else:
        await _cancel_ath(update, context)


def register(app):
    app.add_handler(CommandHandler("start", cmd_start))
    # این هندلر در گروه ۱ ثبت می‌شود تا فقط زمانی اجرا شود که
    # هیچ ConversationHandler فعالی (در گروه ۰) درخواست را نگرفته باشد.
    # در غیر این صورت، این هندلر زودتر از fallback های مکالمات فعال
    # callback مربوط به دکمه بازگشت را می‌گرفت و باعث می‌شد مکالمه
    # داخلی هرگز خاتمه پیدا نکند (باگ بازگشت در همه بخش‌ها).
    app.add_handler(CallbackQueryHandler(back_to_main, pattern="^main_menu$"), group=1)
    app.add_handler(CallbackQueryHandler(ath_back_panel,        pattern="^ath_back_panel$"), group=1)
    app.add_handler(CallbackQueryHandler(ath_view_training,     pattern="^ath_view_training$"))
    app.add_handler(CallbackQueryHandler(ath_view_day,          pattern=r"^ath_view_day_\d+$"))
    app.add_handler(CallbackQueryHandler(ath_ex_detail,         pattern=r"^ath_ex_detail_\d+$"))
    app.add_handler(CallbackQueryHandler(ath_view_diet,         pattern="^ath_view_diet$"))
    app.add_handler(CallbackQueryHandler(ath_view_supplement,   pattern="^ath_view_supplement$"))
    app.add_handler(CallbackQueryHandler(ath_get_pdf,           pattern="^ath_get_pdf$"))
    app.add_handler(CallbackQueryHandler(ath_gallery_self,      pattern="^ath_gallery_self$"))
    app.add_handler(CallbackQueryHandler(ath_del_own_photo,     pattern=r"^ath_del_photo_\d+$"))
    app.add_handler(CallbackQueryHandler(ath_edit_self,         pattern="^ath_edit_self$"))
    app.add_handler(ath_photo_conv)
    app.add_handler(ath_edit_age_conv)
    app.add_handler(ath_edit_height_conv)
    app.add_handler(ath_edit_weight_conv)
    app.add_handler(ath_edit_phone_conv)
