use super::*;

pub(super) fn detail_row(ui: &mut egui::Ui, label: &str, value: &str) {
    ui.horizontal_wrapped(|ui| {
        ui.label(egui::RichText::new(label).color(TEXT_DIM));
        ui.add(egui::Label::new(value).wrap().selectable(false));
    });
}

pub(super) fn details_panel(
    world: &mut World,
    ui: &mut egui::Ui,
    selected_entities: &SelectedEntities,
) {
    ui.label(panel_heading("Details"));
    ui.separator();
    let selections = world.resource::<EditorAssets>().selections.clone();
    if selections.len() > 1 {
        let has_authored_content = !selected_content_paths(world).is_empty();
        ui.label(panel_heading(&format!(
            "{} items selected",
            selections.len()
        )));
        ui.small(
            egui::RichText::new("Batch file operations apply to every selected item.")
                .color(TEXT_DIM),
        );
        ui.add_space(6.0);
        for selection in selections.iter().take(12) {
            ui.add(egui::Label::new(selection.display_label()).truncate());
        }
        if selections.len() > 12 {
            ui.small(format!("…and {} more", selections.len() - 12));
        }
        ui.separator();
        if ui
            .add_enabled(
                has_authored_content,
                egui::Button::new("Duplicate Selection"),
            )
            .clicked()
        {
            duplicate_selection(world);
        }
        if ui
            .add_enabled(
                has_authored_content,
                egui::Button::new("Move Selection To Trash"),
            )
            .clicked()
        {
            request_delete_for_selection(world);
        }
        return;
    }
    let selection = world.resource::<EditorAssets>().selected.clone();
    if let Some(AssetSelection::Folder(path)) = selection {
        ui.label(panel_heading(
            Path::new(&path)
                .file_name()
                .and_then(|name| name.to_str())
                .unwrap_or(&path),
        ));
        detail_row(ui, "Path", &path);
        ui.separator();
        if ui.button("Open Folder").clicked() {
            navigate_content_folder(world, path);
        }
    } else if let Some(selection @ AssetSelection::SubAsset { .. }) = selection {
        subasset_details_panel(world, ui, selected_entities, &selection);
    } else if let Some(asset) = world.resource::<EditorAssets>().selected_asset().cloned() {
        top_level_asset_details_panel(world, ui, selected_entities, &asset);
    } else {
        ui.label(egui::RichText::new("No asset selected").color(TEXT_DIM));
    }
}

