use crate::ui::user::prelude::*;

pub async fn handle_pool_selection(
    bot: Bot,
    q: CallbackQuery,
    dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    pool: PoolType,
    settings: HandlerSettings,
) -> HandlerResult {
    let ln = settings.language;
    let message = get_callback_message(q.clone()).unwrap();

    bot.answer_callback_query(q.id).await?;

    crate::ui::user::update_state_preserving_cache(&dialogue, crate::ui::UserStateKind::Purchase).await?;

    let purchase_state = PurchaseState::with_message(pool, message.id);
    purchase_dialogue.update(purchase_state).await?;

    show_purchase_summary(bot, message.chat.id, message.id, pool, None, None, ln).await?;

    Ok(())
}

pub async fn handle_gb_amount_input(
    bot: Bot,
    msg: Message,
    _dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    settings: HandlerSettings,
) -> HandlerResult {
    let ln = settings.language;
    
    let Some(mut purchase_state) = purchase_dialogue.get().await? else {
        log::error!("Expected PurchaseState but got None");
        return Ok(());
    };

    bot.delete_message(msg.chat.id, msg.id).await?;

    let amount = match msg.text().map(|text| text.trim().parse::<u32>()) {
        Some(Ok(amount)) if amount > 0 && amount <= 999999 => amount,
        Some(Ok(_)) => {
            if let Some(msg_id) = purchase_state.bot_msg_id {
                bot.edit_message_text(msg.chat.id, msg_id, t8x!(Ru, "❌ Количество должно быть от 1 до 999999 GB\n\n💬 Введите количество GB числом", &ln))
                    .await?;
            }
            return Ok(());
        }
        Some(Err(_)) | None => {
            if let Some(msg_id) = purchase_state.bot_msg_id {
                bot.edit_message_text(msg.chat.id, msg_id, t8x!(Ru, "❌ Введите число\n\n💬 Введите количество GB числом", &ln))
                    .await?;
            }
            return Ok(());
        }
    };

    purchase_state.set_amount(amount);
    purchase_dialogue.update(purchase_state.clone()).await?;

    if let Some(msg_id) = purchase_state.bot_msg_id {
        show_purchase_summary(bot, msg.chat.id, msg_id, purchase_state.pool, Some(amount), purchase_state.promocode, ln).await?;
    }

    Ok(())
}

