//! Content Browser presentation shared by production and the UI gallery.
//!
//! The widget owns deterministic Penpot geometry and returns intent. Project navigation,
//! transactions, selection, and authored-document state remain in the editor crate.

use egui;
use egui_phosphor_icons::icons;

use crate::design_system;
use crate::design_system::typography::TypeRole;

pub const TOOLBAR_HEIGHT: f32 = 124.0;
pub const STATUS_BAR_HEIGHT: f32 = 32.0;
pub const COMPACT_BREAKPOINT: f32 = 720.0;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContentBrowserViewMode {
    Grid,
    List,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContentBrowserKindFilter {
    All,
    Model,
    Texture,
    Material,
    Audio,
    Level,
    Prefab,
    Builtin,
}

impl ContentBrowserKindFilter {
    pub const ALL: [Self; 8] = [
        Self::All,
        Self::Model,
        Self::Texture,
        Self::Material,
        Self::Audio,
        Self::Level,
        Self::Prefab,
        Self::Builtin,
    ];

    pub const fn label(self) -> &'static str {
        match self {
            Self::All => "All assets",
            Self::Model => "Models",
            Self::Texture => "Textures",
            Self::Material => "Materials",
            Self::Audio => "Audio",
            Self::Level => "Levels",
            Self::Prefab => "Prefabs",
            Self::Builtin => "Built-ins",
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContentBrowserSort {
    Name,
    Kind,
    Modified,
    Size,
}

impl ContentBrowserSort {
    pub const ALL: [Self; 4] = [Self::Name, Self::Kind, Self::Modified, Self::Size];

    pub const fn label(self) -> &'static str {
        match self {
            Self::Name => "Name",
            Self::Kind => "Type",
            Self::Modified => "Modified",
            Self::Size => "Size",
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContentPathSegment {
    pub path: String,
    pub label: String,
}

#[derive(Debug, Clone)]
pub struct ContentBrowserToolbarViewModel {
    pub path: Vec<ContentPathSegment>,
    pub search: String,
    pub kind_filter: ContentBrowserKindFilter,
    pub sort: ContentBrowserSort,
    pub view: ContentBrowserViewMode,
    pub recursive: bool,
    pub show_details: bool,
    pub thumbnail_size: f32,
    pub can_go_parent: bool,
    pub can_go_back: bool,
    pub can_go_forward: bool,
    pub can_edit_folder: bool,
    pub can_rename: bool,
    pub can_edit_selection: bool,
    pub can_paste: bool,
    pub can_undo: bool,
    pub pending_repairs: usize,
}

#[derive(Debug, Clone, PartialEq)]
pub enum ContentBrowserToolbarAction {
    Back,
    Forward,
    Parent,
    Refresh,
    Navigate(String),
    ImportHere,
    ImportTo,
    NewFolder,
    Rename,
    Duplicate,
    Undo,
    Cut,
    Copy,
    Paste,
    OpenTrash,
    ReviewMoves,
    SetSearch(String),
    SetKindFilter(ContentBrowserKindFilter),
    SetSort(ContentBrowserSort),
    SetView(ContentBrowserViewMode),
    SetRecursive(bool),
    SetShowDetails(bool),
    SetThumbnailSize(f32),
}

pub fn content_browser_toolbar(
    ui: &mut egui::Ui,
    model: &ContentBrowserToolbarViewModel,
) -> Vec<ContentBrowserToolbarAction> {
    let palette = design_system::palette(ui);
    let mut actions = Vec::new();
    let width = ui.available_width().max(1.0);
    let compact = width < COMPACT_BREAKPOINT;
    let (rect, _) = ui.allocate_exact_size(egui::vec2(width, TOOLBAR_HEIGHT), egui::Sense::hover());
    ui.painter().rect_filled(rect, 0.0, palette.recessed);
    ui.painter().line_segment(
        [rect.left_bottom(), rect.right_bottom()],
        egui::Stroke::new(1.0_f32, palette.border),
    );

    let title_bar = egui::Rect::from_min_max(
        rect.min + egui::vec2(8.0, 2.0),
        egui::pos2(rect.right() - 8.0, rect.top() + 31.0),
    );
    ui.scope_builder(egui::UiBuilder::new().max_rect(title_bar), |ui| {
        ui.horizontal_centered(|ui| {
            ui.label(
                egui::RichText::new(icons::FOLDER_OPEN.as_str())
                    .font(egui::FontId::new(
                        14.0,
                        egui::FontFamily::Name("phosphor-bold".into()),
                    ))
                    .color(palette.text_secondary),
            );
            ui.label(TypeRole::AssetTitle.text("Content Browser"));
            let project = egui::Button::new(TypeRole::Eyebrow.text("PROJECT"))
                .fill(palette.accent_dark)
                .stroke(egui::Stroke::new(1.0_f32, palette.accent))
                .corner_radius(egui::CornerRadius::same(4));
            ui.add(project).on_hover_text("Managed project content");
            ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
                design_system::controls::icon_button(
                    ui,
                    icons::DOTS_THREE_VERTICAL,
                    "Content Browser options",
                    true,
                );
            });
        });
    });

    let primary = egui::Rect::from_min_max(
        egui::pos2(rect.left() + 8.0, rect.top() + 38.0),
        egui::pos2(rect.right() - 8.0, rect.top() + 76.0),
    );
    ui.scope_builder(egui::UiBuilder::new().max_rect(primary), |ui| {
        ui.horizontal_centered(|ui| {
            if design_system::controls::icon_button(
                ui,
                icons::ARROW_LEFT,
                "Back",
                model.can_go_back,
            )
            .clicked()
            {
                actions.push(ContentBrowserToolbarAction::Back);
            }
            if design_system::controls::icon_button(
                ui,
                icons::ARROW_RIGHT,
                "Forward",
                model.can_go_forward,
            )
            .clicked()
            {
                actions.push(ContentBrowserToolbarAction::Forward);
            }
            if design_system::controls::icon_button(
                ui,
                icons::ARROW_UP,
                "Parent folder",
                model.can_go_parent,
            )
            .clicked()
            {
                actions.push(ContentBrowserToolbarAction::Parent);
            }
            if design_system::controls::icon_button(
                ui,
                icons::ARROWS_CLOCKWISE,
                "Refresh content",
                true,
            )
            .clicked()
            {
                actions.push(ContentBrowserToolbarAction::Refresh);
            }
            if ui
                .add(
                    egui::Button::new(design_system::controls::icon_label(
                        icons::UPLOAD_SIMPLE,
                        "Import Here",
                        TypeRole::Control,
                        13.0,
                        palette.text_primary,
                    ))
                    .fill(palette.accent_dark)
                    .stroke(egui::Stroke::new(1.0_f32, palette.accent))
                    .corner_radius(egui::CornerRadius::same(4)),
                )
                .clicked()
            {
                actions.push(ContentBrowserToolbarAction::ImportHere);
            }
            if !compact
                && ui
                    .add_enabled(
                        model.can_edit_folder,
                        egui::Button::new(design_system::controls::icon_label(
                            icons::FOLDER_PLUS,
                            "New Folder",
                            TypeRole::Control,
                            13.0,
                            palette.text_primary,
                        )),
                    )
                    .clicked()
            {
                actions.push(ContentBrowserToolbarAction::NewFolder);
            }

            ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
                content_operations_menu(ui, model, &mut actions);
                if model.pending_repairs > 0
                    && ui
                        .button(format!("Resolve {} moves", model.pending_repairs))
                        .on_hover_text("Review ambiguous external move identities")
                        .clicked()
                {
                    actions.push(ContentBrowserToolbarAction::ReviewMoves);
                }
                if !compact {
                    let mut details = model.show_details;
                    if ui
                        .add(egui::Button::new(design_system::controls::icon_label(
                            icons::INFO,
                            "Details",
                            TypeRole::Control,
                            13.0,
                            palette.text_primary,
                        )))
                        .clicked()
                    {
                        details = !details;
                        actions.push(ContentBrowserToolbarAction::SetShowDetails(details));
                    }
                }
                for (mode, icon, tooltip) in [
                    (ContentBrowserViewMode::List, icons::LIST, "List view"),
                    (ContentBrowserViewMode::Grid, icons::GRID_FOUR, "Grid view"),
                ] {
                    let response = design_system::controls::icon_button(ui, icon, tooltip, true);
                    if model.view == mode {
                        ui.painter().rect_stroke(
                            response.rect,
                            4.0,
                            egui::Stroke::new(1.0_f32, palette.accent),
                            egui::StrokeKind::Inside,
                        );
                    }
                    if response.clicked() {
                        actions.push(ContentBrowserToolbarAction::SetView(mode));
                    }
                }
                let mut filter = model.kind_filter;
                egui::ComboBox::from_id_salt("content_browser_kind")
                    .width(if compact { 72.0 } else { 92.0 })
                    .selected_text(filter.label())
                    .show_ui(ui, |ui| {
                        for option in ContentBrowserKindFilter::ALL {
                            ui.selectable_value(&mut filter, option, option.label());
                        }
                    });
                if filter != model.kind_filter {
                    actions.push(ContentBrowserToolbarAction::SetKindFilter(filter));
                }
                let mut search = model.search.clone();
                if ui
                    .add_sized(
                        [if compact { 116.0 } else { 184.0 }, 24.0],
                        egui::TextEdit::singleline(&mut search).hint_text("Search project assets"),
                    )
                    .changed()
                {
                    actions.push(ContentBrowserToolbarAction::SetSearch(search));
                }
            });
        });
    });

    let secondary = egui::Rect::from_min_max(
        egui::pos2(rect.left() + 8.0, rect.top() + 84.0),
        egui::pos2(rect.right() - 8.0, rect.bottom() - 5.0),
    );
    ui.scope_builder(egui::UiBuilder::new().max_rect(secondary), |ui| {
        path_bar(ui, &model.path, &mut actions);
    });
    actions
}

fn path_bar(
    ui: &mut egui::Ui,
    path: &[ContentPathSegment],
    actions: &mut Vec<ContentBrowserToolbarAction>,
) {
    let palette = design_system::palette(ui);
    let (rect, _) = ui.allocate_exact_size(
        egui::vec2(ui.available_width().max(1.0), 24.0),
        egui::Sense::hover(),
    );
    ui.painter().rect(
        rect,
        4.0,
        palette.recessed,
        egui::Stroke::new(1.0_f32, palette.border),
        egui::StrokeKind::Inside,
    );
    ui.scope_builder(
        egui::UiBuilder::new().max_rect(rect.shrink2(egui::vec2(8.0, 2.0))),
        |ui| {
            ui.horizontal_centered(|ui| {
                for (index, segment) in path.iter().enumerate() {
                    if index > 0 {
                        ui.label(TypeRole::Small.text("/").color(palette.text_muted));
                    }
                    let response = ui
                        .add(egui::Button::new(TypeRole::Small.text(&segment.label)).frame(false));
                    if response.clicked() {
                        actions.push(ContentBrowserToolbarAction::Navigate(segment.path.clone()));
                    }
                    response.on_hover_text(&segment.path);
                }
            });
        },
    );
}

fn content_operations_menu(
    ui: &mut egui::Ui,
    model: &ContentBrowserToolbarViewModel,
    actions: &mut Vec<ContentBrowserToolbarAction>,
) {
    let response = ui.menu_button(
        design_system::controls::icon_label(
            icons::DOTS_THREE,
            "Actions",
            TypeRole::Control,
            13.0,
            design_system::palette(ui).text_primary,
        ),
        |ui| {
            operation(
                ui,
                "Import To…",
                model.can_edit_folder,
                ContentBrowserToolbarAction::ImportTo,
                actions,
            );
            operation(
                ui,
                "New Folder",
                model.can_edit_folder,
                ContentBrowserToolbarAction::NewFolder,
                actions,
            );
            ui.separator();
            operation(
                ui,
                "Rename",
                model.can_rename,
                ContentBrowserToolbarAction::Rename,
                actions,
            );
            operation(
                ui,
                "Duplicate",
                model.can_edit_selection,
                ContentBrowserToolbarAction::Duplicate,
                actions,
            );
            operation(
                ui,
                "Cut",
                model.can_edit_selection,
                ContentBrowserToolbarAction::Cut,
                actions,
            );
            operation(
                ui,
                "Copy",
                model.can_edit_selection,
                ContentBrowserToolbarAction::Copy,
                actions,
            );
            operation(
                ui,
                "Paste",
                model.can_paste,
                ContentBrowserToolbarAction::Paste,
                actions,
            );
            ui.separator();
            operation(
                ui,
                "Undo Content Operation",
                model.can_undo,
                ContentBrowserToolbarAction::Undo,
                actions,
            );
            operation(
                ui,
                "Open Trash",
                true,
                ContentBrowserToolbarAction::OpenTrash,
                actions,
            );
            ui.separator();
            let mut recursive = model.recursive;
            if ui.checkbox(&mut recursive, "Include subfolders").changed() {
                actions.push(ContentBrowserToolbarAction::SetRecursive(recursive));
            }
            let mut details = model.show_details;
            if ui.checkbox(&mut details, "Show details pane").changed() {
                actions.push(ContentBrowserToolbarAction::SetShowDetails(details));
            }
            ui.label(TypeRole::Caption.text("Thumbnail size"));
            let mut thumbnail_size = model.thumbnail_size;
            if ui
                .add(egui::Slider::new(&mut thumbnail_size, 48.0..=112.0).show_value(false))
                .changed()
            {
                actions.push(ContentBrowserToolbarAction::SetThumbnailSize(
                    thumbnail_size,
                ));
            }
            ui.label(TypeRole::Caption.text("Sort by"));
            let mut sort = model.sort;
            egui::ComboBox::from_id_salt("content_browser_sort")
                .selected_text(sort.label())
                .show_ui(ui, |ui| {
                    for option in ContentBrowserSort::ALL {
                        ui.selectable_value(&mut sort, option, option.label());
                    }
                });
            if sort != model.sort {
                actions.push(ContentBrowserToolbarAction::SetSort(sort));
            }
        },
    );
    response.response.on_hover_text("Content operations");
}

fn operation(
    ui: &mut egui::Ui,
    label: &str,
    enabled: bool,
    action: ContentBrowserToolbarAction,
    actions: &mut Vec<ContentBrowserToolbarAction>,
) {
    if ui.add_enabled(enabled, egui::Button::new(label)).clicked() {
        actions.push(action);
        ui.close();
    }
}

#[derive(Debug, Clone)]
pub struct ContentBrowserStatusViewModel<'a> {
    pub summary: &'a str,
    pub location: &'a str,
    pub status: &'a str,
}

