"""Handlers for inline button callbacks (done, snooze, pause, delete).""" from aiogram import Router, F from aiogram.types import CallbackQuery, Message from sqlalchemy.ext.asyncio import AsyncSession from bot.keyboards.reminders import ( ReminderActionCallback, SnoozeDelayCallback, ConfirmCallback, get_snooze_delay_keyboard, get_confirmation_keyboard, ) from bot.keyboards.main_menu import get_main_menu_keyboard from bot.services.reminders_service import RemindersService from bot.services.time_service import get_time_service from bot.logging_config import get_logger logger = get_logger(__name__) router = Router(name="callbacks") reminders_service = RemindersService() time_service = get_time_service() # ==================== Done Action ==================== @router.callback_query(ReminderActionCallback.filter(F.action == "done")) async def handle_done( callback: CallbackQuery, callback_data: ReminderActionCallback, session: AsyncSession, ) -> None: """ Handle 'Done' button - mark reminder as completed. Args: callback: Callback query callback_data: Parsed callback data session: Database session """ reminder = await reminders_service.mark_as_done(session, callback_data.reminder_id) if not reminder: await callback.answer("Напоминание не найдено", show_alert=True) return next_run_str = time_service.format_next_run(reminder.next_run_at) await callback.message.edit_text( f"✅ Отлично! Отметил как выполненное.\n\n" f"Следующее напоминание будет {next_run_str}." ) await callback.answer("Выполнено!") logger.info(f"Reminder {reminder.id} marked as done by user {callback.from_user.id}") # ==================== Snooze Action ==================== @router.callback_query(ReminderActionCallback.filter(F.action == "snooze")) async def handle_snooze_select( callback: CallbackQuery, callback_data: ReminderActionCallback, ) -> None: """ Handle 'Snooze' button - show delay options. Args: callback: Callback query callback_data: Parsed callback data """ await callback.message.edit_text( "На сколько отложить напоминание?", reply_markup=get_snooze_delay_keyboard(callback_data.reminder_id), ) await callback.answer() @router.callback_query(SnoozeDelayCallback.filter()) async def handle_snooze_delay( callback: CallbackQuery, callback_data: SnoozeDelayCallback, session: AsyncSession, ) -> None: """ Handle snooze delay selection. Args: callback: Callback query callback_data: Parsed callback data session: Database session """ reminder = await reminders_service.snooze( session, callback_data.reminder_id, callback_data.hours ) if not reminder: await callback.answer("Напоминание не найдено", show_alert=True) return next_run_str = time_service.format_next_run(reminder.next_run_at) await callback.message.edit_text( f"⏰ Напоминание отложено.\n\n" f"Напомню {next_run_str}." ) await callback.answer("Отложено!") logger.info( f"Reminder {reminder.id} snoozed for {callback_data.hours}h " f"by user {callback.from_user.id}" ) # ==================== Pause/Resume Actions ==================== @router.callback_query(ReminderActionCallback.filter(F.action == "pause")) async def handle_pause( callback: CallbackQuery, callback_data: ReminderActionCallback, session: AsyncSession, ) -> None: """ Handle 'Pause' button - deactivate reminder. Args: callback: Callback query callback_data: Parsed callback data session: Database session """ reminder = await reminders_service.pause_reminder(session, callback_data.reminder_id) if not reminder: await callback.answer("Напоминание не найдено", show_alert=True) return await callback.message.edit_text( "⏸ Напоминание поставлено на паузу.\n\n" "Можешь возобновить его в любое время через «📋 Мои напоминания»." ) await callback.answer("Поставлено на паузу") logger.info(f"Reminder {reminder.id} paused by user {callback.from_user.id}") @router.callback_query(ReminderActionCallback.filter(F.action == "resume")) async def handle_resume( callback: CallbackQuery, callback_data: ReminderActionCallback, session: AsyncSession, ) -> None: """ Handle 'Resume' button - reactivate reminder. Args: callback: Callback query callback_data: Parsed callback data session: Database session """ reminder = await reminders_service.resume_reminder(session, callback_data.reminder_id) if not reminder: await callback.answer("Напоминание не найдено", show_alert=True) return next_run_str = time_service.format_next_run(reminder.next_run_at) await callback.message.edit_text( f"▶️ Напоминание возобновлено!\n\n" f"Следующее напоминание будет {next_run_str}." ) await callback.answer("Возобновлено!") logger.info(f"Reminder {reminder.id} resumed by user {callback.from_user.id}") # ==================== Delete Action ==================== @router.callback_query(ReminderActionCallback.filter(F.action == "delete")) async def handle_delete_confirm( callback: CallbackQuery, callback_data: ReminderActionCallback, ) -> None: """ Handle 'Delete' button - ask for confirmation. Args: callback: Callback query callback_data: Parsed callback data """ await callback.message.edit_text( "Точно удалить напоминание?", reply_markup=get_confirmation_keyboard( entity="delete", entity_id=callback_data.reminder_id ), ) await callback.answer() @router.callback_query(ConfirmCallback.filter(F.entity == "delete")) async def handle_delete_execute( callback: CallbackQuery, callback_data: ConfirmCallback, session: AsyncSession, ) -> None: """ Execute reminder deletion after confirmation. Args: callback: Callback query callback_data: Parsed callback data session: Database session """ if callback_data.action == "no": await callback.message.edit_text("Удаление отменено.") await callback.answer() return deleted = await reminders_service.delete_reminder_by_id( session, callback_data.entity_id ) if not deleted: await callback.answer("Напоминание не найдено", show_alert=True) return await callback.message.edit_text("🗑 Напоминание удалено.") await callback.answer("Удалено") logger.info( f"Reminder {callback_data.entity_id} deleted by user {callback.from_user.id}" ) # ==================== Settings Placeholder ==================== @router.message(F.text == "⚙️ Настройки") async def handle_settings(message: Message) -> None: """ Handle settings button (placeholder). Args: message: Telegram message """ await message.answer( "⚙️ Настройки\n\n" "Функционал настроек будет добавлен в следующих версиях.\n\n" "Пока доступны основные функции:\n" "• Создание напоминаний\n" "• Просмотр и управление\n" "• Редактирование параметров", reply_markup=get_main_menu_keyboard(), )