//! Block menu hover anchor / layout helper。
//!
//! 本模块承接 block menu 的锚点与面板布局计算，保持几何计算与 DOM 查询分离。
//! 调用方（lib.rs）保留 DOM 查询（editor_stage_element），本模块只做纯几何计算。
//!
//! 迁入自 lib.rs：
//! - `hover_anchor_top`
//! - `hover_anchor_transform`
//! - `block_menu_layout`（参数化版）

use crate::editor_runtime::{
    block_hover_state::{BlockMenuLayout, HoveredBlockState},
    content_layout::content_text_left,
};

/// 多行块的最小高度阈值，超过此值视作多行。
const HANDLE_MULTILINE_HEIGHT: f64 = 40.0;

/// handle shell 菜单左侧最小限制。
const HANDLE_MENU_LEFT_LIMIT: f64 = -320.0;

/// 计算 handle shell 锚点在 stage 内的垂直位置。
pub(crate) fn hover_anchor_top(block: &HoveredBlockState) -> f64 {
    if block.height > HANDLE_MULTILINE_HEIGHT {
        block.top + 12.0
    } else {
        block.top + (block.height / 2.0) - 32.0
    }
}

/// 计算 handle shell 锚点 transform 值（当前固定返回 "none"）。
pub(crate) fn hover_anchor_transform(_block: &HoveredBlockState) -> &'static str {
    "none"
}

/// 计算 block menu 面板布局。
///
/// 参数化版本：调用方提供 stage 的 bounding client rect 尺寸和位置，
/// 本函数做纯几何计算，不查询 DOM。
pub(crate) fn block_menu_layout(
    block: &HoveredBlockState,
    stage_width: f64,
    stage_height: f64,
    stage_top: f64,
    stage_left: f64,
) -> Option<BlockMenuLayout> {
    let shell_top = hover_anchor_top(block);
    let stage_padding = 18.0;
    let space_above = (shell_top - stage_padding).max(0.0);
    let space_below = (stage_height - shell_top - stage_padding).max(0.0);
    let open_upward = space_below < 340.0 && space_above > space_below;
    let available_height = if open_upward {
        space_above
    } else {
        space_below
    };
    let max_height = if available_height >= 220.0 {
        available_height
    } else {
        available_height.max(160.0)
    };
    let menu_width = 242.0;
    let menu_stage_left =
        (content_text_left(stage_width) - menu_width - 132.0).max(HANDLE_MENU_LEFT_LIMIT);
    let viewport_shell_top = stage_top + shell_top;
    let top = if open_upward {
        viewport_shell_top + 64.0 - max_height
    } else {
        viewport_shell_top
    }
    .max(8.0);
    let left = (stage_left + menu_stage_left).max(8.0);

    Some(BlockMenuLayout {
        max_height,
        open_upward,
        top,
        left,
    })
}
