use super::*;

#[expect(
    clippy::too_many_arguments,
    reason = "asset list rendering shares explicit grid/list selection and thumbnail inputs"
)]
pub(super) fn asset_list(
    world: &mut World,
    ui: &mut egui::Ui,
    selected_entities: &SelectedEntities,
    selected: &Option<AssetSelection>,
    folders: &[FolderSnapshot],
    assets: &[AssetRow],
    cache_snapshot: &ThumbnailCacheSnapshot,
    visible_order: &[AssetSelection],
) {
    if ui.available_width() < COMPACT_LIST_WIDTH {
        compact_asset_list(
            world,
            ui,
            selected_entities,
            selected,
            folders,
            assets,
            cache_snapshot,
            visible_order,
        );
        return;
    }

    ui.horizontal(|ui| {
        ui.add_sized([236.0, 18.0], egui::Label::new("Name"));
        ui.add_sized([80.0, 18.0], egui::Label::new("Type"));
        ui.add_sized([72.0, 18.0], egui::Label::new("Size"));
        ui.add_sized([88.0, 18.0], egui::Label::new("Modified"));
        ui.label("Path");
    });

    for folder in folders {
        let selection = AssetSelection::Folder(folder.path.clone());
        let is_selected = world.resource::<EditorAssets>().is_selected(&selection);
        let row_frame = egui::Frame::new()
            .fill(if is_selected {
                crate::ui::theme::SELECTION_BG_MUTED
            } else {
                WIDGET_BG.linear_multiply(0.9)
            })
            .inner_margin(egui::Margin::symmetric(6, 3))
            .show(ui, |ui| {
                ui.horizontal(|ui| {
                    ui.add_sized([20.0, 20.0], egui::Label::new(""));
                    ui.label(icon_text(icons::FOLDER, 14.0).color(TEXT_DIM));
                    ui.add_sized(
                        [196.0, 20.0],
                        egui::Button::selectable(is_selected, folder.name.as_str()),
                    )
                })
                .inner
            });
        let response = row_frame.response.interact(egui::Sense::click_and_drag());
        if response.double_clicked() {
            navigate_content_folder(world, folder.path.clone());
        } else if response.clicked() {
            apply_content_click_selection(world, ui, selection.clone(), visible_order);
        }
        if response.drag_started() {
            world
                .resource_mut::<EditorAssets>()
                .start_drag(selection.clone());
        }
        if response.secondary_clicked() {
            prepare_context_menu_selection(world, selection);
        }
        response.context_menu(|ui| folder_context_menu(world, ui, folder));
    }

    for row in assets {
        draw_asset_list_item(world, ui, selected_entities, selected, row, visible_order);
        if row.asset.path.as_deref().is_some_and(|path| {
            world
                .resource::<AssetBrowserUiState>()
                .expanded_assets
                .contains(path)
        }) {
            embedded_asset_shelf(
                world,
                ui,
                selected_entities,
                selected,
                &row.asset,
                cache_snapshot,
                56.0,
            );
        }
    }
}

