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

use crate::config::APP_ID;
use crate::core::database::Database;
use crate::core::duplicates;
use crate::core::fuse;
use crate::core::wayland;
use crate::i18n::{i18n, ni18n};
use super::widgets;

/// Build the dashboard page showing system health and statistics.
pub fn build_dashboard_page(db: &Rc<Database>) -> adw::NavigationPage {
    let clamp = adw::Clamp::builder()
        .maximum_size(800)
        .tightening_threshold(600)
        .build();

    let content = gtk::Box::builder()
        .orientation(gtk::Orientation::Vertical)
        .spacing(24)
        .margin_top(24)
        .margin_bottom(24)
        .margin_start(18)
        .margin_end(18)
        .build();

    // FUSE warning banner if not functional
    let fuse_info = fuse::detect_system_fuse();
    if !fuse_info.status.is_functional() {
        let banner = adw::Banner::builder()
            .title(&i18n("FUSE is not working - some AppImages may not launch"))
            .button_label(&i18n("Fix Now"))
            .revealed(true)
            .accessible_role(gtk::AccessibleRole::Alert)
            .build();
        banner.set_action_name(Some("win.fix-fuse"));
        content.append(&banner);
    }

    // Getting Started checklist (shown for new users)
    let records = db.get_all_appimages().unwrap_or_default();
    let total_count = records.len();
    let integrated_count = records.iter().filter(|r| r.integrated).count();
    if total_count < 3 {
        let started_group = adw::PreferencesGroup::builder()
            .title("Getting Started")
            .description("New to Driftwood? Here are three steps to get you up and running.")
            .build();

        let scan_row = adw::ActionRow::builder()
            .title("Scan your system for apps")
            .subtitle("Look for AppImage files in your configured folders")
            .activatable(true)
            .build();
        scan_row.set_action_name(Some("win.scan"));
        if total_count > 0 {
            let check = widgets::status_badge_with_icon("emblem-ok-symbolic", "Done", "success");
            check.set_valign(gtk::Align::Center);
            scan_row.add_suffix(&check);
        }
        started_group.add(&scan_row);

        let catalog_row = adw::ActionRow::builder()
            .title("Browse the app catalog")
            .subtitle("Discover and install apps from the AppImage ecosystem")
            .activatable(true)
            .build();
        catalog_row.set_action_name(Some("win.catalog"));
        catalog_row.add_suffix(&widgets::accessible_suffix_icon("go-next-symbolic", &i18n("Open catalog")));
        started_group.add(&catalog_row);

        let menu_row = adw::ActionRow::builder()
            .title("Add an app to your launcher")
            .subtitle("Make an app findable in your application menu")
            .build();
        if integrated_count > 0 {
            let check = widgets::status_badge_with_icon("emblem-ok-symbolic", "Done", "success");
            check.set_valign(gtk::Align::Center);
            menu_row.add_suffix(&check);
        }
        started_group.add(&menu_row);

        content.append(&started_group);
    }

    // Section 1: System Status
    content.append(&build_system_status_group());

    // Section 2: Library Statistics
    content.append(&build_library_stats_group(db));

    // Section 3: Updates Summary (actionable)
    content.append(&build_updates_summary_group(db));

    // Section 4: Duplicates Summary (actionable)
    content.append(&build_duplicates_summary_group(db));

    // Section 5: Disk Usage (actionable)
    content.append(&build_disk_usage_group(db));

    // Section 6: Activity
    content.append(&build_activity_group(db));

    // Section 7: Quick Actions
    content.append(&build_quick_actions_group());

    clamp.set_child(Some(&content));
    let scrolled = gtk::ScrolledWindow::builder()
        .child(&clamp)
        .vexpand(true)
        .build();

    let header = adw::HeaderBar::new();
    let toolbar = adw::ToolbarView::new();
    toolbar.add_top_bar(&header);
    toolbar.set_content(Some(&scrolled));
    widgets::apply_pointer_cursors(&toolbar);

    adw::NavigationPage::builder()
        .title("Dashboard")
        .tag("dashboard")
        .child(&toolbar)
        .build()
}