pub(crate) fn top_level_asset_details_panel(
    world: &mut World,
    ui: &mut egui::Ui,
    selected_entities: &SelectedEntities,
    asset: &EditorAsset,
) {
    asset_details_header(world, ui, asset);
    ui.add_space(8.0);
    detail_row(ui, "Path", asset.path.as_deref().unwrap_or("Built-in"));
    detail_row(ui, "Folder", asset.folder_path.as_str());

    if asset.path.is_none() && asset.label == blacksite_surface::DEFAULT_GRID_LABEL {
        ui.separator();
        ui.label(egui::RichText::new("Engine built-in · read-only").color(TEXT_DIM));
        ui.small("World-space tri-planar checker used when no valid project material resolves.");
        return;
    }

    if let Some(path) = asset.path.as_deref() {
        if let Some(record) = world
            .get_resource::<crate::asset_db::AssetRegistry>()
            .and_then(|registry| find_asset_by_path(registry, path))
        {
            detail_row(ui, "Asset ID", &record.id.as_string());
            if matches!(asset.kind, EditorAssetKind::Model) {
                let settings = record.model_import();
                ui.separator();
                ui.label(panel_heading("Import Settings"));
                import_settings_editor(world, ui, asset, path, settings);
                if let Some(manifest) = settings.static_mesh_manifest_path.as_deref() {
                    detail_row(ui, "Static mesh artifact", manifest);
                }
            }
            if matches!(asset.kind, EditorAssetKind::Texture) {
                if let Some(settings) = record.texture_import() {
                    ui.separator();
                    ui.label(panel_heading("Texture Properties"));
                    texture_import_settings_editor(world, ui, path, &record, settings);
                }
            }
            if !record.dependencies.is_empty() {
                ui.separator();
                let missing_count = record
                    .dependencies
                    .iter()
                    .filter(|dependency| !dependency_path(dependency).is_file())
                    .count();
                ui.horizontal_wrapped(|ui| {
                    ui.label(panel_heading("Dependencies"));
                    if missing_count > 0 {
                        let optional = !model_uses_source_materials(&record);
                        ui.small(
                            egui::RichText::new(if optional {
                                format!("{missing_count} missing | override")
                            } else {
                                format!("{missing_count} missing")
                            })
                            .color(if optional {
                                WARNING
                            } else {
                                ERROR
                            }),
                        );
                    }
                });
                for dep in &record.dependencies {
                    let exists = dependency_path(dep).is_file();
                    ui.horizontal(|ui| {
                        ui.label(
                            egui::RichText::new(if exists {
                                icons::CHECK_CIRCLE.as_str()
                            } else {
                                icons::WARNING_CIRCLE.as_str()
                            })
                            .font(egui::FontId::new(
                                12.0,
                                egui::FontFamily::Name(PHOSPHOR.into()),
                            ))
                            .color(if exists {
                                SUCCESS
                            } else {
                                WARNING
                            }),
                        );
                        ui.add(egui::Label::new(dep).truncate()).on_hover_text(dep);
                    });
                }
            }
        }
        detail_row(
            ui,
            "Size",
            file_size(path).map(format_bytes).as_deref().unwrap_or("-"),
        );
        detail_row(
            ui,
            "Modified",
            modified_time(path)
                .map(format_modified)
                .as_deref()
                .unwrap_or("-"),
        );
        if matches!(asset.kind, EditorAssetKind::Material) {
            ui.separator();
            ui.label(panel_heading("Material"));
            crate::ui::design_system::scope(ui, |ui| {
                if MaterialInstanceAsset::load_from_path(path).is_ok() {
                    material_instance_asset_editor(world, ui, asset, path, true);
                } else {
                    material_asset_editor(world, ui, asset, path, true);
                }
            });
        }
        if matches!(asset.kind, EditorAssetKind::AudioClip) {
            detail_row(ui, "Format", audio_format_label(path));
            let previewing = world
                .resource::<crate::play::audio_preview::AudioPreviewState>()
                .clip_path
                .as_deref()
                == Some(path);
            ui.horizontal_wrapped(|ui| {
                if ui
                    .add_enabled(
                        !previewing,
                        egui::Button::new(format!("{} Audition", icons::PLAY.as_str())),
                    )
                    .clicked()
                {
                    if let Err(error) =
                        crate::play::audio_preview::audition_audio_asset(world, asset)
                    {
                        world.resource_mut::<SceneIo>().status =
                            format!("Audio audition failed: {error}");
                    }
                }
                if ui
                    .add_enabled(
                        previewing,
                        egui::Button::new(format!("{} Stop", icons::STOP.as_str())),
                    )
                    .clicked()
                {
                    crate::play::audio_preview::stop_audio_preview(world);
                }
            });
        }
    }

    ui.separator();
    asset_action_buttons(world, ui, selected_entities, asset);
}

