use adw::prelude::*;
use crate::app::AppState;
use crate::utils::format_size;

pub fn build_output_page(state: &AppState) -> adw::NavigationPage {
    let scrolled = gtk::ScrolledWindow::builder()
        .hscrollbar_policy(gtk::PolicyType::Never)
        .vexpand(true)
        .build();

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

    // Operation summary - dynamically rebuilt when this step is shown
    let summary_group = adw::PreferencesGroup::builder()
        .title("Operation Summary")
        .description("Review your processing settings before starting")
        .build();

    let summary_box = gtk::ListBox::builder()
        .selection_mode(gtk::SelectionMode::None)
        .css_classes(["boxed-list"])
        .build();
    summary_box.set_widget_name("ops-summary-list");

    summary_group.add(&summary_box);
    content.append(&summary_group);

    // Output directory
    let output_group = adw::PreferencesGroup::builder()
        .title("Output Directory")
        .build();

    let default_output = state.output_dir.borrow()
        .as_ref()
        .map(|p| p.display().to_string())
        .unwrap_or_else(|| "processed/ (subfolder next to originals)".to_string());

    let output_row = adw::ActionRow::builder()
        .title("Output Location")
        .subtitle(&default_output)
        .activatable(true)
        .action_name("win.choose-output")
        .build();
    output_row.add_prefix(&gtk::Image::from_icon_name("folder-symbolic"));

    let choose_button = gtk::Button::builder()
        .icon_name("folder-open-symbolic")
        .tooltip_text("Choose output folder")
        .valign(gtk::Align::Center)
        .action_name("win.choose-output")
        .build();
    choose_button.add_css_class("flat");
    output_row.add_suffix(&choose_button);
    output_row.add_suffix(&gtk::Image::from_icon_name("go-next-symbolic"));

    let cfg = state.job_config.borrow();

    let structure_row = adw::SwitchRow::builder()
        .title("Preserve Directory Structure")
        .subtitle("Keep subfolder hierarchy in output")
        .active(cfg.preserve_dir_structure)
        .build();

    output_group.add(&output_row);
    output_group.add(&structure_row);
    content.append(&output_group);

    // Overwrite behavior
    let overwrite_group = adw::PreferencesGroup::builder()
        .title("If Files Already Exist")
        .build();

    let overwrite_row = adw::ComboRow::builder()
        .title("Overwrite Behavior")
        .subtitle("What to do when output file already exists")
        .use_subtitle(true)
        .build();
    let overwrite_model = gtk::StringList::new(&[
        "Ask before overwriting",
        "Auto-rename with suffix",
        "Always overwrite",
        "Skip existing files",
    ]);
    overwrite_row.set_model(Some(&overwrite_model));
    overwrite_row.set_list_factory(Some(&super::full_text_list_factory()));
    overwrite_row.set_selected(cfg.overwrite_behavior as u32);

    overwrite_group.add(&overwrite_row);
    content.append(&overwrite_group);

    // Image count - dynamically updated
    let stats_group = adw::PreferencesGroup::builder()
        .title("Batch Info")
        .build();

    let excluded = state.excluded_files.borrow();
    let files = state.loaded_files.borrow();
    let included_count = files.iter().filter(|p| !excluded.contains(*p)).count();
    let total_size: u64 = files.iter()
        .filter(|p| !excluded.contains(*p))
        .filter_map(|p| std::fs::metadata(p).ok())
        .map(|m| m.len())
        .sum();
    drop(files);
    drop(excluded);

    let count_row = adw::ActionRow::builder()
        .title("Images to process")
        .subtitle(format!("{} images ({})", included_count, format_size(total_size)))
        .build();
    count_row.add_prefix(&gtk::Image::from_icon_name("image-x-generic-symbolic"));

    stats_group.add(&count_row);
    content.append(&stats_group);

    drop(cfg);

    // Wire preserve directory structure
    {
        let jc = state.job_config.clone();
        structure_row.connect_active_notify(move |row| {
            jc.borrow_mut().preserve_dir_structure = row.is_active();
        });
    }

    // Wire overwrite behavior
    {
        let jc = state.job_config.clone();
        overwrite_row.connect_selected_notify(move |row| {
            jc.borrow_mut().overwrite_behavior = row.selected() as u8;
        });
    }

    scrolled.set_child(Some(&content));

    let page = adw::NavigationPage::builder()
        .title("Output & Process")
        .tag("step-output")
        .child(&scrolled)
        .build();

    // Refresh stats and summary when navigating to this page
    {
        let lf = state.loaded_files.clone();
        let ef = state.excluded_files.clone();
        let jc = state.job_config.clone();
        let od = state.output_dir.clone();
        let cr = count_row.clone();
        let or = output_row.clone();
        let sb = summary_box.clone();
        page.connect_map(move |_| {
            // Update image count and size
            let files = lf.borrow();
            let excluded = ef.borrow();
            let included_count = files.iter().filter(|p| !excluded.contains(*p)).count();
            let total_size: u64 = files.iter()
                .filter(|p| !excluded.contains(*p))
                .filter_map(|p| std::fs::metadata(p).ok())
                .map(|m| m.len())
                .sum();
            cr.set_subtitle(&format!("{} images ({})", included_count, format_size(total_size)));
            drop(files);
            drop(excluded);

            // Update output directory display
            let dir_text = od.borrow()
                .as_ref()
                .map(|p| p.display().to_string())
                .unwrap_or_else(|| "processed/ (subfolder next to originals)".to_string());
            or.set_subtitle(&dir_text);

            // Build operation summary
            while let Some(child) = sb.first_child() {
                sb.remove(&child);
            }

            let cfg = jc.borrow();
            let mut ops: Vec<(&str, String)> = Vec::new();

            if cfg.resize_enabled {
                let mode = match cfg.resize_mode {
                    0 => format!("{}x{} (exact)", cfg.resize_width, cfg.resize_height),
                    _ => format!("fit {}x{}", cfg.resize_width, cfg.resize_height),
                };
                ops.push(("Resize", mode));
            }
            if cfg.adjustments_enabled {
                let mut parts = Vec::new();
                if cfg.rotation > 0 { parts.push("rotate"); }
                if cfg.flip > 0 { parts.push("flip"); }
                if cfg.brightness != 0 { parts.push("brightness"); }
                if cfg.contrast != 0 { parts.push("contrast"); }
                if cfg.saturation != 0 { parts.push("saturation"); }
                if cfg.grayscale { parts.push("grayscale"); }
                if cfg.sepia { parts.push("sepia"); }
                if cfg.sharpen { parts.push("sharpen"); }
                if cfg.crop_aspect_ratio > 0 { parts.push("crop"); }
                if cfg.trim_whitespace { parts.push("trim"); }
                if cfg.canvas_padding > 0 { parts.push("padding"); }
                let desc = if parts.is_empty() { "enabled".into() } else { parts.join(", ") };
                ops.push(("Adjustments", desc));
            }
            if cfg.convert_enabled {
                let fmt = cfg.convert_format.map(|f| f.extension().to_uppercase())
                    .unwrap_or_else(|| "per-format mapping".into());
                ops.push(("Convert", fmt));
            }
            if cfg.compress_enabled {
                ops.push(("Compress", cfg.quality_preset.label().into()));
            }
            if cfg.metadata_enabled {
                let mode = match &cfg.metadata_mode {
                    crate::app::MetadataMode::StripAll => "strip all",
                    crate::app::MetadataMode::KeepAll => "keep all",
                    crate::app::MetadataMode::Privacy => "privacy mode",
                    crate::app::MetadataMode::Custom => "custom",
                };
                ops.push(("Metadata", mode.into()));
            }
            if cfg.watermark_enabled {
                let wm_type = if cfg.watermark_use_image { "image" } else { "text" };
                ops.push(("Watermark", wm_type.into()));
            }
            if cfg.rename_enabled {
                ops.push(("Rename", "enabled".into()));
            }

            if ops.is_empty() {
                let row = adw::ActionRow::builder()
                    .title("No operations enabled")
                    .subtitle("Go back and enable at least one operation")
                    .build();
                row.add_prefix(&gtk::Image::from_icon_name("dialog-warning-symbolic"));
                sb.append(&row);
            } else {
                for (name, desc) in &ops {
                    let row = adw::ActionRow::builder()
                        .title(*name)
                        .subtitle(desc.as_str())
                        .build();
                    row.add_prefix(&gtk::Image::from_icon_name("emblem-ok-symbolic"));
                    sb.append(&row);
                }
            }
        });
    }

    page
}