fn build_system_status_group() -> adw::PreferencesGroup {
    let group = adw::PreferencesGroup::builder()
        .title("System Status")
        .description("Display server, FUSE, and compatibility information")
        .build();

    // Session type
    let session = wayland::detect_session_type();
    let session_row = adw::ActionRow::builder()
        .title("Display server")
        .subtitle(session.label())
        .tooltip_text("How your system draws windows on screen")
        .build();
    let session_badge = widgets::status_badge(
        session.label(),
        match session {
            wayland::SessionType::Wayland => "success",
            wayland::SessionType::X11 => "warning",
            wayland::SessionType::Unknown => "neutral",
        },
    );
    session_badge.set_valign(gtk::Align::Center);
    session_row.add_suffix(&session_badge);
    group.add(&session_row);

    // Desktop environment
    let de = wayland::detect_desktop_environment();
    let de_row = adw::ActionRow::builder()
        .title("Desktop environment")
        .subtitle(&de)
        .tooltip_text("Your desktop interface")
        .build();
    group.add(&de_row);

    // FUSE status
    let fuse_info = fuse::detect_system_fuse();
    let fuse_row = adw::ActionRow::builder()
        .title("App compatibility")
        .subtitle(&fuse_description(&fuse_info))
        .tooltip_text("Most AppImages need a system component called FUSE to run. This shows whether it is set up correctly.")
        .build();
    let fuse_badge = widgets::status_badge(
        fuse_info.status.label(),
        fuse_info.status.badge_class(),
    );
    fuse_badge.set_valign(gtk::Align::Center);
    fuse_row.add_suffix(&fuse_badge);
    group.add(&fuse_row);

    // Install hint if FUSE not functional
    if let Some(ref hint) = fuse_info.install_hint {
        let hint_row = adw::ActionRow::builder()
            .title("Fix app compatibility")
            .subtitle(hint)
            .subtitle_selectable(true)
            .build();
        hint_row.add_css_class("monospace");
        group.add(&hint_row);
    }

    // XWayland
    let has_xwayland = wayland::has_xwayland();
    let xwayland_row = adw::ActionRow::builder()
        .title("XWayland")
        .subtitle(if has_xwayland { "Running" } else { "Not detected" })
        .tooltip_text("Compatibility layer that lets older apps run on modern displays")
        .build();
    let xwayland_badge = widgets::status_badge(
        if has_xwayland { "Available" } else { "Unavailable" },
        if has_xwayland { "success" } else { "neutral" },
    );
    xwayland_badge.set_valign(gtk::Align::Center);
    xwayland_row.add_suffix(&xwayland_badge);
    group.add(&xwayland_row);

    // AppImageLauncher conflict check
    if let Some(version) = fuse::detect_appimagelauncher() {
        let ail_row = adw::ActionRow::builder()
            .title("AppImageLauncher detected")
            .subtitle(&format!(
                "Version {} - may conflict with some AppImage runtimes",
                version
            ))
            .build();
        let ail_badge = widgets::status_badge("Conflict", "warning");
        ail_badge.set_valign(gtk::Align::Center);
        ail_row.add_suffix(&ail_badge);
        group.add(&ail_row);
    }

    group
}

fn fuse_description(info: &fuse::FuseSystemInfo) -> String {
    let mut parts = Vec::new();
    if info.has_libfuse2 {
        parts.push("libfuse2");
    }
    if info.has_libfuse3 {
        parts.push("libfuse3");
    }
    if info.has_fusermount {
        parts.push("fusermount");
    }
    if info.has_dev_fuse {
        parts.push("/dev/fuse");
    }
    if parts.is_empty() {
        "No FUSE components detected".to_string()
    } else {
        format!("Available: {}", parts.join(", "))
    }
}

fn build_library_stats_group(db: &Rc<Database>) -> adw::PreferencesGroup {
    let group = adw::PreferencesGroup::builder()
        .title("Library")
        .description("Overview of your AppImage collection")
        .build();

    let records = db.get_all_appimages().unwrap_or_default();

    let total = records.len();
    let integrated = records.iter().filter(|r| r.integrated).count();
    let executable = records.iter().filter(|r| r.is_executable).count();

    let total_row = adw::ActionRow::builder()
        .title(&ni18n("AppImage", "AppImages", total as u32))
        .subtitle(&total.to_string())
        .activatable(true)
        .build();
    total_row.add_suffix(&widgets::accessible_suffix_icon("go-next-symbolic", &i18n("View library")));
    total_row.set_action_name(Some("navigation.pop"));
    group.add(&total_row);

    let integrated_row = adw::ActionRow::builder()
        .title("Integrated")
        .subtitle(&format!("{} of {}", integrated, total))
        .build();
    group.add(&integrated_row);

    let exec_row = adw::ActionRow::builder()
        .title("Executable")
        .subtitle(&format!("{} of {}", executable, total))
        .build();
    if executable < total {
        let badge = widgets::status_badge(
            &format!("{} not executable", total - executable),
            "warning",
        );
        badge.set_valign(gtk::Align::Center);
        exec_row.add_suffix(&badge);
    }
    group.add(&exec_row);

    group
}