pub(super) fn asset_details_header(world: &World, ui: &mut egui::Ui, asset: &EditorAsset) {
    let thumbnail = world
        .get_resource::<AssetThumbnailCache>()
        .and_then(|cache| cache.snapshot().texture_for(asset));
    ui.horizontal_top(|ui| {
        let (preview, _) = ui.allocate_exact_size(egui::vec2(96.0, 96.0), egui::Sense::hover());
        ui.painter().rect(
            preview,
            5.0,
            WIDGET_BG,
            egui::Stroke::new(1.0_f32, BORDER),
            egui::StrokeKind::Inside,
        );
        if let Some(texture) = thumbnail {
            ui.painter().image(
                texture,
                preview.shrink(4.0),
                egui::Rect::from_min_max(egui::Pos2::ZERO, egui::pos2(1.0, 1.0)),
                egui::Color32::WHITE,
            );
        } else {
            ui.painter().text(
                preview.center(),
                egui::Align2::CENTER_CENTER,
                kind_icon(&asset.kind).as_str(),
                egui::FontId::new(30.0, egui::FontFamily::Name(PHOSPHOR.into())),
                TEXT_DIM,
            );
        }
        ui.vertical(|ui| {
            ui.add(egui::Label::new(egui::RichText::new(&asset.label).strong()).truncate())
                .on_hover_text(&asset.label);
            ui.small(egui::RichText::new(kind_label(&asset.kind)).color(TEXT_DIM));
            if let (Some(state), Some(path)) = (
                world.get_resource::<CollaborationState>(),
                asset.path.as_deref(),
            ) {
                let status = state.file_status(Path::new(path));
                let _ = file_status_indicator_ui(ui, &status, Path::new(path));
            }
            if let Some(snapshot) = asset.path.as_deref().and_then(|path| {
                world
                    .get_resource::<crate::asset_documents::AuthoredAssetDocumentStore>()
                    .and_then(|store| store.snapshot_for_path(path))
            }) {
                if snapshot.dirty {
                    ui.small(egui::RichText::new("UNSAVED").color(WARNING).strong());
                }
            }
            ui.add_space(4.0);
            ui.small(egui::RichText::new("Asset identity and import settings").color(TEXT_MUTED));
        });
    });
}

pub(super) fn subasset_details_panel(
    world: &mut World,
    ui: &mut egui::Ui,
    selected_entities: &SelectedEntities,
    selection: &AssetSelection,
) {
    let Some(embedded) = embedded_asset_for_selection(world, selection) else {
        ui.colored_label(egui::Color32::YELLOW, "Embedded asset is not available.");
        return;
    };
    let AssetSelection::SubAsset {
        parent_path,
        sub_asset_id,
        ..
    } = selection
    else {
        return;
    };
    ui.horizontal_wrapped(|ui| {
        ui.label(
            egui::RichText::new(subasset_icon(embedded.kind).as_str())
                .font(egui::FontId::new(
                    30.0,
                    egui::FontFamily::Name(PHOSPHOR.into()),
                ))
                .color(ACCENT),
        );
        ui.vertical(|ui| {
            ui.strong(embedded.label.as_str());
            ui.small(egui::RichText::new(subasset_kind_label(embedded.kind)).color(TEXT_DIM));
        });
    });
    ui.add_space(8.0);
    detail_row(ui, "Parent", parent_path);
    detail_row(ui, "ID", sub_asset_id);
    detail_row(ui, "Source", &embedded.detail);

    ui.separator();
    match embedded.kind {
        AssetSubAssetKind::Mesh => {
            if embedded.requires_skinned_hierarchy {
                if ui.button("Place Skinned Model At Origin").clicked() {
                    place_subasset_operator(world, selection.clone(), Vec3::ZERO);
                }
            } else if ui.button("Place At Origin").clicked() {
                place_subasset_operator(world, selection.clone(), Vec3::ZERO);
            }
        }
        AssetSubAssetKind::Texture => {
            if ui.button("Apply Texture To Selection").clicked() {
                if let Some(asset) =
                    texture_asset_from_subasset_selection(world, &Some(selection.clone()))
                {
                    apply_texture_operator(world, asset, selected_entities);
                }
            }
        }
        AssetSubAssetKind::Material => {
            let status = if embedded.detail.contains("Authoring Override") {
                "Authoring Override is active; this source material is not assigned."
            } else {
                "Source material is assigned through static mesh renderer slots."
            };
            ui.small(egui::RichText::new(status).color(TEXT_DIM));
        }
        AssetSubAssetKind::Skeleton => {
            ui.small(
                egui::RichText::new("Skeleton metadata is generated from the model source.")
                    .color(TEXT_DIM),
            );
        }
        AssetSubAssetKind::AnimationClip => {
            let animated_actor = selected_entities
                .as_slice()
                .iter()
                .copied()
                .find(|entity| world.get::<shared::SkinnedMeshRenderer>(*entity).is_some());
            let action = if animated_actor.is_some() {
                "Assign To Selected Actor"
            } else {
                "Create Animated Actor"
            };
            if ui.button(action).clicked() {
                if let Some(entity) = animated_actor {
                    assign_animation_clip_operator(world, selection.clone(), entity);
                } else {
                    place_subasset_operator(world, selection.clone(), Vec3::ZERO);
                }
            }
        }
    }
    if ui.button("Select Parent Asset").clicked() {
        world
            .resource_mut::<EditorAssets>()
            .select(AssetSelection::File(parent_path.clone()));
    }
}

