use crate::ui::prelude::*;
use crate::util::markdown_restorer::{restore_html_from_entities, html_to_markdown_v2};
use indoc::indoc;

fn get_audience_text(users_without_purchases: bool) -> String {
    if users_without_purchases {
        "пользователям без покупок".to_string()
    } else {
        "всем пользователям".to_string()
    }
}

pub async fn show_broadcast_menu(
    bot: Bot,
    dialogue: MasterDialogue,
    msg: Message,
) -> HandlerResult {
    let message = indoc! {r#"
        📢 <b>Рассылка сообщений</b>
        
        Выберите тип аудитории для рассылки:
    "#};

    let keyboard = make_inline_keyboard(
        vec![
            ("👥 Всем пользователям", AdminCallback::BroadcastToAll).into(),
            ("🆕 Только пользователям без покупок", AdminCallback::BroadcastToWithoutPurchases).into(),
            ("🔙 Назад в меню", AdminCallback::AdminMenu).into(),
        ],
        1,
    );

    let result = bot.edit_message_text(msg.chat.id, msg.id, message)
        .parse_mode(teloxide::types::ParseMode::Html)
        .reply_markup(keyboard.clone())
        .await;

    match result {
        Ok(_) => {
            dialogue.update_admin_kind(AdminStateKind::Menu).await?;
        }
        Err(_) => {
            bot.send_message(msg.chat.id, message)
                .parse_mode(teloxide::types::ParseMode::Html)
                .reply_markup(keyboard)
                .await?;
            dialogue.update_admin_kind(AdminStateKind::Menu).await?;
        }
    }

    Ok(())
}

pub async fn start_broadcast_with_audience(
    bot: Bot,
    dialogue: MasterDialogue,
    msg: Message,
    users_without_purchases: bool,
) -> HandlerResult {
    let audience_text = get_audience_text(users_without_purchases);

    let message = format!(
        indoc! {r#"
            📢 <b>Рассылка {}</b>
            
            📝 Введите текст сообщения для рассылки:
            
            <i>Поддерживается Markdown разметка</i>
        "#},
        audience_text
    );

    let keyboard = make_inline_keyboard(
        vec![
            ("🔙 Назад", AdminCallback::BroadcastMenu).into(),
        ],
        1,
    );

    let result = bot.edit_message_text(msg.chat.id, msg.id, message.clone())
        .parse_mode(teloxide::types::ParseMode::Html)
        .reply_markup(keyboard.clone())
        .await;

    match result {
        Ok(_) => {
            dialogue.update_admin_kind(AdminStateKind::Broadcast { users_without_purchases }).await?;
        }
        Err(_) => {
            bot.send_message(msg.chat.id, message)
                .parse_mode(teloxide::types::ParseMode::Html)
                .reply_markup(keyboard)
                .await?;
            dialogue.update_admin_kind(AdminStateKind::Broadcast { users_without_purchases }).await?;
        }
    }

    Ok(())
}

pub async fn handle_broadcast_text_input(
    bot: Bot,
    dialogue: MasterDialogue,
    msg: Message,
    users_without_purchases: bool,
) -> HandlerResult {
    let Some(text) = msg.text() else {
        bot.send_message(msg.chat.id, "❌ Пожалуйста, отправьте текстовое сообщение")
            .await?;
        return Ok(());
    };

    let broadcast_text = restore_html_from_entities(&msg)
        .unwrap_or_else(|| text.trim().to_string());

    log::info!("Final broadcast text: {:?}", broadcast_text);

    if broadcast_text.is_empty() {
        bot.send_message(msg.chat.id, "❌ Сообщение не может быть пустым")
            .await?;
        return Ok(());
    }

    let _ = bot.delete_message(msg.chat.id, msg.id).await;

    let audience_text = get_audience_text(users_without_purchases);

    let confirmation_message = format!(
        indoc! {r#"
            📢 <b>Подтверждение рассылки</b>
            
            <b>Аудитория:</b> {}
            
            <b>Текст сообщения:</b>
            {}
            
            ⚠️ <b>Вы уверены, что хотите отправить это сообщение?</b>
        "#},
        audience_text,
        broadcast_text
    );

    let keyboard = InlineKeyboardMarkup::default()
        .append_row(vec![
            InlineKeyboardButton::callback(
                "✅ Отправить",
                AdminCallback::BroadcastConfirm { users_without_purchases }.to_string()
            ),
            InlineKeyboardButton::callback(
                "🧪 Тест",
                AdminCallback::BroadcastTest { users_without_purchases }.to_string()
            ),
        ])
        .append_row(vec![
            InlineKeyboardButton::callback(
                "🔙 Отмена",
                AdminCallback::BroadcastMenu.to_string()
            ),
        ]);

    bot.send_message(msg.chat.id, confirmation_message)
        .parse_mode(teloxide::types::ParseMode::Html)
        .reply_markup(keyboard)
        .await?;

    dialogue.update_admin_kind(AdminStateKind::BroadcastConfirm {
        users_without_purchases,
        broadcast_text: broadcast_text.to_string(),
    }).await?;

    Ok(())
}

pub async fn handle_broadcast_confirm_callback(
    bot: Bot,
    dialogue: MasterDialogue,
    msg: Message,
    users_without_purchases: bool,
) -> HandlerResult {
    let broadcast_text = if let Some(state) = dialogue.get().await? {
        match &state.admin_kind {
            AdminStateKind::BroadcastConfirm { broadcast_text, .. } => {
                log::debug!("Retrieved broadcast text for confirmation: {:?}", broadcast_text);
                broadcast_text.clone()
            }
            _ => {
                log::error!("Expected BroadcastConfirm state, got: {:?}", state.admin_kind);
                "Тестовое сообщение".to_string() // Fallback
            }
        }
    } else {
        log::error!("No state found in dialogue");
        "Тестовое сообщение".to_string() // Fallback
    };

    bot.edit_message_text(
        msg.chat.id,
        msg.id,
        "📤 Отправка рассылки... Пожалуйста, подождите."
    )
    .await?;

    match api::broadcast_message(
        broadcast_text.to_string(),
        None, // No inline buttons for now
        users_without_purchases,
    ).await {
        Ok(_) => {
            let audience_text = get_audience_text(users_without_purchases);

            let success_message = format!(
                indoc! {r#"
                    ✅ <b>Рассылка отправлена!</b>
                    
                    📊 <b>Аудитория:</b> {}
                    📨 <b>Сообщение успешно отправлено</b>
                    
                    🎯 Рассылка будет доставлена в фоновом режиме
                "#},
                audience_text
            );

            bot.edit_message_text(msg.chat.id, msg.id, success_message)
                .parse_mode(teloxide::types::ParseMode::Html)
                .reply_markup(make_inline_keyboard(
                    vec![("🔙 Вернуться в меню", AdminCallback::AdminMenu).into()],
                    1,
                ))
                .await?;
        }
        Err(e) => {
            let error_message = format!(
                indoc! {r#"
                    ❌ <b>Ошибка при отправке рассылки</b>
                    
                    <code>{}</code>
                    
                    Пожалуйста, попробуйте еще раз
                "#},
                e
            );

            bot.edit_message_text(msg.chat.id, msg.id, error_message)
                .parse_mode(teloxide::types::ParseMode::Html)
                .reply_markup(make_inline_keyboard(
                    vec![
                        ("🔄 Попробовать снова", AdminCallback::BroadcastMenu).into(),
                        ("🔙 Вернуться в меню", AdminCallback::AdminMenu).into(),
                    ],
                    1,
                ))
                .await?;
        }
    }


    dialogue.update_admin_kind(AdminStateKind::Menu).await?;
    Ok(())
}

pub async fn handle_broadcast_test_callback(
    bot: Bot,
    dialogue: MasterDialogue,
    msg: Message,
    users_without_purchases: bool,
) -> HandlerResult {
    let broadcast_text = if let Some(state) = dialogue.get().await? {
        match &state.admin_kind {
            AdminStateKind::BroadcastConfirm { broadcast_text, .. } => {
                log::debug!("Retrieved broadcast text from state: {:?}", broadcast_text);
                broadcast_text.clone()
            }
            _ => {
                log::error!("Expected BroadcastConfirm state, got: {:?}", state.admin_kind);
                "Тестовое сообщение".to_string() // Fallback
            }
        }
    } else {
        log::error!("No state found in dialogue");
        "Тестовое сообщение".to_string() // Fallback
    };

    bot.edit_message_text(
        msg.chat.id,
        msg.id,
        "🧪 Отправка тестового сообщения... Пожалуйста, подождите."
    )
    .await?;

    let current_user_id = msg.chat.id.0.to_string();

    log::info!("Broadcast text: {}", broadcast_text);

    match api::send_test_message(
        vec![current_user_id.clone()],
        broadcast_text.to_string(),
        None, // No inline buttons for now
    ).await {
        Ok(_) => {
            let audience_text = get_audience_text(users_without_purchases);

            let success_message = format!(
                indoc! {r#"
                    🧪 <b>Тестовое сообщение отправлено!</b>
                    
                    ✅ <b>Сообщение успешно отправлено вам для проверки</b>
                    📱 <b>Получатель:</b> <code>{}</code>
                    
                    <b>Аудитория для полной рассылки:</b> {}
                    
                    <b>Текст сообщения:</b>
                    {}
                    
                    💡 Если сообщение выглядит правильно, можете отправить его всем пользователям
                "#},
                current_user_id, audience_text, broadcast_text
            );

            bot.edit_message_text(msg.chat.id, msg.id, success_message)
                .parse_mode(teloxide::types::ParseMode::Html)
                .reply_markup(InlineKeyboardMarkup::default()
                    .append_row(vec![
                        InlineKeyboardButton::callback(
                            "✅ Отправить всем",
                            AdminCallback::BroadcastConfirm { users_without_purchases }.to_string()
                        ),
                        InlineKeyboardButton::callback(
                            "🧪 Еще раз тест",
                            AdminCallback::BroadcastTest { users_without_purchases }.to_string()
                        ),
                    ])
                    .append_row(vec![
                        InlineKeyboardButton::callback(
                            "🔙 Назад",
                            AdminCallback::BroadcastMenu.to_string()
                        ),
                    ]))
                .await?;
        }
        Err(e) => {
            let error_message = format!(
                indoc! {r#"
                    ❌ <b>Ошибка при отправке тестового сообщения</b>
                    
                    <code>{}</code>
                    
                    Пожалуйста, попробуйте еще раз
                "#},
                e
            );

            bot.edit_message_text(msg.chat.id, msg.id, error_message)
                .parse_mode(teloxide::types::ParseMode::Html)
                .reply_markup(InlineKeyboardMarkup::default()
                    .append_row(vec![
                        InlineKeyboardButton::callback(
                            "🔄 Попробовать снова",
                            AdminCallback::BroadcastTest { users_without_purchases }.to_string()
                        ),
                        InlineKeyboardButton::callback(
                            "🔙 Назад",
                            AdminCallback::BroadcastMenu.to_string()
                        ),
                    ]))
                .await?;
        }
    }

    Ok(())
} 


pub async fn broadcast_confirm_state_handler(
    bot: Bot,
    _dialogue: MasterDialogue,
    msg: Message,
    (_users_without_purchases, _broadcast_text): (bool, String),
) -> HandlerResult {
    bot.send_message(msg.chat.id, "Используйте кнопки для подтверждения или отмены рассылки")
        .await?;
    Ok(())
}