fn build_updates_summary_group(db: &Rc<Database>) -> adw::PreferencesGroup {
    let group = adw::PreferencesGroup::builder()
        .title("Updates")
        .description("AppImage update availability")
        .build();

    let records = db.get_all_appimages().unwrap_or_default();

    let with_update_info = records
        .iter()
        .filter(|r| r.update_info.is_some())
        .count();
    let with_updates = records
        .iter()
        .filter(|r| {
            if let (Some(ref latest), Some(ref current)) = (&r.latest_version, &r.app_version) {
                crate::core::updater::version_is_newer(latest, current)
            } else {
                false
            }
        })
        .count();

    let info_row = adw::ActionRow::builder()
        .title("With update info")
        .subtitle(&format!("{} of {}", with_update_info, records.len()))
        .build();
    group.add(&info_row);

    // Actionable updates row -> triggers check-updates
    let updates_row = adw::ActionRow::builder()
        .title("Updates available")
        .subtitle(&with_updates.to_string())
        .activatable(true)
        .build();
    updates_row.set_action_name(Some("win.check-updates"));
    if with_updates > 0 {
        let badge = widgets::status_badge(&format!("{} updates", with_updates), "info");
        badge.set_valign(gtk::Align::Center);
        updates_row.add_suffix(&badge);
    }
    updates_row.add_suffix(&widgets::accessible_suffix_icon("go-next-symbolic", &i18n("View updates")));
    group.add(&updates_row);

    if with_updates > 0 {
        let update_all_row = adw::ActionRow::builder()
            .title("Update All")
            .subtitle(&format!("Apply {} available updates", with_updates))
            .activatable(true)
            .build();
        update_all_row.set_action_name(Some("win.update-all"));
        let update_badge = widgets::status_badge("Go", "suggested");
        update_badge.set_valign(gtk::Align::Center);
        update_all_row.add_suffix(&update_badge);
        update_all_row.add_suffix(&widgets::accessible_suffix_icon("go-next-symbolic", &i18n("Update all apps")));
        group.add(&update_all_row);
    }

    // Last checked timestamp
    let settings = gio::Settings::new(APP_ID);
    let last_check = settings.string("last-update-check");
    let last_label = if last_check.is_empty() {
        "Never".to_string()
    } else {
        widgets::relative_time(&last_check)
    };
    let last_row = adw::ActionRow::builder()
        .title("Last checked")
        .subtitle(&last_label)
        .build();
    group.add(&last_row);

    group
}

fn build_duplicates_summary_group(db: &Rc<Database>) -> adw::PreferencesGroup {
    let group = adw::PreferencesGroup::builder()
        .title("Duplicates")
        .description("Duplicate and multi-version detection")
        .build();

    let groups = duplicates::detect_duplicates(db);
    let summary = duplicates::summarize_duplicates(&groups);

    if summary.total_groups == 0 {
        let row = adw::ActionRow::builder()
            .title("No duplicates found")
            .subtitle("All AppImages appear unique")
            .build();
        let badge = widgets::status_badge("Clean", "success");
        badge.set_valign(gtk::Align::Center);
        row.add_suffix(&badge);
        group.add(&row);
    } else {
        // Actionable row -> opens duplicate dialog
        let groups_row = adw::ActionRow::builder()
            .title("Duplicate groups")
            .subtitle(&summary.total_groups.to_string())
            .activatable(true)
            .build();
        groups_row.set_action_name(Some("win.find-duplicates"));
        groups_row.add_suffix(&widgets::accessible_suffix_icon("go-next-symbolic", &i18n("View duplicates")));
        group.add(&groups_row);

        if summary.total_potential_savings > 0 {
            let savings_row = adw::ActionRow::builder()
                .title("Potential savings")
                .subtitle(&widgets::format_size(summary.total_potential_savings as i64))
                .build();
            let badge = widgets::status_badge("Reclaimable", "warning");
            badge.set_valign(gtk::Align::Center);
            savings_row.add_suffix(&badge);
            group.add(&savings_row);
        }
    }

    group
}