pub(super) fn dependency_path(reference: &str) -> PathBuf {
    let path = Path::new(reference);
    if path.starts_with("assets") {
        path.to_path_buf()
    } else {
        Path::new("assets").join(path)
    }
}

pub(super) fn asset_action_buttons(
    world: &mut World,
    ui: &mut egui::Ui,
    selected_entities: &SelectedEntities,
    asset: &EditorAsset,
) {
    ui.horizontal_wrapped(|ui| {
        if matches!(asset.kind, EditorAssetKind::Texture) && ui.button("Apply Texture").clicked() {
            apply_texture_operator(world, asset.clone(), selected_entities);
        }
        if asset.path.is_some()
            && matches!(asset.kind, EditorAssetKind::Material)
            && ui.button("Apply Material").clicked()
        {
            apply_material_operator(world, asset.clone(), selected_entities);
        }
        if matches!(
            asset.kind,
            EditorAssetKind::Primitive(_)
                | EditorAssetKind::Light(_)
                | EditorAssetKind::Model
                | EditorAssetKind::AudioClip
                | EditorAssetKind::Prefab
        ) && ui.button("Place At Origin").clicked()
        {
            place_asset_operator(world, asset.clone(), Vec3::ZERO);
        }
        if matches!(asset.kind, EditorAssetKind::Level) && ui.button("Open Scene").clicked() {
            open_level_asset(world, asset);
        }
        if matches!(asset.kind, EditorAssetKind::Model)
            && has_embedded_assets(world, asset)
            && ui.button("Toggle Contents").clicked()
        {
            if let Some(path) = asset.path.as_ref() {
                toggle_asset_expanded(world, path);
            }
        }
        if matches!(asset.kind, EditorAssetKind::Model) && ui.button("Reimport").clicked() {
            reimport_asset(world, asset);
        }
        if asset.path.is_some() && ui.button("Move To Trash").clicked() {
            request_delete_for_asset(world, asset);
        }
    });
}

pub(super) fn open_level_asset(world: &mut World, asset: &EditorAsset) {
    let Some(path) = asset.path.as_deref() else {
        return;
    };
    world.resource_mut::<SceneIo>().request = Some(SceneIoRequest::OpenPath(PathBuf::from(path)));
}

pub(super) fn activate_content_asset(world: &mut World, asset: &EditorAsset) {
    world
        .resource_mut::<EditorAssets>()
        .select(AssetSelection::from_asset(asset));
    match asset.kind {
        EditorAssetKind::Level => open_level_asset(world, asset),
        EditorAssetKind::Model if has_embedded_assets(world, asset) => {
            if let Some(path) = asset.path.as_deref() {
                toggle_asset_expanded(world, path);
            }
        }
        _ => {
            world.resource_mut::<AssetBrowserUiState>().show_details = true;
        }
    }
}
