//! Actor-centric inspector (authoring components only).

mod transform;

use bevy::prelude::*;
use bevy_egui::egui;
use egui_phosphor_icons::icons;
use shared::{infer_actor_kind, ActorId, ActorKind, ActorName, HydratedPrefabMember, LevelObject};

use crate::ext::extensibility::ActorInspectorSectionRegistry;
use crate::ui::inspector;
use crate::ui::selection_ops::is_linked_read_only;
use crate::ui::theme::{panel_heading, BORDER, SELECTION, TEXT, TEXT_DIM, WIDGET_BG};
use crate::ui::widgets::phosphor_icon;

use transform::transform_inspector_ui;

const COMPACT_ACTOR_HEADER_WIDTH: f32 = 360.0;

pub fn draw_actor_inspector(world: &mut World, ui: &mut egui::Ui, entity: Entity) {
    let linked_read_only = is_linked_read_only(world, entity);
    let prefab_member = world.get::<HydratedPrefabMember>(entity).is_some();
    let Some(entity_ref) = world.get_entity(entity).ok() else {
        ui.label("Entity no longer exists.");
        return;
    };
    if !entity_ref.contains::<LevelObject>() {
        ui.label("Not a level object.");
        return;
    }

    let kind = infer_actor_kind(entity_ref)
        .or_else(|| entity_ref.get::<ActorKind>().copied())
        .unwrap_or(ActorKind::Empty);

    egui::Frame::new()
        .fill(WIDGET_BG)
        .stroke(egui::Stroke::new(1.0, BORDER))
        .corner_radius(egui::CornerRadius::same(4))
        .inner_margin(egui::Margin::symmetric(8, 8))
        .show(ui, |ui| {
            let compact = ui.available_width() < COMPACT_ACTOR_HEADER_WIDTH;
            ui.horizontal(|ui| {
                ui.label(phosphor_icon(actor_icon(kind), 28.0).color(TEXT_DIM));
                let text_max_width = (ui.available_width() - 28.0).max(96.0);
                ui.vertical(|ui| {
                    ui.set_max_width(text_max_width);
                    let name = entity_ref
                        .get::<ActorName>()
                        .map(|name| name.0.as_str())
                        .or_else(|| entity_ref.get::<Name>().map(|name| name.as_str()))
                        .unwrap_or("Unnamed");
                    let actor_id = entity_ref
                        .get::<ActorId>()
                        .map(|id| id.0.as_str())
                        .filter(|id| !id.trim().is_empty())
                        .unwrap_or("unpersisted");
                    ui.add(egui::Label::new(panel_heading(name)).truncate());
                    if compact {
                        ui.small(
                            egui::RichText::new(format!("{kind:?} | Actor {actor_id}"))
                                .color(TEXT_DIM),
                        );
                        ui.small(
                            egui::RichText::new(format!("Runtime {entity:?}")).color(TEXT_DIM),
                        );
                    } else {
                        ui.small(
                            egui::RichText::new(format!(
                                "{kind:?}  |  Actor {actor_id}  |  Runtime {entity:?}"
                            ))
                            .color(TEXT_DIM),
                        );
                    }
                });
                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
                    ui.label(phosphor_icon(icons::DOTS_THREE_VERTICAL, 16.0).color(TEXT_DIM));
                    ui.label(phosphor_icon(icons::LOCK_SIMPLE, 16.0).color(TEXT_DIM));
                });
            });
        });
    ui.add_space(6.0);

    if linked_read_only {
        ui.small(
            egui::RichText::new(if prefab_member {
                "Linked prefab member"
            } else {
                "Linked scene member"
            })
            .color(TEXT_DIM),
        );
        ui.add_space(4.0);
    }

    if prefab_member {
        egui::ScrollArea::vertical()
            .auto_shrink([false, false])
            .show(ui, |ui| {
                crate::assets::prefab_overrides::prefab_member_inspector_ui(world, ui, entity);
            });
        return;
    }

    ui.add_enabled_ui(!linked_read_only, |ui| {
        egui::ScrollArea::vertical()
            .auto_shrink([false, false])
            .show(ui, |ui| {
                transform_inspector_ui(world, ui, entity);

                match kind {
                    ActorKind::StaticMesh
                    | ActorKind::SkinnedMesh
                    | ActorKind::Brush
                    | ActorKind::ImportedModel
                    | ActorKind::Light
                    | ActorKind::Empty
                    | ActorKind::PrefabAnchor
                    | ActorKind::PlayerSpawn
                    | ActorKind::WeaponSpawn
                    | ActorKind::TriggerVolume
                    | ActorKind::PostProcessVolume
                    | ActorKind::TeamSpawn
                    | ActorKind::Objective
                    | ActorKind::AudioSource
                    | ActorKind::AudioListener
                    | ActorKind::Navigation => {
                        inspector::authoring_inspector_ui(world, ui, entity);
                    }
                }

                world.resource_scope(|world, registry: Mut<ActorInspectorSectionRegistry>| {
                    registry.draw_sections(world, ui, entity);
                });

                inspector::add_component_footer(world, ui, entity);
            });
    });
}

