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()