/// Show purchase summary with payment options
pub async fn show_purchase_summary(
    bot: Bot,
    chat_id: ChatId,
    msg_id: MessageId,
    pool: PoolType,
    amount: Option<u32>,
    promocode: Option<String>,
    ln: Language,
) -> HandlerResult {
    let payment_systems = match api::get_payment_systems(chat_id.0).await {
        Ok(systems) => systems,
        Err(e) => {
            log::error!("Failed to get payment systems: {}", e);
            bot.edit_message_text(chat_id, msg_id, t8x!(Ru, "Ошибка получения методов оплаты", &ln))
                .await?;
            return Ok(());
        }
    };

    let mut keyboard = InlineKeyboardMarkup::default();

    let promo_line = if let Some(ref promo) = promocode {
        strfmt!(t8x!(Ru, "\n✅ Промокод применен: {promo}\n", &ln), promo => promo.to_string())?
    } else if amount.is_some() {
        let promo_button = InlineKeyboardButton::callback(
            t8x!(Ru, "🏷️ Ввести скидочный купон🏷️", &ln),
            PurchaseCallback::EnterPromocode.to_string(),
        );
        keyboard = keyboard.append_row(vec![promo_button]);
        "".to_string()
    } else {
        "".to_string()
    };

    let pool_price_text = t8x!(Ru, "💸 <b>Стоимость за GB:</b> ${pool_price:.2}\n", &ln);
    let amount_text = t8x!(Ru, "📊 <b>Количество:</b> {amount}\n", &ln);

    let pool_name = pool.display_name(&ln);
    
    let discount_info = if let Some(amount) = amount {
        if amount >= 100 {
            t8x!(Ru, "\n💡 <i>При заказе от 100 GB действует объемная скидка, но промокоды недоступны</i>\n", &ln)
        } else {
            ""
        }
    } else {
        ""
    };
    
    let payment_methods_info = if !payment_systems.is_empty() && amount.is_some() {
        let methods_text = payment_systems.iter()
            .map(|ps| format!("💳 <b>{}</b>: {}", ps.name, ps.description))
            .collect::<Vec<String>>()
            .join("\n");
        format!("\n\n<b>Доступные способы оплаты:</b>\n{}\n", methods_text)
    } else {
        "".to_string()
    };

    let (amount_line, final_price_line, current_hint, pool_price_line) = if let Some(amount) = amount {
        let price = match api::calculate_detailed_price(chat_id.0, &pool, amount, promocode.as_deref()).await {
            Ok(price) => price,
            Err(api::PurchaseError::PromoCodeNotExists) => {
                log::warn!("Promocode became unavailable during price calculation, retrying without it");
                api::calculate_detailed_price(chat_id.0, &pool, amount, None).await?
            }
            Err(e) => {
                log::error!("Failed to calculate price: {}", e);
                bot.edit_message_text(chat_id, msg_id, t8x!(Ru, "Ошибка расчета стоимости", &ln))
                    .await?;
                return Ok(());
            }
        };

        let mut amount = amount.to_string();
        amount.push_str(" GB");
        let amount_line = strfmt!(amount_text, amount)?;
        
        log::debug!("Price object before strfmt: {:?}", price);
        log::debug!("Price.final_price: {:?}", price.final_price);
        
        let final_price_line = match strfmt!(t8x!(Ru, "💰 <b>Итоговая стоимость:</b> ${price:.2}\n", &ln), price => price.final_price) {
            Ok(line) => line,
            Err(e) => {
                log::error!("strfmt error: {}", e);
                log::error!("Price object: {:?}", price);
                format!("💰 <b>Итоговая стоимость:</b> ${:.2}\n", price.final_price)
            }
        };
        let current_hint = t8x!(Ru, "\n 💬 <b>Выберите способ оплаты или введите другое количество GB:</b>", &ln);
        let pool_price = strfmt!(pool_price_text, pool_price => price.pool_price)?;

        let mut payment_buttons: Vec<InlineKeyboardButton> = vec![];
        for (index, ps) in payment_systems.iter().enumerate() {
            payment_buttons.push(InlineKeyboardButton::callback(
                format!("💳 {}", ps.name),
                PurchaseCallback::SelectPaymentMethod { index: index as u8 }.to_string(),
            ));
        }

        payment_buttons.push(InlineKeyboardButton::callback(
            t8x!(Ru, "💰 Оплатить реферальными $", &ln),
            PurchaseCallback::PayWithReferral.to_string(),
        ));

        for chunk in payment_buttons.chunks(2) {
            keyboard = keyboard.append_row(chunk.to_vec());
        }

        (amount_line, final_price_line, current_hint, pool_price)
    } else {
        let amount_line = strfmt!(amount_text, amount => t8x!(Ru, "Не выбрано", &ln))?;
        let final_price_line = "".to_string();
        let current_hint = t8x!(Ru, "\n 💬 <b>Введите количество GB:</b>", &ln);
        let pool_price = api::get_pool_prices(chat_id.0).await?.get_price(&pool);
        let pool_price = strfmt!(pool_price_text, pool_price => pool_price)?;

        (amount_line, final_price_line, current_hint, pool_price)
    };

    let message = strfmt!(t8x!(Ru, r#"
            🛒 <b>Покупка трафика</b>
            
            🧊 <b>Тип прокси:</b> {pool_name}
            {pool_price_line} {amount_line} {final_price_line} {promo_line} {discount_info} {payment_methods_info} {current_hint}
        "#, &ln),
        pool_name,
        amount_line,
        promo_line,
        pool_price_line,
        final_price_line,
        discount_info,
        payment_methods_info,
        current_hint
    )?;

    let back_button = InlineKeyboardButton::callback(
        t8x!(Ru, "🔙Назад🔙", &ln),
        Callback::BuyTraffic { pool: None }.to_string(),
    );
    keyboard = keyboard.append_row(vec![back_button]);

    bot.edit_message_text(chat_id, msg_id, message)
        .reply_markup(keyboard)
        .await?;

    Ok(())
}

pub async fn handle_payment_system_selection(
    bot: Bot,
    q: CallbackQuery,
    dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    index: u8,
    settings: HandlerSettings,
) -> HandlerResult {
    let message = get_callback_message(q.clone()).unwrap();
    
    let Some(mut purchase_state) = purchase_dialogue.get().await? else {
        log::error!("Expected PurchaseState but got None");
        return Ok(());
    };

    bot.answer_callback_query(q.id.clone()).await?;

    let Some(_) = purchase_state.amount else {
        return Ok(());
    };

    let payment_systems = match api::get_payment_systems(message.chat.id.0).await {
        Ok(systems) => systems,
        Err(e) => {
            log::error!("Failed to get payment systems: {}", e);
            return Ok(());
        }
    };

    let Some(selected_payment_system) = payment_systems.get(index as usize) else {
        log::error!("Invalid payment system index: {}", index);
        return Ok(());
    };

    purchase_state.set_payment_method(selected_payment_system.name.clone());
    purchase_dialogue.update(purchase_state).await?;

    handle_purchase_confirmation(bot, q, dialogue, purchase_dialogue, settings).await
}

pub async fn handle_purchase_confirmation(
    bot: Bot,
    q: CallbackQuery,
    _dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    settings: HandlerSettings,
) -> HandlerResult {
    let ln = settings.language;
    let message = get_callback_message(q.clone()).unwrap();
    
    let Some(purchase_state) = purchase_dialogue.get().await? else {
        log::error!("Expected PurchaseState but got None");
        return Ok(());
    };

    bot.answer_callback_query(q.id).await?;

    let Some(amount) = purchase_state.amount else {
        return Ok(());
    };
    
    let Some(ref payment_method) = purchase_state.payment_method else {
        return Ok(());
    };

    let request = PurchaseRequest {
        payment_method: payment_method.clone(),
        amount,
        pool: purchase_state.pool,
        promocode: purchase_state.promocode.clone(),
    };

    let final_price = api::calculate_detailed_price(message.chat.id.0, &purchase_state.pool, amount, purchase_state.promocode.as_deref()).await?;

    bot.edit_message_text(
        message.chat.id,
        message.id,
        t8x!(Ru, "⏳ Создание платежа...", &ln),
    )
    .await?;

    match api::create_invoice_web(message.chat.id.0, request.clone()).await {
        Ok(invoice_result) => {
            if payment_method == "telegram_stars" {
                match serde_json::from_str::<serde_json::Value>(&invoice_result.url) {
                    Ok(invoice_data) => {
                        log::debug!("INVOICE_DATA: {invoice_data:#?}");

                        use crate::util::telegram_stars::send_telegram_stars_invoice;
                        send_telegram_stars_invoice(
                            bot.clone(),
                            message.chat.id,
                            invoice_data.clone(),
                            ln,
                        ).await?;
                        
                        let pool_name = purchase_state.pool.display_name(&ln);
                        let message_text = strfmt!(t8x!(Ru, r#"
                                ⭐ <b>Счет на оплату Telegram Stars отправлен!</b>
                                {amount} GB {pool_name} прокси за {stars_amount} ⭐
                                
                                💳 Проверьте сообщения выше для оплаты
                            "#, &ln),
                            pool_name => pool_name,
                            amount => amount,
                            stars_amount => invoice_data.get("stars_amount").and_then(|v| v.as_u64()).unwrap_or(0)
                        )?;

                        let buttons = vec![
                            InlineKeyboardButton::callback(
                                t8x!(Ru, "🔙 Назад", &ln),
                                PurchaseCallback::Back.to_string(),
                            ),
                        ];

                        let mut keyboard = InlineKeyboardMarkup::default();
                        for button in buttons {
                            keyboard = keyboard.append_row(vec![button]);
                        }

                        bot.edit_message_text(message.chat.id, message.id, message_text)
                            .reply_markup(keyboard)
                            .await?;
                    }
                    Err(e) => {
                        log::error!("Failed to parse Telegram Stars invoice data: {}", e);
                        bot.edit_message_text(message.chat.id, message.id, t8x!(Ru, "❌ Ошибка создания счета", &ln))
                            .await?;
                    }
                }
            } else {
                let pool_name = purchase_state.pool.display_name(&ln);
                log::debug!("🔍 final_price object in handle_purchase_confirmation: {:?}", final_price);
                let mut message_text = strfmt!(t8x!(Ru, r#"
                        💳 <b>Счет создан!</b>
                        {amount} GB {pool_name} прокси за ${price:.2}
                    "#, &ln),
                    pool_name => pool_name,
                    amount => amount,
                    price => final_price.final_price
                )?;

                if let Some(ref invoice_id) = invoice_result.id {
                    message_text.push_str(&format!("\nНомер счета: #<code>{}</code>", invoice_id));
                }

                let buttons = vec![
                    InlineKeyboardButton::url(
                        t8x!(Ru, "💳 Перейти к оплате", &ln),
                        reqwest::Url::parse(&invoice_result.url)?,
                    ),
                    InlineKeyboardButton::callback(
                        t8x!(Ru, "🔙 Назад", &ln),
                        PurchaseCallback::Back.to_string(),
                    ),
                ];

                let mut keyboard = InlineKeyboardMarkup::default();
                for button in buttons {
                    keyboard = keyboard.append_row(vec![button]);
                }

                bot.edit_message_text(message.chat.id, message.id, message_text)
                    .reply_markup(keyboard)
                    .await?;
            }
        }
        Err(api::PurchaseError::PromoCodeNotExists) => {
            log::warn!("Promocode became unavailable during invoice creation, retrying without promocode");
            
            let mut updated_state = purchase_state.clone();
            updated_state.set_promocode(None);
            purchase_dialogue.update(updated_state).await?;
            
            bot.edit_message_text(
                message.chat.id,
                message.id,
                t8x!(Ru, "❌ Промокод больше недоступен. Создаем платеж без скидки...", &ln),
            ).await?;
            
            tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
            
            let retry_request = PurchaseRequest {
                payment_method: request.payment_method,
                amount: request.amount,
                pool: request.pool,
                promocode: None,
            };
            
            match api::create_invoice_web(message.chat.id.0, retry_request).await {
                Ok(invoice_result) => {
                    let final_price = api::calculate_detailed_price(message.chat.id.0, &purchase_state.pool, amount, None).await?;

                    let pool_name = purchase_state.pool.display_name(&ln);
                    log::debug!("🔍 final_price object in retry section: {:?}", final_price);
                    let mut message_text = strfmt!(t8x!(Ru, r#"
                            💳 <b>Счет создан!</b>
                            {amount} GB {pool_name} прокси за ${price:.2}
                            
                            ⚠️ Промокод был недоступен и не применен
                        "#, &ln),
                        pool_name => pool_name,
                        amount => amount,
                        price => final_price.final_price
                    )?;

                    if let Some(ref invoice_id) = invoice_result.id {
                        message_text.push_str(&format!("\nНомер счета: #{}", invoice_id));
                    }

                    let buttons = vec![
                        InlineKeyboardButton::url(
                            t8x!(Ru, "💳 Перейти к оплате", &ln),
                            reqwest::Url::parse(&invoice_result.url)?,
                        ),
                        InlineKeyboardButton::callback(
                            t8x!(Ru, "🔙 Назад", &ln),
                            PurchaseCallback::Back.to_string(),
                        ),
                    ];

                    let mut keyboard = InlineKeyboardMarkup::default();
                    for button in buttons {
                        keyboard = keyboard.append_row(vec![button]);
                    }

                    bot.edit_message_text(message.chat.id, message.id, message_text)
                        .reply_markup(keyboard)
                        .await?;
                }
                Err(e) => {
                    log::error!("Failed to create invoice even without promocode: {}", e);
                    let error_message = match e {
                        api::PurchaseError::PaymentMethodNotAvailable => {
                            t8x!(Ru, "❌ Выбранный способ оплаты недоступен", &ln)
                        }
                        _ => t8x!(Ru, "❌ Ошибка создания платежа", &ln),
                    };

                    bot.edit_message_text(message.chat.id, message.id, error_message)
                        .reply_markup(make_inline_keyboard(
                            vec![(t8x!(Ru, "🔙 Назад", &ln), PurchaseCallback::Back).into()],
                            1,
                        ))
                        .await?;
                }
            }
        }
        Err(e) => {
            log::error!("Failed to create invoice: {}", e);
            let error_message = match e {
                api::PurchaseError::PaymentMethodNotAvailable => {
                    t8x!(Ru, "❌ Выбранный способ оплаты недоступен", &ln)
                }
                api::PurchaseError::PromoCodeNotExists => {
                    t8x!(Ru, "❌ Промокод недействителен или истек", &ln)
                }
                _ => t8x!(Ru, "❌ Ошибка создания платежа", &ln),
            };

            bot.edit_message_text(message.chat.id, message.id, error_message)
                .reply_markup(make_inline_keyboard(
                    vec![(t8x!(Ru, "🔙 Назад", &ln), PurchaseCallback::Back).into()],
                    1,
                ))
                .await?;
        }
    }

    Ok(())
}

/// Handle referral payment
pub async fn handle_referral_payment(
    bot: Bot,
    q: CallbackQuery,
    dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    settings: HandlerSettings,
) -> HandlerResult {
    let ln = settings.language;
    let message = get_callback_message(q.clone()).unwrap();
    
    let Some(purchase_state) = purchase_dialogue.get().await? else {
        log::error!("Expected PurchaseState but got None");
        return Ok(());
    };

    bot.answer_callback_query(q.id).await?;

    let Some(amount) = purchase_state.amount else {
        return Ok(());
    };

    bot.edit_message_text(
        message.chat.id,
        message.id,
        t8x!(Ru, "⏳ Обработка платежа...", &ln),
    )
    .await?;

    let request = ReferralPaymentRequest {
        amount,
        pool: purchase_state.pool,
        promocode: purchase_state.promocode.clone(),
    };

    match api::process_referral_payment(message.chat.id.0, request.clone()).await {
        Ok(()) => {
            // let pool_name = purchase_state.pool.display_name(&ln);
            // let success_message = strfmt!(t9d!(Ru, indoc!{r#"
            //         ✅ Платеж успешно выполнен!
            //         
            //         Тип прокси: {pool_name}
            //         Количество: {amount} GB
            //         
            //         Трафик добавлен на ваш баланс.
            //     "#}, &ln),
            //     pool_name => pool_name,
            //     amount => amount
            // )?;

            // bot.edit_message_text(message.chat.id, message.id, success_message)
            //     .reply_markup(make_inline_keyboard(
            //         vec![(t8x!(Ru, "👤 Профиль", &ln), PurchaseCallback::Back).into()],
            //         1,
            //     ))
            //     .await?;

            bot.delete_message(message.chat.id, message.id).await?;

            crate::ui::user::update_state_preserving_cache(&dialogue, UserStateKind::Profile).await?;
        }
        Err(e) => {
            log::error!("Failed to process referral payment: {}", e);
            let error_message = match e {
                api::PurchaseError::InsufficientReferralBalance => {
                    t8x!(Ru, "❌ Недостаточно средств на реферальном балансе", &ln)
                }
                api::PurchaseError::PromoCodeNotExists => {
                    t8x!(Ru, "❌ Промокод недействителен или истек", &ln)
                }
                _ => t8x!(Ru, "❌ Ошибка обработки платежа", &ln),
            };

            bot.edit_message_text(message.chat.id, message.id, error_message)
                .reply_markup(make_inline_keyboard(
                    vec![(t8x!(Ru, "🔙 Назад", &ln), PurchaseCallback::Back).into()],
                    1,
                ))
                .await?;
        }
    }

    Ok(())
}

pub async fn handle_promocode_entry(
    bot: Bot,
    q: CallbackQuery,
    _dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    settings: HandlerSettings,
) -> HandlerResult {
    let ln = settings.language;
    let message = get_callback_message(q.clone()).unwrap();
    
    let Some(mut purchase_state) = purchase_dialogue.get().await? else {
        log::error!("Expected PurchaseState but got None");
        return Ok(());
    };

    bot.answer_callback_query(q.id).await?;

    let message_text = t8x!(Ru, "Введите промокод:", &ln);
    bot.edit_message_text(message.chat.id, message.id, message_text)
        .reply_markup(make_inline_keyboard(
            vec![(t8x!(Ru, "🔙 Назад", &ln), PurchaseCallback::Back).into()],
            1,
        ))
        .await?;

    purchase_state.step = PurchaseStep::EnterPromocode;
    purchase_dialogue.update(purchase_state).await?;

    Ok(())
}

/// Handle promocode input
pub async fn handle_promocode_input(
    bot: Bot,
    msg: Message,
    _dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    settings: HandlerSettings,
) -> HandlerResult {
    let ln = settings.language;

    log::info!("handle_promocode_input");
    
    let Some(mut purchase_state) = purchase_dialogue.get().await? else {
        log::error!("Expected PurchaseState but got None");
        return Ok(());
    };

    log::info!("bot_msg_id: {:#?}", purchase_state.bot_msg_id);

    bot.delete_message(msg.chat.id, msg.id).await?;

    let Some(amount) = purchase_state.amount else {
        log::warn!("No amount");
        return Ok(());
    };

    let promocode = msg.text().map(|s| s.trim().to_string());

    if let Some(ref code) = promocode {
        if !code.is_empty() {
            match api::get_promocode_info(msg.chat.id.0, code, amount).await {
                Ok(promo_info) => {
                    let discount_percent = (promo_info.discount * 100.0) as u32;
                    purchase_state.set_promocode(Some(code.clone()));
                    purchase_dialogue.update(purchase_state.clone()).await?;

                    if let Some(msg_id) = purchase_state.bot_msg_id {
                        bot.edit_message_text(
                            msg.chat.id,
                            msg_id,
                            strfmt!(t8x!(Ru, "✅ Промокод применен! Скидка: {discount_percent}%", &ln), discount_percent => discount_percent)?,
                        )
                        .await?;

                        tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;

                        show_purchase_summary(bot, msg.chat.id, msg_id, purchase_state.pool, Some(amount), Some(code.clone()), ln).await?;
                    }
                    return Ok(());
                }
                Err(api::PurchaseError::PromoCodeNotExists) => {
                    if let Some(msg_id) = purchase_state.bot_msg_id {
                        bot.edit_message_text(
                            msg.chat.id,
                            msg_id,
                            t8x!(Ru, "❌ Промокод недействителен или истек", &ln),
                        )
                        .await?;

                        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
                    }
                    
                    purchase_state.set_promocode(None);
                    purchase_dialogue.update(purchase_state.clone()).await?;

                    if let Some(msg_id) = purchase_state.bot_msg_id {
                        show_purchase_summary(bot, msg.chat.id, msg_id, purchase_state.pool, Some(amount), None, ln).await?;
                    }
                    return Ok(());
                }
                Err(e) => {
                    log::error!("Failed to validate promocode: {}", e);
                    if let Some(msg_id) = purchase_state.bot_msg_id {
                        bot.edit_message_text(
                            msg.chat.id,
                            msg_id,
                            t8x!(Ru, "❌ Ошибка проверки промокода", &ln),
                        )
                        .await?;
                    }
                }
            }
        }
    }

    purchase_state.set_promocode(promocode);
    purchase_dialogue.update(purchase_state.clone()).await?;

    if let Some(msg_id) = purchase_state.bot_msg_id {
        show_purchase_summary(bot, msg.chat.id, msg_id, purchase_state.pool, purchase_state.amount, purchase_state.promocode, ln).await?;
    }

    Ok(())
}



pub async fn purchase_callback_handler(
    bot: Bot,
    q: CallbackQuery,
    dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    settings: HandlerSettings,
) -> HandlerResult {
    use PurchaseCallback::*;

    let Some(data) = q.data.clone() else {
        log::error!("Callback data is None");
        return Err("Callback data is None".into());
    };

    let callback: PurchaseCallback = serde_json::from_str(&data)?;

    match callback {
        SelectPool { pool } => {
            handle_pool_selection(bot, q, dialogue, purchase_dialogue, pool, settings).await
        }
        SelectPaymentMethod { index } => {
            handle_payment_system_selection(bot, q, dialogue, purchase_dialogue, index, settings).await
        }
        EnterPromocode => {
            handle_promocode_entry(bot, q, dialogue, purchase_dialogue, settings).await
        }
        PayWithReferral => {
            handle_referral_payment(bot, q, dialogue, purchase_dialogue, settings).await
        }
        Back => {
            handle_purchase_back(bot, q, dialogue, purchase_dialogue, settings).await
        }
    }
}

pub async fn handle_purchase_back(
    bot: Bot,
    q: CallbackQuery,
    _dialogue: MasterDialogue,
    purchase_dialogue: PurchaseDialogue,
    settings: HandlerSettings,
) -> HandlerResult {
    let ln = settings.language;
    let message = get_callback_message(q.clone()).unwrap();
    
    let Some(purchase_state) = purchase_dialogue.get().await? else {
        log::error!("Expected PurchaseState but got None");
        return Ok(());
    };

    bot.answer_callback_query(q.id).await?;

    show_purchase_summary(
        bot, 
        message.chat.id, 
        message.id, 
        purchase_state.pool, 
        purchase_state.amount, 
        purchase_state.promocode, 
        ln
    ).await?;

    Ok(())
}