fn actor_icon(kind: ActorKind) -> egui_phosphor_icons::Icon {
    match kind {
        ActorKind::StaticMesh
        | ActorKind::SkinnedMesh
        | ActorKind::Brush
        | ActorKind::ImportedModel => icons::CUBE,
        ActorKind::Light => icons::LIGHTBULB,
        ActorKind::PrefabAnchor => icons::PACKAGE,
        ActorKind::PlayerSpawn => icons::PERSON_SIMPLE_RUN,
        ActorKind::WeaponSpawn => icons::CROSSHAIR,
        ActorKind::TriggerVolume => icons::SELECTION,
        ActorKind::PostProcessVolume => icons::APERTURE,
        ActorKind::TeamSpawn | ActorKind::Objective => icons::FLAG,
        ActorKind::AudioSource => icons::SPEAKER_HIGH,
        ActorKind::AudioListener => icons::HEADPHONES,
        ActorKind::Navigation => icons::PATH,
        ActorKind::Empty => icons::CIRCLE,
    }
}

pub fn draw_multi_actor_inspector(world: &mut World, ui: &mut egui::Ui, entities: &[Entity]) {
    if entities.is_empty() {
        egui::Frame::new()
            .fill(WIDGET_BG)
            .stroke(egui::Stroke::new(1.0, BORDER))
            .corner_radius(egui::CornerRadius::same(4))
            .inner_margin(egui::Margin::symmetric(10, 10))
            .show(ui, |ui| {
                ui.horizontal(|ui| {
                    ui.label(phosphor_icon(icons::SELECTION, 24.0).color(TEXT_DIM));
                    ui.label(egui::RichText::new("No selection").color(TEXT_DIM).strong());
                });
            });
        return;
    }
    if entities.len() == 1 {
        draw_actor_inspector(world, ui, entities[0]);
        return;
    }

    egui::Frame::new()
        .fill(WIDGET_BG)
        .stroke(egui::Stroke::new(1.0, BORDER))
        .corner_radius(egui::CornerRadius::same(4))
        .inner_margin(egui::Margin::symmetric(10, 10))
        .show(ui, |ui| {
            ui.horizontal(|ui| {
                ui.label(phosphor_icon(icons::SELECTION_ALL, 26.0).color(SELECTION));
                ui.vertical(|ui| {
                    ui.label(
                        egui::RichText::new(format!("{} objects selected", entities.len()))
                            .color(TEXT)
                            .strong(),
                    );
                    ui.label(
                        egui::RichText::new("Shared transform gizmo")
                            .color(TEXT_DIM)
                            .small(),
                    );
                });
            });
        });
}
