смотри, у меня такой вопрос по моему коду

"Получен номер: 79919990387
Страна: Россия
Сервис: Яндекс
Ожидание SMS...
Вы можете управлять активацией или вернуться в главное меню."

можно ли в данном сообщении выводить максимальную стоимость, которую ввел пользовталеь ранее и так же можно сюда выводить оператора, для которого была заказана смс



import asyncio
import logging
import time
import json
from pathlib import Path
from typing import Optional, List, Tuple
from aiogram import Dispatcher, types, F
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup

# Импорт дополнительных модулей
from ..data import get_user_api_key, get_user_operator, get_user_country
from ..api import SmsHubAPI
from ..utils import get_usd_to_rub_rate, safe_edit_or_send_message
from .main_menu import send_main_menu
from .activation import user_activations, poll_for_sms
from ..constants import OPERATOR_DISPLAY_NAMES, COUNTRIES, SERVICE_DISPLAY_NAMES

logger = logging.getLogger(__name__)

class SmsOrderState(StatesGroup):
    waiting_for_service = State()
    waiting_for_max_price = State()

SERVICES: List[Tuple[str, str]] = list(SERVICE_DISPLAY_NAMES.items())
POPULARITY_FILE = Path("service_popularity.json")

def load_popularity_data():
    if POPULARITY_FILE.exists():
        with open(POPULARITY_FILE, 'r', encoding='utf-8') as f:
            return json.load(f)
    return {}

def save_popularity_data(popularity_data):
    with open(POPULARITY_FILE, 'w', encoding='utf-8') as f:
        json.dump(popularity_data, f, ensure_ascii=False, indent=4)

def update_service_popularity(service_code: str):
    popularity_data = load_popularity_data()
    if service_code in popularity_data:
        popularity_data[service_code] += 1
    else:
        popularity_data[service_code] = 1
    save_popularity_data(popularity_data)

def get_sorted_services():
    popularity_data = load_popularity_data()
    sorted_services = sorted(SERVICES, key=lambda service: popularity_data.get(service[0], 0), reverse=True)
    return sorted_services

def get_service_pages(services: List[Tuple[str, str]], page_size: int = 18) -> List[List[Tuple[str, str]]]:
    pages = []
    for i in range(0, len(services), page_size):
        pages.append(services[i:i + page_size])
    return pages

def build_service_keyboard(page_number: int = 0) -> InlineKeyboardBuilder:
    sorted_services = get_sorted_services()
    services_pages = get_service_pages(sorted_services)
    keyboard = InlineKeyboardBuilder()

    if page_number < len(services_pages):
        current_page = services_pages[page_number]

        for code, name in current_page:
            keyboard.button(text=name, callback_data=f"service_select:{code}")

        if page_number > 0:
            keyboard.button(text="⬅️ Назад", callback_data=f"service_page:{page_number - 1}", width=3)

        if page_number < len(services_pages) - 1:
            keyboard.button(text="➡️ Вперед", callback_data=f"service_page:{page_number + 1}", width=3)

    keyboard.button(text="🔙 Назад в меню", callback_data="back_to_main_menu", width=3)
    keyboard.adjust(3)
    return keyboard

async def get_sms_handler(callback_query: types.CallbackQuery, state: FSMContext):
    try:
        await callback_query.answer()
    except Exception as e:
        logger.warning(f"Не удалось ответить на callback_query: {e}")

    user_api_key = get_user_api_key(callback_query.from_user.id)
    if not user_api_key:
        keyboard = InlineKeyboardBuilder()
        keyboard.button(text="⚙️ Настройки", callback_data="settings")
        keyboard.button(text="🔙 Назад", callback_data="back_to_main_menu")
        keyboard.adjust(1)
        await safe_edit_or_send_message(
            message=callback_query.message,
            new_text="Пожалуйста, сначала настройте ваш API ключ в разделе 'Настройки'.",
            state=state,
            reply_markup=keyboard.as_markup()
        )
        return

    logger.info(f"Пользователь {callback_query.from_user.id} начал процесс получения номера.")
    keyboard = build_service_keyboard()

    await state.update_data(cancel_request=False, current_task=None)

    await safe_edit_or_send_message(
        message=callback_query.message,
        new_text=(
            "Выберите сервис, нажав на кнопку ниже.\n"
            "Если вы хотите, вы также можете ввести полное название сервиса или хотя бы часть его названия, чтобы получить результаты поиска."
        ),
        state=state,
        reply_markup=keyboard.as_markup()
    )
    await state.set_state(SmsOrderState.waiting_for_service)

