// BEDIT — block editor as a dedicated "space" tab (issue #261).
//
// Workflow:
//   1. BEDIT: user picks an INSERT (or has one pre-selected).
//   2. A block-editor space opens: rendering, picking and new geometry are
//      scoped to the block's record, so ONLY the block's own (block-local)
//      entities are drawn — no INSERT transform, they show exactly as stored.
//   3. The user edits them with normal commands. Because they ARE the block
//      definition's entities, edits are live.
//   4. Save Block (BEDIT_SAVE): keep the edits and leave the block space.
//      Discard (BEDIT_DISCARD): restore the block to its on-entry snapshot.
//
// Unlike REFEDIT (which copies entities into model space with the INSERT
// transform and inverse-transforms them back on save), a BEDIT space edits the
// block record in place, so there is no copy-back and no transform — the space
// render filter (`current_layout_block_handle`) already draws only the block.

use acadrust::{EntityType, Handle};
use glam::DVec3;

use crate::command::{CadCommand, CmdResult};
use crate::modules::{IconKind, ModuleEvent, ToolDef};

/// Right-edge side-toolbar buttons shown while a BEDIT block-editor space is
/// active: save the block edits and leave, or discard them.
pub fn block_edit_tools() -> Vec<ToolDef> {
    vec![
        ToolDef {
            id: "BEDIT_SAVE",
            label: "Save Block",
            icon: IconKind::Svg(include_bytes!("../../../../assets/icons/mt_ok.svg")),
            event: ModuleEvent::Command("BEDIT_SAVE".to_string()),
        },
        ToolDef {
            id: "BEDIT_DISCARD",
            label: "Discard Block Edit",
            icon: IconKind::Svg(include_bytes!("../../../../assets/icons/mt_cancel.svg")),
            event: ModuleEvent::Command("BEDIT_DISCARD".to_string()),
        },
    ]
}

// ── Session state (held in DocumentTab) ───────────────────────────────────

/// Active BEDIT block-editor session. Lives in `DocumentTab::block_edit`.
#[derive(Clone)]
pub struct BlockEditSession {
    /// Name of the block being edited (also the space-tab label).
    pub block_name: String,
    /// Handle of the block record whose entities are being edited.
    pub br_handle: Handle,
    /// Space to return to when the block editor closes (the layout that was
    /// active when BEDIT began).
    pub return_layout: String,
    /// The block's block-local entities captured on entry, so Discard can
    /// restore the definition (structural Block/BlockEnd/AttDef excluded).
    pub snapshot: Vec<EntityType>,
    /// Camera state of the space that was active when BEDIT began, restored
    /// on Save/Discard so the view returns exactly where it was (#425).
    pub return_camera: crate::scene::view::camera::Camera,
}

// ── BEDIT pick command ─────────────────────────────────────────────────────

/// Step 1: wait for the user to pick a single INSERT entity to edit.
pub struct BlockEditPickCommand;

impl BlockEditPickCommand {
    pub fn new() -> Self {
        Self
    }
}

impl CadCommand for BlockEditPickCommand {
    fn name(&self) -> &'static str {
        "BEDIT"
    }
    fn prompt(&self) -> String {
        "BEDIT  Select block reference to edit:".into()
    }
    fn needs_entity_pick(&self) -> bool {
        true
    }
    fn on_entity_pick(&mut self, handle: Handle, _pt: DVec3) -> CmdResult {
        if handle.is_null() {
            return CmdResult::NeedPoint;
        }
        // Signal the host to open the block-editor space for this INSERT.
        CmdResult::Relaunch(format!("BEDIT_BEGIN:{}", handle.value()), vec![handle])
    }
    fn on_point(&mut self, _pt: DVec3) -> CmdResult {
        CmdResult::NeedPoint
    }
    fn on_enter(&mut self) -> CmdResult {
        CmdResult::Cancel
    }
}

// ── Autocomplete registry ─────────────────────────────────
inventory::submit!(crate::command::CommandRegistration { names: &["BEDIT"] }); // BlockEditPickCommand
inventory::submit!(crate::command::CommandRegistration { names: &["BEDIT_SAVE"] });
inventory::submit!(crate::command::CommandRegistration { names: &["BEDIT_DISCARD"] });
