from aiogram import Router, F
from aiogram.filters import Command
from aiogram.types import Message, CallbackQuery
from keyboards.main_menu import get_main_menu
from keyboards.inline import get_marathons_keyboard, get_marathon_details_keyboard, get_settings_keyboard
from services.api_client import api_client
router = Router()
@router.message(Command("marathons"))
@router.message(F.text == "📊 Мои марафоны")
async def cmd_marathons(message: Message):
"""Show user's marathons."""
user = await api_client.get_user_by_telegram_id(message.from_user.id)
if not user:
await message.answer(
"Сначала привяжи аккаунт через настройки профиля на сайте.",
reply_markup=get_main_menu()
)
return
marathons = await api_client.get_user_marathons(message.from_user.id)
if not marathons:
await message.answer(
"Мои марафоны\n\n"
"У тебя пока нет активных марафонов.\n"
"Присоединись к марафону на сайте!",
reply_markup=get_main_menu()
)
return
text = "📊 Мои марафоны\n\n"
for m in marathons:
status_emoji = {
"preparing": "⏳",
"active": "🎮",
"finished": "🏁"
}.get(m.get("status"), "❓")
text += f"{status_emoji} {m.get('title')}\n"
text += f" Очки: {m.get('total_points', 0)} | "
text += f"Место: #{m.get('position', '?')}\n\n"
await message.answer(
text,
reply_markup=get_marathons_keyboard(marathons)
)
@router.callback_query(F.data.startswith("marathon:"))
async def marathon_details(callback: CallbackQuery):
"""Show marathon details."""
marathon_id = int(callback.data.split(":")[1])
details = await api_client.get_marathon_details(
marathon_id=marathon_id,
telegram_id=callback.from_user.id
)
if not details:
await callback.answer("Не удалось загрузить данные марафона", show_alert=True)
return
marathon = details.get("marathon", {})
participant = details.get("participant", {})
active_events = details.get("active_events", [])
current_assignment = details.get("current_assignment")
status_text = {
"preparing": "⏳ Подготовка",
"active": "🎮 Активен",
"finished": "🏁 Завершён"
}.get(marathon.get("status"), "❓")
text = f"{marathon.get('title')}\n"
text += f"Статус: {status_text}\n\n"
text += f"📈 Твоя статистика:\n"
text += f"• Очки: {participant.get('total_points', 0)}\n"
text += f"• Место: #{details.get('position', '?')}\n"
text += f"• Стрик: {participant.get('current_streak', 0)} 🔥\n"
text += f"• Дропов: {participant.get('drop_count', 0)}\n\n"
if active_events:
text += "⚡ Активные события:\n"
for event in active_events:
event_emoji = {
"golden_hour": "🌟",
"jackpot": "🎰",
"double_risk": "⚡",
"common_enemy": "👥",
"swap": "🔄",
"game_choice": "🎲"
}.get(event.get("type"), "📌")
text += f"{event_emoji} {event.get('type', '').replace('_', ' ').title()}\n"
text += "\n"
if current_assignment:
challenge = current_assignment.get("challenge", {})
game = challenge.get("game", {})
text += f"🎯 Текущее задание:\n"
text += f"Игра: {game.get('title', 'N/A')}\n"
text += f"Задание: {challenge.get('title', 'N/A')}\n"
text += f"Сложность: {challenge.get('difficulty', 'N/A')}\n"
text += f"Очки: {challenge.get('points', 0)}\n"
await callback.message.edit_text(
text,
reply_markup=get_marathon_details_keyboard(marathon_id)
)
await callback.answer()
@router.callback_query(F.data == "back_to_marathons")
async def back_to_marathons(callback: CallbackQuery):
"""Go back to marathons list."""
marathons = await api_client.get_user_marathons(callback.from_user.id)
if not marathons:
await callback.message.edit_text(
"Мои марафоны\n\n"
"У тебя пока нет активных марафонов."
)
await callback.answer()
return
text = "📊 Мои марафоны\n\n"
for m in marathons:
status_emoji = {
"preparing": "⏳",
"active": "🎮",
"finished": "🏁"
}.get(m.get("status"), "❓")
text += f"{status_emoji} {m.get('title')}\n"
text += f" Очки: {m.get('total_points', 0)} | "
text += f"Место: #{m.get('position', '?')}\n\n"
await callback.message.edit_text(
text,
reply_markup=get_marathons_keyboard(marathons)
)
await callback.answer()
@router.message(Command("stats"))
@router.message(F.text == "📈 Статистика")
async def cmd_stats(message: Message):
"""Show user's overall statistics."""
user = await api_client.get_user_by_telegram_id(message.from_user.id)
if not user:
await message.answer(
"Сначала привяжи аккаунт через настройки профиля на сайте.",
reply_markup=get_main_menu()
)
return
stats = await api_client.get_user_stats(message.from_user.id)
if not stats:
await message.answer(
"📈 Статистика\n\n"
"Пока нет данных для отображения.\n"
"Начни участвовать в марафонах!",
reply_markup=get_main_menu()
)
return
text = f"📈 Общая статистика\n\n"
text += f"👤 {user.get('nickname', 'Игрок')}\n\n"
text += f"🏆 Марафонов завершено: {stats.get('marathons_completed', 0)}\n"
text += f"🎮 Марафонов активно: {stats.get('marathons_active', 0)}\n"
text += f"✅ Заданий выполнено: {stats.get('challenges_completed', 0)}\n"
text += f"💰 Всего очков: {stats.get('total_points', 0)}\n"
text += f"🔥 Лучший стрик: {stats.get('best_streak', 0)}\n"
await message.answer(text, reply_markup=get_main_menu())
@router.message(Command("settings"))
@router.message(F.text == "⚙️ Настройки")
async def cmd_settings(message: Message):
"""Show notification settings."""
user = await api_client.get_user_by_telegram_id(message.from_user.id)
if not user:
await message.answer(
"Сначала привяжи аккаунт через настройки профиля на сайте.",
reply_markup=get_main_menu()
)
return
# Get current notification settings
settings = await api_client.get_notification_settings(message.from_user.id)
if not settings:
settings = {"notify_events": True, "notify_disputes": True, "notify_moderation": True}
await message.answer(
"⚙️ Настройки уведомлений\n\n"
"Нажми на категорию, чтобы включить/выключить:\n\n"
"✅ — уведомления включены\n"
"❌ — уведомления выключены\n\n"
"Уведомления о старте/финише марафонов и коды безопасности нельзя отключить.",
reply_markup=get_settings_keyboard(settings)
)
@router.callback_query(F.data.startswith("toggle:"))
async def toggle_notification(callback: CallbackQuery):
"""Toggle notification setting."""
setting_name = callback.data.split(":")[1]
# Get current settings
current_settings = await api_client.get_notification_settings(callback.from_user.id)
if not current_settings:
await callback.answer("Не удалось загрузить настройки", show_alert=True)
return
# Toggle the setting
current_value = current_settings.get(setting_name, True)
new_value = not current_value
# Update on backend
result = await api_client.update_notification_settings(
callback.from_user.id,
{setting_name: new_value}
)
if not result or result.get("error"):
await callback.answer("Не удалось сохранить настройки", show_alert=True)
return
# Update keyboard with new values
await callback.message.edit_reply_markup(
reply_markup=get_settings_keyboard(result)
)
status = "включены" if new_value else "выключены"
setting_names = {
"notify_events": "События",
"notify_disputes": "Споры",
"notify_moderation": "Модерация"
}
await callback.answer(f"{setting_names.get(setting_name, setting_name)}: {status}")
@router.callback_query(F.data == "back_to_menu")
async def back_to_menu(callback: CallbackQuery):
"""Go back to main menu from settings."""
await callback.message.delete()
await callback.message.answer(
"Главное меню",
reply_markup=get_main_menu()
)
await callback.answer()