async def go_back_to_service_selection(callback_query: types.CallbackQuery, state: FSMContext):
    try:
        await callback_query.answer()
    except Exception as e:
        logger.warning(f"Не удалось ответить на callback_query: {e}")
    logger.info(f"Пользователь {callback_query.from_user.id} отменил операцию.")
    
    await state.update_data(cancel_request=True)

    data = await state.get_data()
    current_task = data.get('current_task')
    if current_task:
        current_task.cancel()

    keyboard = build_service_keyboard()
    await safe_edit_or_send_message(
        message=callback_query.message,
        new_text=(
            "Выберите сервис, нажав на кнопку ниже.\n"
            "Если вы хотите, вы также можете ввести полное название сервиса или хотя бы часть его названия, чтобы получить результаты поиска."
        ),
        state=state,
        reply_markup=keyboard.as_markup()
    )

    await state.update_data(cancel_request=False)

    await state.set_state(SmsOrderState.waiting_for_service)

async def back_to_main_menu(callback_query: types.CallbackQuery, state: FSMContext):
    try:
        await callback_query.answer()
    except Exception as e:
        logger.warning(f"Не удалось ответить на callback_query: {e}")
    logger.info(f"Пользователь {callback_query.from_user.id} вернулся в главное меню.")

    await send_main_menu(callback_query.message, state)

async def service_page_handler(callback_query: types.CallbackQuery, state: FSMContext):
    try:
        await callback_query.answer()
    except Exception as e:
        logger.warning(f"Не удалось ответить на callback_query: {e}")

    page_number = int(callback_query.data.split(":")[1])
    keyboard = build_service_keyboard(page_number)

    await safe_edit_or_send_message(
        message=callback_query.message,
        new_text="Выберите сервис или введите код сервиса вручную:",
        state=state,
        reply_markup=keyboard.as_markup()
    )

async def service_selected_handler(callback_query: types.CallbackQuery, state: FSMContext):
    try:
        await callback_query.answer()
    except Exception as e:
        logger.warning(f"Не удалось ответить на callback_query: {e}")

    service_code = callback_query.data.split(":")[1]
    update_service_popularity(service_code)

    await state.update_data(selected_service=service_code, cancel_request=False)
    task = asyncio.create_task(service_handler_logic(callback_query.message, state, user_id=callback_query.from_user.id, service_code=service_code, is_service_selection=True))
    await state.update_data(current_task=task)

async def service_handler(message: types.Message, state: FSMContext, service_code: Optional[str] = None, user_id: Optional[int] = None):
    user_input = message.text.strip().lower()

    if user_id is None:
        user_id = message.from_user.id

    logger.info(f"Пользователь {user_id} ввел сервис: {user_input}")

    service_code = next((code for code, name in SERVICE_DISPLAY_NAMES.items() if name.lower() == user_input or code.lower() == user_input), None)

    if service_code is None:
        matched_services = [(code, name) for code, name in SERVICE_DISPLAY_NAMES.items() if user_input in name.lower()]

        if matched_services:
            keyboard = InlineKeyboardBuilder()
            for code, name in matched_services:
                keyboard.button(text=name, callback_data=f"service_select:{code}")

            keyboard.adjust(3)
            keyboard.button(text="🔙 Назад", callback_data="service_page:0")
            await safe_edit_or_send_message(
                message=message,
                new_text="Пожалуйста, выберите один из представленных сервисов:",
                state=state,
                reply_markup=keyboard.as_markup()
            )
            return
        else:
            keyboard = InlineKeyboardBuilder()
            keyboard.button(text="🔙 Назад к сервисам", callback_data="service_page:0")
            await safe_edit_or_send_message(
                message=message,
                new_text="Сервис не найден. Попробуйте ввести код или полное название сервиса.", 
                state=state,
                reply_markup=keyboard.as_markup()
            )
            return
    else:
        await state.update_data(selected_service=service_code, cancel_request=False)
        task = asyncio.create_task(service_handler_logic(message, state, user_id=user_id, service_code=service_code))
        await state.update_data(current_task=task)