pub fn content_browser_status_bar(ui: &mut egui::Ui, model: ContentBrowserStatusViewModel<'_>) {
    let palette = design_system::palette(ui);
    let (rect, _) = ui.allocate_exact_size(
        egui::vec2(ui.available_width().max(1.0), STATUS_BAR_HEIGHT),
        egui::Sense::hover(),
    );
    ui.painter().rect_filled(rect, 0.0, palette.recessed);
    ui.painter().line_segment(
        [rect.left_top(), rect.right_top()],
        egui::Stroke::new(1.0_f32, palette.border),
    );
    ui.painter().text(
        rect.left_center() + egui::vec2(10.0, 0.0),
        egui::Align2::LEFT_CENTER,
        model.summary,
        TypeRole::Small.font(),
        palette.text_secondary,
    );
    ui.painter().text(
        rect.center(),
        egui::Align2::CENTER_CENTER,
        model.location,
        TypeRole::Caption.font(),
        palette.text_muted,
    );
    ui.painter().text(
        rect.right_center() - egui::vec2(10.0, 0.0),
        egui::Align2::RIGHT_CENTER,
        model.status,
        TypeRole::Small.font(),
        palette.text_muted,
    );
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn penpot_content_browser_geometry_is_stable() {
        assert_eq!(TOOLBAR_HEIGHT, 124.0);
        assert_eq!(STATUS_BAR_HEIGHT, 32.0);
        assert_eq!(COMPACT_BREAKPOINT, 720.0);
    }

    #[test]
    fn filters_and_sorts_have_stable_labels() {
        assert_eq!(ContentBrowserKindFilter::ALL.len(), 8);
        assert_eq!(ContentBrowserKindFilter::All.label(), "All assets");
        assert_eq!(ContentBrowserSort::ALL.len(), 4);
        assert_eq!(ContentBrowserSort::Kind.label(), "Type");
    }
}