fn build_disk_usage_group(db: &Rc<Database>) -> adw::PreferencesGroup {
    let group = adw::PreferencesGroup::builder()
        .title("Disk Usage")
        .description("Storage used by your AppImages")
        .build();

    let records = db.get_all_appimages().unwrap_or_default();
    let total_bytes: i64 = records.iter().map(|r| r.size_bytes).sum();

    // Actionable total row -> opens cleanup wizard
    let total_row = adw::ActionRow::builder()
        .title("Total disk usage")
        .subtitle(&widgets::format_size(total_bytes))
        .activatable(true)
        .build();
    total_row.set_action_name(Some("win.cleanup"));
    total_row.add_suffix(&widgets::accessible_suffix_icon("go-next-symbolic", &i18n("Clean up disk")));
    group.add(&total_row);

    // Largest AppImages
    let mut sorted = records.clone();
    sorted.sort_by(|a, b| b.size_bytes.cmp(&a.size_bytes));

    for record in sorted.iter().take(3) {
        let name = record.app_name.as_deref().unwrap_or(&record.filename);
        let row = adw::ActionRow::builder()
            .title(name)
            .subtitle(&widgets::format_size(record.size_bytes))
            .build();
        group.add(&row);
    }

    group
}

fn build_activity_group(db: &Rc<Database>) -> adw::PreferencesGroup {
    let group = adw::PreferencesGroup::builder()
        .title("Activity")
        .description("Launch history and usage statistics")
        .build();

    let total_launches = db.get_total_launch_count().unwrap_or(0);
    let total_row = adw::ActionRow::builder()
        .title("Total launches")
        .subtitle(&total_launches.to_string())
        .build();
    group.add(&total_row);

    if let Ok(Some((name, time))) = db.get_last_launch() {
        let last_row = adw::ActionRow::builder()
            .title("Last launched")
            .subtitle(&format!("{} - {}", name, time))
            .build();
        group.add(&last_row);
    }

    if let Ok(top) = db.get_top_launched(5) {
        for (name, count) in &top {
            let row = adw::ActionRow::builder()
                .title(name)
                .subtitle(&format!("{} launches", count))
                .build();
            group.add(&row);
        }
    }

    group
}

fn build_quick_actions_group() -> adw::PreferencesGroup {
    let group = adw::PreferencesGroup::builder()
        .title("Quick Actions")
        .build();

    let button_box = gtk::Box::builder()
        .orientation(gtk::Orientation::Horizontal)
        .spacing(12)
        .halign(gtk::Align::Center)
        .margin_top(6)
        .margin_bottom(6)
        .build();

    let scan_btn = gtk::Button::builder()
        .label("Scan")
        .tooltip_text("Scan for AppImages")
        .build();
    scan_btn.add_css_class("pill");
    scan_btn.add_css_class("suggested-action");
    scan_btn.set_action_name(Some("win.scan"));
    scan_btn.update_property(&[
        gtk::accessible::Property::Description("Scan for AppImages in configured directories"),
    ]);

    let updates_btn = gtk::Button::builder()
        .label("Check Updates")
        .tooltip_text("Check all AppImages for updates")
        .build();
    updates_btn.add_css_class("pill");
    updates_btn.set_action_name(Some("win.check-updates"));
    updates_btn.update_property(&[
        gtk::accessible::Property::Description("Check all AppImages for available updates"),
    ]);

    let clean_btn = gtk::Button::builder()
        .label("Clean Orphans")
        .tooltip_text("Remove orphaned desktop entries")
        .build();
    clean_btn.add_css_class("pill");
    clean_btn.set_action_name(Some("win.clean-orphans"));
    clean_btn.update_property(&[
        gtk::accessible::Property::Description("Remove orphaned desktop entries and icons"),
    ]);

    button_box.append(&scan_btn);
    button_box.append(&updates_btn);
    button_box.append(&clean_btn);

    // Use an ActionRow to contain the buttons for proper group styling
    let row = adw::ActionRow::new();
    row.set_child(Some(&button_box));
    group.add(&row);

    group
}