async def service_handler_logic(message: types.Message, state: FSMContext, user_id: int, service_code: str, is_service_selection: bool = False):
    logger.info(f"Пользователь {user_id} выбрал сервис: {service_code}")

    user_api_key = get_user_api_key(user_id)
    user_operator = get_user_operator(user_id) or "any"
    user_country_code = get_user_country(user_id) or "0"
    country_name = COUNTRIES.get(user_country_code, user_country_code)

    if not user_api_key:
        await safe_edit_or_send_message(
            message=message,
            new_text="Пожалуйста, сначала настройте ваш API ключ в разделе 'Настройки'.",
            state=state
        )
        await state.set_state(None)
        await send_main_menu(message, state)
        return

    smshub_api = SmsHubAPI(user_api_key)
    usd_to_rub_rate = await get_usd_to_rub_rate()

    max_attempts = 3
    success = False
    last_exception = None

    try:
        for attempt in range(1, max_attempts + 1):
            data = await state.get_data()
            if data.get("cancel_request"):
                logger.info(f"Запрос для пользователя {user_id} был отменен.")
                return

            try:
                progress_text = f"Идет запрос {attempt}/{max_attempts}..."
                keyboard = InlineKeyboardBuilder()
                keyboard.button(text="❌ Отмена", callback_data="cancel_operation")
                keyboard.adjust(1)
                
                await safe_edit_or_send_message(
                    message=message,
                    new_text=progress_text,
                    state=state,
                    reply_markup=keyboard.as_markup()
                )

                price_info = await smshub_api.get_price_for_service(service_code, country=user_country_code)
                numbers_status = await smshub_api.get_numbers_status(country=user_country_code, operator=user_operator)

                if price_info and numbers_status:
                    service_key = f"{service_code}_0"
                    available_numbers = int(numbers_status.get(service_key, 0) or 0)
                    if available_numbers == 0:
                        keyboard = InlineKeyboardBuilder()
                        keyboard.button(text="Назад", callback_data="service_page:0")
                        await safe_edit_or_send_message(
                            message=message,
                            new_text="Нет доступных номеров у выбранного оператора для данного сервиса. Пожалуйста, выберите другого оператора или попробуйте позже.",
                            state=state,
                            reply_markup=keyboard.as_markup()
                        )
                        return

                    prices = [float(price_str) for price_str in price_info.keys() if price_str is not None]
                    if not prices:
                        keyboard = InlineKeyboardBuilder()
                        keyboard.button(text="Назад", callback_data="service_page:0")
                        await safe_edit_or_send_message(
                            message=message,
                            new_text="Цены для выбранного сервиса недоступны. Пожалуйста, попробуйте другой сервис или повторите попытку позже.",
                            state=state,
                            reply_markup=keyboard.as_markup()
                        )
                        return

                    min_price_usd = min(prices)
                    max_price_usd = max(prices)
                    min_price_rub = min_price_usd * usd_to_rub_rate if usd_to_rub_rate else 0
                    max_price_rub = max_price_usd * usd_to_rub_rate if usd_to_rub_rate else 0

                    operator_display = OPERATOR_DISPLAY_NAMES.get(user_operator, user_operator)
                    service_display = SERVICE_DISPLAY_NAMES.get(service_code, service_code)

                    keyboard = InlineKeyboardBuilder()
                    keyboard.button(text="❌ Отмена", callback_data="cancel_operation")
                    keyboard.adjust(1)

                    message_text = (
                        f"*Страна:* `{country_name}`\n"
                        f"*Доступно номеров:* `{available_numbers}`\n"
                        f"*Оператор:* `{operator_display}`\n"
                        f"*Сервис:* `{service_display}`\n"
                        f"*Текущие цены для сервиса* `{service_display}`:\n"
                        f"от `{min_price_usd:.4f}` $ (₽{min_price_rub:.2f}) до `{max_price_usd:.4f}` $ (₽{max_price_rub:.2f}).\n\n"
                        f"_Введите максимальную стоимость в $ (например, 10):_"
                    )

                    await safe_edit_or_send_message(
                        message=message,
                        new_text=message_text,
                        state=state,
                        reply_markup=keyboard.as_markup(),
                        parse_mode="Markdown"
                    )

                    await state.update_data(
                        service=service_code,
                        service_display=service_display,
                        country_name=country_name,
                        available_numbers=available_numbers,
                        operator_display=operator_display,
                        min_price=min_price_usd,
                        max_price_usd=max_price_usd,
                        min_price_rub=min_price_rub,
                        max_price_rub=max_price_rub,
                        user_id=user_id
                    )

                    await state.set_state(SmsOrderState.waiting_for_max_price)
                    success = True
                    break

            except Exception as e:
                logger.error(f"Ошибка при получении данных для сервиса '{service_code}', попытка {attempt}: {e}")
                last_exception = e
            await asyncio.sleep(5)
    except asyncio.CancelledError:
        logger.info(f"Задача для пользователя {user_id} была отменена.")
        return

    if not success:
        keyboard = InlineKeyboardBuilder()
        keyboard.button(text="Назад", callback_data="service_page:0")
        await safe_edit_or_send_message(
            message=message,
            new_text="Не удалось получить информацию о ценах для выбранного сервиса. Пожалуйста, попробуйте другой сервис или повторите попытку позже.",
            state=state,
            reply_markup=keyboard.as_markup()
        )

