use adw::prelude::*;
use std::rc::Rc;

use crate::core::database::{AppImageRecord, Database};
use crate::core::fuse::FuseStatus;
use crate::core::integrator;
use crate::core::wayland::WaylandStatus;
use crate::i18n::{i18n, i18n_f};
use super::widgets;

/// Show a confirmation dialog before integrating an AppImage into the desktop.
/// Returns true if the user confirms, false if cancelled.
pub fn show_integration_dialog(
    parent: &impl IsA<gtk::Widget>,
    record: &AppImageRecord,
    db: &Rc<Database>,
    on_complete: impl Fn(bool) + 'static,
) {
    let name = record.app_name.as_deref().unwrap_or(&record.filename);

    let dialog = adw::AlertDialog::builder()
        .heading(&i18n_f("Integrate {name}?", &[("{name}", name)]))
        .body(&i18n("This will add the application to your desktop menu."))
        .close_response("cancel")
        .default_response("integrate")
        .build();

    dialog.add_response("cancel", &i18n("Cancel"));
    dialog.add_response("integrate", &i18n("Integrate"));
    dialog.set_response_appearance("integrate", adw::ResponseAppearance::Suggested);

    // Build extra content with details
    let content = gtk::Box::builder()
        .orientation(gtk::Orientation::Vertical)
        .spacing(12)
        .margin_top(6)
        .build();

    // App identity section
    let identity_box = gtk::ListBox::new();
    identity_box.add_css_class("boxed-list");
    identity_box.set_selection_mode(gtk::SelectionMode::None);
    identity_box.update_property(&[
        gtk::accessible::Property::Label(&i18n("Application details")),
    ]);

    // Name
    let name_row = adw::ActionRow::builder()
        .title(&i18n("Application"))
        .subtitle(name)
        .build();
    if let Some(ref icon_path) = record.icon_path {
        let path = std::path::Path::new(icon_path);
        if path.exists() {
            if let Ok(texture) = gtk::gdk::Texture::from_filename(path) {
                let image = gtk::Image::builder()
                    .pixel_size(32)
                    .build();
                image.set_paintable(Some(&texture));
                image.update_property(&[gtk::accessible::Property::Label(name)]);
                name_row.add_prefix(&image);
            }
        }
    }
    identity_box.append(&name_row);

    // Version
    if let Some(ref version) = record.app_version {
        let row = adw::ActionRow::builder()
            .title(&i18n("Version"))
            .subtitle(version)
            .build();
        identity_box.append(&row);
    }

    content.append(&identity_box);

    // What will happen section
    let actions_box = gtk::ListBox::new();
    actions_box.add_css_class("boxed-list");
    actions_box.set_selection_mode(gtk::SelectionMode::None);
    actions_box.update_property(&[
        gtk::accessible::Property::Label(&i18n("Integration actions")),
    ]);

    let desktop_row = adw::ActionRow::builder()
        .title(&i18n("Desktop entry"))
        .subtitle(&i18n("A .desktop file will be created in ~/.local/share/applications"))
        .build();
    let check1 = gtk::Image::from_icon_name("emblem-ok-symbolic");
    check1.set_valign(gtk::Align::Center);
    check1.set_accessible_role(gtk::AccessibleRole::Presentation);
    desktop_row.add_prefix(&check1);
    actions_box.append(&desktop_row);

    let icon_row = adw::ActionRow::builder()
        .title(&i18n("Icon"))
        .subtitle(&i18n("The app icon will be installed to ~/.local/share/icons"))
        .build();
    let check2 = gtk::Image::from_icon_name("emblem-ok-symbolic");
    check2.set_valign(gtk::Align::Center);
    check2.set_accessible_role(gtk::AccessibleRole::Presentation);
    icon_row.add_prefix(&check2);
    actions_box.append(&icon_row);

    content.append(&actions_box);

    // Runtime compatibility warnings - now with styled banner
    let wayland_status = record
        .wayland_status
        .as_deref()
        .map(WaylandStatus::from_str)
        .unwrap_or(WaylandStatus::Unknown);

    let fuse_status = record
        .fuse_status
        .as_deref()
        .map(FuseStatus::from_str)
        .unwrap_or(FuseStatus::MissingLibfuse2);

    let mut warnings: Vec<(String, String, String)> = Vec::new();

    if wayland_status == WaylandStatus::X11Only {
        warnings.push((
            i18n("X11 only"),
            i18n("This app does not support Wayland and will run through XWayland"),
            "X11".to_string(),
        ));
    } else if wayland_status == WaylandStatus::XWayland {
        warnings.push((
            i18n("XWayland"),
            i18n("This app runs through the XWayland compatibility layer"),
            "XWayland".to_string(),
        ));
    }

    if !fuse_status.is_functional() {
        let fuse_msg = match fuse_status {
            FuseStatus::Fuse3Only => i18n("Only FUSE3 is installed - libfuse2 may be needed"),
            FuseStatus::NoFusermount => i18n("fusermount not found - AppImage mount may fail"),
            FuseStatus::NoDevFuse => i18n("/dev/fuse not available - AppImage mount will fail"),
            FuseStatus::MissingLibfuse2 => i18n("libfuse2 not installed - fallback extraction will be used"),
            _ => i18n("FUSE issue detected"),
        };
        warnings.push(("FUSE".to_string(), fuse_msg, fuse_status.label().to_string()));
    }

    if !warnings.is_empty() {
        // Styled warning banner
        let warning_box = gtk::Box::builder()
            .orientation(gtk::Orientation::Vertical)
            .spacing(8)
            .build();
        warning_box.add_css_class("compat-warning-banner");

        let warning_header = gtk::Box::builder()
            .orientation(gtk::Orientation::Horizontal)
            .spacing(8)
            .build();
        let warning_icon = gtk::Image::from_icon_name("dialog-warning-symbolic");
        warning_icon.set_pixel_size(16);
        warning_icon.set_accessible_role(gtk::AccessibleRole::Presentation);
        warning_header.append(&warning_icon);
        let warning_title = gtk::Label::builder()
            .label(&i18n("Compatibility Notes"))
            .css_classes(["title-4"])
            .halign(gtk::Align::Start)
            .build();
        warning_header.append(&warning_title);
        warning_box.append(&warning_header);

        let compat_list = gtk::ListBox::new();
        compat_list.add_css_class("boxed-list");
        compat_list.set_selection_mode(gtk::SelectionMode::None);
        compat_list.update_property(&[
            gtk::accessible::Property::Label(&i18n("Compatibility warnings")),
        ]);

        for (title, subtitle, badge_text) in &warnings {
            let row = adw::ActionRow::builder()
                .title(title.as_str())
                .subtitle(subtitle.as_str())
                .build();
            let badge = widgets::status_badge(badge_text, "warning");
            badge.set_valign(gtk::Align::Center);
            row.add_suffix(&badge);
            compat_list.append(&row);
        }

        warning_box.append(&compat_list);
        content.append(&warning_box);
    }

    dialog.set_extra_child(Some(&content));

    let record_clone = record.clone();
    let db_ref = db.clone();
    let record_id = record.id;

    dialog.connect_response(None, move |_dialog, response| {
        if response == "integrate" {
            match integrator::integrate_tracked(&record_clone, &db_ref) {
                Ok(result) => {
                    if let Some(ref icon_path) = result.icon_install_path {
                        log::info!("Icon installed to: {}", icon_path.display());
                    }
                    db_ref
                        .set_integrated(
                            record_id,
                            true,
                            Some(&result.desktop_file_path.to_string_lossy()),
                        )
                        .ok();
                    on_complete(true);
                }
                Err(e) => {
                    log::error!("Integration failed: {}", e);
                    on_complete(false);
                }
            }
        } else {
            on_complete(false);
        }
    });

    dialog.present(Some(parent));
}