pub(super) fn draw_asset_list_item(
    world: &mut World,
    ui: &mut egui::Ui,
    selected_entities: &SelectedEntities,
    _selected: &Option<AssetSelection>,
    row: &AssetRow,
    visible_order: &[AssetSelection],
) {
    let has_children = has_embedded_assets(world, &row.asset);
    let expanded = row.asset.path.as_deref().is_some_and(|path| {
        world
            .resource::<AssetBrowserUiState>()
            .expanded_assets
            .contains(path)
    });
    let is_selected = world.resource::<EditorAssets>().is_selected(&row.selection);
    let document_status = asset_document_status(world, row.asset.path.as_deref());
    let status = AssetCardStatus::for_document(
        document_status.as_ref(),
        document_status
            .as_ref()
            .is_some_and(|snapshot| snapshot.dirty),
        false,
    );
    let row_frame = egui::Frame::new()
        .fill(if is_selected {
            crate::ui::theme::SELECTION_BG_MUTED
        } else {
            WIDGET_BG.linear_multiply(0.9)
        })
        .stroke(egui::Stroke::new(
            1.0_f32,
            if is_selected { ACCENT } else { BORDER },
        ))
        .inner_margin(egui::Margin::symmetric(6, 3))
        .show(ui, |ui| {
            ui.horizontal(|ui| {
                if has_children {
                    let icon = if expanded {
                        icons::CARET_DOWN
                    } else {
                        icons::CARET_RIGHT
                    };
                    if ui
                        .add_sized(
                            [20.0, 20.0],
                            egui::Button::new(icon_text(icon, 12.0)).frame(false),
                        )
                        .clicked()
                    {
                        if let Some(path) = row.asset.path.as_ref() {
                            toggle_asset_expanded(world, path);
                        }
                    }
                } else {
                    ui.add_sized([20.0, 20.0], egui::Label::new(""));
                }
                ui.label(icon_text(kind_icon(&row.asset.kind), 14.0).color(TEXT_DIM));
                let response = ui.add_sized(
                    [176.0, 20.0],
                    egui::Button::selectable(is_selected, row.asset.label.as_str()),
                );
                draw_asset_status_marker(ui, status);
                ui.add_sized([80.0, 20.0], egui::Label::new(kind_label(&row.asset.kind)));
                ui.add_sized(
                    [72.0, 20.0],
                    egui::Label::new(
                        row.file_size
                            .map(format_bytes)
                            .unwrap_or_else(|| "-".to_string()),
                    ),
                );
                ui.add_sized(
                    [88.0, 20.0],
                    egui::Label::new(
                        row.modified
                            .map(format_modified)
                            .unwrap_or_else(|| "-".to_string()),
                    ),
                );
                ui.add(
                    egui::Label::new(row.asset.path.as_deref().unwrap_or("Built-in")).truncate(),
                );
                ui.menu_button(icon_text(icons::DOTS_THREE_VERTICAL, 13.0), |ui| {
                    asset_context_menu(world, ui, &row.asset, selected_entities);
                });
                response
            })
            .inner
        });
    let response = row_frame.response.interact(egui::Sense::click_and_drag());

    if response.double_clicked() {
        activate_content_asset(world, &row.asset);
    } else if response.clicked() {
        apply_content_click_selection(world, ui, row.selection.clone(), visible_order);
    }
    if response.drag_started() {
        world
            .resource_mut::<EditorAssets>()
            .start_drag(row.selection.clone());
    }
    if response.secondary_clicked() {
        prepare_context_menu_selection(world, row.selection.clone());
    }
    response.context_menu(|ui| {
        asset_context_menu(world, ui, &row.asset, selected_entities);
    });
}

pub(super) fn asset_document_status(
    world: &World,
    path: Option<&str>,
) -> Option<crate::asset_documents::AuthoredDocumentSnapshot> {
    path.and_then(|path| {
        world
            .get_resource::<crate::asset_documents::AuthoredAssetDocumentStore>()
            .and_then(|store| store.snapshot_for_path(path))
    })
}