async def max_price_handler(message: types.Message, state: FSMContext):
    max_price_input = message.text.strip()
    data = await state.get_data()
    user_id = data.get('user_id', message.from_user.id)

    # Удаляем сообщение от пользователя, содержащее максимальную стоимость
    try:
        await message.delete()
    except Exception as e:
        logger.error(f"Не удалось удалить сообщение пользователя: {e}")

    logger.info(f"Пользователь {user_id} указал максимальную стоимость: {max_price_input}")

    try:
        max_price = float(max_price_input)
    except ValueError:
        user_data = await state.get_data()
        min_price = user_data.get('min_price')
        max_price_val = user_data.get('max_price_usd')
        min_price_rub = user_data.get('min_price_rub')
        max_price_rub = user_data.get('max_price_rub')

        keyboard = InlineKeyboardBuilder()
        keyboard.button(text="❌ Отмена", callback_data="cancel_operation")
        keyboard.adjust(1)
        await safe_edit_or_send_message(
            message=message,
            new_text=(
                f"Пожалуйста, введите корректное число для максимальной стоимости. "
                f"От `{min_price:.4f}` $ (₽{min_price_rub:.2f}) до `{max_price_val:.4f}` $ (₽{max_price_rub:.2f})."
            ),
            state=state,
            reply_markup=keyboard.as_markup(),
            parse_mode="Markdown"
        )
        return

    user_data = await state.get_data()
    service = user_data['service']
    service_display = user_data['service_display']
    min_price = user_data['min_price']
    country_name = user_data['country_name']
    operator_display = user_data['operator_display']
    user_api_key = get_user_api_key(user_id)
    smshub_api = SmsHubAPI(user_api_key)
    user_country_code = get_user_country(user_id) or "0"
    
    if max_price < min_price:
        keyboard = InlineKeyboardBuilder()
        keyboard.button(text="❌ Отмена", callback_data="cancel_operation")
        keyboard.adjust(1)
        await safe_edit_or_send_message(
            message=message,
            new_text=f"Максимальная стоимость должна быть не менее `{min_price:.4f}` $.",
            state=state,
            reply_markup=keyboard.as_markup(),
            parse_mode="Markdown"
        )
        return

    max_attempts = 3
    success = False
    last_exception = None

    try:
        for attempt in range(1, max_attempts + 1):
            data = await state.get_data()
            if data.get("cancel_request"):
                logger.info(f"Запрос на получение номера для пользователя {user_id} был отменен.")
                return

            try:
                progress_text = f"Идет запрос {attempt}/{max_attempts} на получение номера..."
                keyboard = InlineKeyboardBuilder()
                keyboard.button(text="❌ Отмена", callback_data="cancel_operation")
                keyboard.adjust(1)

                await safe_edit_or_send_message(
                    message=message,
                    new_text=progress_text,
                    state=state,
                    reply_markup=keyboard.as_markup()
                )

                user_operator = get_user_operator(user_id) or "any"
                result = await smshub_api.get_number(service, country=user_country_code, max_price=max_price, operator=user_operator)

                if result and result.startswith("ACCESS_NUMBER"):
                    _, activation_id, number = result.split(":")
                    logger.info(f"Пользователь {user_id} получил номер: {number}, активация ID: {activation_id}")

                    if user_id not in user_activations:
                        user_activations[user_id] = {}
                    user_activations[user_id][activation_id] = {
                        'number': number,
                        'service': service,
                        'service_display': service_display,
                        'country_name': country_name,
                        'status': 'Ожидание SMS',
                        'task': None,
                        'last_update': time.time()
                    }

                    keyboard = InlineKeyboardBuilder()
                    keyboard.button(text="📂 Текущие активации", callback_data="current_activations")
                    keyboard.button(text="❌ Отменить активацию", callback_data=f"cancel_activation:{activation_id}")
                    keyboard.button(text="🔙 Главное меню", callback_data="back_to_main_menu")
                    keyboard.adjust(1)

                    message_text = (
                        f"*Получен номер:* `{number}`\n"
                        f"*Страна:* `{country_name}`\n"
                        f"*Сервис:* `{service_display}`\n"
                        f"Ожидание SMS...\n"
                        f"Вы можете управлять активацией или вернуться в главное меню."
                    )

                    await safe_edit_or_send_message(
                        message=message,
                        new_text=message_text,
                        state=state,
                        reply_markup=keyboard.as_markup(),
                        parse_mode="Markdown"
                    )

                    await state.set_state(None)

                    task = asyncio.create_task(poll_for_sms(
                        bot=message.bot,
                        user_id=user_id,
                        chat_id=message.chat.id,
                        activation_id=activation_id,
                        smshub_api=smshub_api
                    ))
                    user_activations[user_id][activation_id]['task'] = task
                    success = True
                    break
                else:
                    logger.error(f"Не удалось получить номер. Ответ: {result}")
                    last_exception = result
                    if result == "NO_NUMBERS":
                        if user_operator != "any":
                            suggestion = "Попробуйте выбрать 'Любой оператор' в настройках или увеличить максимальную цену."
                        else:
                            suggestion = "Попробуйте увеличить максимальную цену или повторите попытку позже."

                        await safe_edit_or_send_message(
                            message=message,
                            new_text=f"Нет доступных номеров для оператора {operator_display} по данной цене.\n{suggestion}",
                            state=state
                        )
                    else:
                        await safe_edit_or_send_message(
                            message=message,
                            new_text="Не удалось получить номер. Попробуйте снова.",
                            state=state
                        )
                    await send_main_menu(message, state)
                    break
            except Exception as e:
                logger.error(f"Ошибка при попытке получения номера, попытка {attempt}: {e}")
                last_exception = e
            await asyncio.sleep(5)
    except asyncio.CancelledError:
        logger.info(f"Задача для пользователя {user_id} была отменена.")
        return

    if not success:
        await safe_edit_or_send_message(
            message=message,
            new_text=f"Произошла ошибка при обработке запроса: {last_exception}. Попробуйте снова.",
            state=state
        )

def register_sms_handlers(dp: Dispatcher):
    dp.callback_query.register(get_sms_handler, F.data == "get_sms")
    dp.callback_query.register(go_back_to_service_selection, F.data == "cancel_operation")
    dp.callback_query.register(back_to_main_menu, F.data == "back_to_main_menu")
    dp.callback_query.register(service_page_handler, F.data.startswith("service_page:"))
    dp.callback_query.register(service_selected_handler, F.data.startswith("service_select:"))
    dp.message.register(service_handler, SmsOrderState.waiting_for_service)
    dp.message.register(max_price_handler, SmsOrderState.waiting_for_max_price)