#[expect(
    clippy::too_many_arguments,
    reason = "compact list rendering shares explicit grid/list selection and thumbnail inputs"
)]
pub(super) fn compact_asset_list(
    world: &mut World,
    ui: &mut egui::Ui,
    selected_entities: &SelectedEntities,
    selected: &Option<AssetSelection>,
    folders: &[FolderSnapshot],
    assets: &[AssetRow],
    cache_snapshot: &ThumbnailCacheSnapshot,
    visible_order: &[AssetSelection],
) {
    for folder in folders {
        let selection = AssetSelection::Folder(folder.path.clone());
        let is_selected = world.resource::<EditorAssets>().is_selected(&selection);
        let response = ui
            .horizontal(|ui| {
                ui.label(icon_text(icons::FOLDER, 14.0).color(TEXT_DIM));
                ui.add_sized(
                    [fit_width(ui, 120.0, f32::INFINITY), 22.0],
                    egui::Button::selectable(is_selected, folder.name.as_str()),
                )
            })
            .inner;
        if response.double_clicked() {
            navigate_content_folder(world, folder.path.clone());
        } else if response.clicked() {
            apply_content_click_selection(world, ui, selection.clone(), visible_order);
        }
        if response.drag_started() {
            world
                .resource_mut::<EditorAssets>()
                .start_drag(selection.clone());
        }
        if response.secondary_clicked() {
            prepare_context_menu_selection(world, selection);
        }
        response.context_menu(|ui| folder_context_menu(world, ui, folder));
        ui.small(egui::RichText::new("Folder").color(TEXT_DIM));
        ui.add_space(4.0);
    }

    for row in assets {
        let is_selected = world.resource::<EditorAssets>().is_selected(&row.selection);
        let document_status = asset_document_status(world, row.asset.path.as_deref());
        let status = AssetCardStatus::for_document(
            document_status.as_ref(),
            document_status
                .as_ref()
                .is_some_and(|snapshot| snapshot.dirty),
            false,
        );
        let has_children = has_embedded_assets(world, &row.asset);
        let expanded = row.asset.path.as_deref().is_some_and(|path| {
            world
                .resource::<AssetBrowserUiState>()
                .expanded_assets
                .contains(path)
        });
        let mut response = None;
        ui.horizontal(|ui| {
            if has_children {
                let icon = if expanded {
                    icons::CARET_DOWN
                } else {
                    icons::CARET_RIGHT
                };
                if ui
                    .add_sized(
                        [20.0, 20.0],
                        egui::Button::new(icon_text(icon, 12.0)).frame(false),
                    )
                    .clicked()
                {
                    if let Some(path) = row.asset.path.as_ref() {
                        toggle_asset_expanded(world, path);
                    }
                }
            }
            ui.label(icon_text(kind_icon(&row.asset.kind), 14.0).color(TEXT_DIM));
            draw_asset_status_marker(ui, status);
            response = Some(ui.add_sized(
                [fit_width(ui, 120.0, f32::INFINITY), 22.0],
                egui::Button::selectable(is_selected, row.asset.label.as_str()),
            ));
            ui.menu_button(icon_text(icons::DOTS_THREE_VERTICAL, 13.0), |ui| {
                asset_context_menu(world, ui, &row.asset, selected_entities);
            });
        });
        let response = response.expect("compact asset list response");
        let size = row
            .file_size
            .map(format_bytes)
            .unwrap_or_else(|| "-".to_string());
        let modified = row
            .modified
            .map(format_modified)
            .unwrap_or_else(|| "-".to_string());
        let path = row.asset.path.as_deref().unwrap_or("Built-in");
        ui.add(
            egui::Label::new(
                egui::RichText::new(format!(
                    "{} | {} | {} | {}",
                    kind_label(&row.asset.kind),
                    size,
                    modified,
                    path
                ))
                .color(TEXT_DIM),
            )
            .truncate(),
        );
        ui.add_space(4.0);

        if response.double_clicked() {
            activate_content_asset(world, &row.asset);
        } else if response.clicked() {
            apply_content_click_selection(world, ui, row.selection.clone(), visible_order);
        }
        if response.drag_started() {
            world
                .resource_mut::<EditorAssets>()
                .start_drag(row.selection.clone());
        }
        if response.secondary_clicked() {
            prepare_context_menu_selection(world, row.selection.clone());
        }
        response.context_menu(|ui| {
            asset_context_menu(world, ui, &row.asset, selected_entities);
        });
        if expanded {
            embedded_asset_shelf(
                world,
                ui,
                selected_entities,
                selected,
                &row.asset,
                cache_snapshot,
                56.0,
            );
        }
    }
}

pub(super) fn draw_folder_cell(
    ui: &mut egui::Ui,
    folder: &FolderSnapshot,
    thumbnail_size: f32,
    is_selected: bool,
) -> egui::Response {
    let thumb_size = thumbnail_size.clamp(48.0, 112.0);
    let cell_size = egui::vec2(thumb_size + 20.0, thumb_size + 30.0);
    let (rect, response) = ui.allocate_exact_size(cell_size, egui::Sense::click_and_drag());
    let fill = if is_selected {
        crate::ui::theme::SELECTION_BG_MUTED
    } else if response.hovered() {
        ELEVATED_BG
    } else {
        WIDGET_BG
    };
    ui.painter().rect(
        rect,
        4.0,
        fill,
        egui::Stroke::new(1.0_f32, if is_selected { ACCENT } else { BORDER }),
        egui::StrokeKind::Inside,
    );
    ui.painter().text(
        rect.center_top() + egui::vec2(0.0, 10.0 + thumb_size * 0.45),
        egui::Align2::CENTER_CENTER,
        icons::FOLDER_SIMPLE.as_str(),
        egui::FontId::new(
            (thumb_size * 0.48).max(24.0),
            egui::FontFamily::Name("phosphor-regular".into()),
        ),
        TEXT,
    );
    ui.painter().text(
        egui::pos2(rect.center().x, rect.max.y - 6.0),
        egui::Align2::CENTER_BOTTOM,
        folder.name.as_str(),
        egui::FontId::new(11.0, egui::FontFamily::Proportional),
        TEXT,
    );
    response
}
