//! Edit-mode context menu.
//!
//! Shown when the user opens an icon's context menu — touch hold or
//! mouse right-click — on the dock or homescreen grid. The menu is
//! anchored near the icon it belongs to, clamped inside the visible
//! surface, and offers the per-item actions the shell supports:
//!
//! - Información — opens a small overlay describing the app.
//! - Eliminar del homescreen — unpins the item from the dock / grid.
//! - Desinstalar — stub for now; filtered per-app-type later.
//! - Cancelar edición — dismisses the menu and exits edit mode.
//!
//! Tapping anywhere outside the panel also exits edit mode, routed through
//! the overlay's `on_dismiss` in [`crate::app`].

use crate::message::Message;
use crate::homescreen::DragOrigin;

use rust_i18n::t;

/// State carried by an open edit menu: which icon it is anchored on and
/// the approximate centre of that icon (in logical pixels) so the panel
/// lands adjacent to the cell that opened the menu.
pub struct EditMenu
{
	pub origin:   DragOrigin,
	pub app_id:   String,
	pub app_name: String,
	pub anchor:   ( f32, f32 ),
	pub running:  bool,
}

/// Approximate menu card dimensions in logical pixels. Used to clamp the
/// anchor against the surface edges so the panel never renders partially
/// off-screen even when the icon that opened the menu sits in a corner.
const MENU_W: f32 = 260.0;
const MENU_H: f32 = 230.0;
/// Minimum breathing room between the menu and the surface edges.
const EDGE_PAD: f32 = 12.0;
/// Nudge above the anchor so the panel centre doesn't sit on the finger.
const ANCHOR_NUDGE_UP: f32 = 32.0;

impl EditMenu
{
	/// Compute the top-left corner of the panel, clamped inside the
	/// visible surface. The anchor is the centre of the icon the menu
	/// belongs to; we place the menu above and slightly offset so the
	/// user can see the icon the menu refers to.
	fn panel_origin( &self, screen_w: u32, screen_h: u32 ) -> ( f32, f32 )
	{
		let ( ax, ay ) = self.anchor;
		let sw = screen_w as f32;
		let sh = screen_h as f32;
		let min_x = EDGE_PAD;
		let max_x = ( sw - MENU_W - EDGE_PAD ).max( min_x );
		let min_y = EDGE_PAD;
		let max_y = ( sh - MENU_H - EDGE_PAD ).max( min_y );
		let x = ( ax - MENU_W * 0.5 ).clamp( min_x, max_x );
		let y = ( ay - MENU_H - ANCHOR_NUDGE_UP ).clamp( min_y, max_y );
		( x, y )
	}

	pub fn view( &self, screen_w: u32, screen_h: u32 ) -> ltk::Element<Message>
	{
		let palette = ltk::theme_palette();

		let temp_only = matches!( self.origin, DragOrigin::Running { .. } );
		let mut col = ltk::column::<Message>()
			.fit_content()
			.max_width( MENU_W )
			.padding( 8.0 )
			.spacing( 2.0 )
			.push(
				ltk::text( &self.app_name )
					.size( 14.0 )
					.color( palette.text_primary ),
			)
			.push( ltk::separator() );

		if !temp_only
		{
			col = col
				.push(
					ltk::list_item::<Message>( t!( "editmenu_info" ).to_string() )
						.on_press( Message::EditMenuInfo ),
				);
		}
		if self.running
		{
			col = col
				.push(
					ltk::list_item::<Message>( t!( "editmenu_close" ).to_string() )
						.on_press( Message::EditMenuClose ),
				);
		}
		if !temp_only
		{
			col = col
				.push(
					ltk::list_item::<Message>( t!( "editmenu_remove" ).to_string() )
						.on_press( Message::EditMenuRemove ),
				)
				.push(
					ltk::list_item::<Message>( t!( "editmenu_uninstall" ).to_string() )
						.on_press( Message::EditMenuUninstall ),
				);
		}
		col = col.push( ltk::separator() ).push(
			ltk::list_item::<Message>( t!( "editmenu_cancel" ).to_string() )
				.on_press( Message::EditMenuCancel ),
		);

		let panel = ltk::container( col )
			.background( palette.surface )
			.padding( 4.0 )
			.radius( 12.0 );

		// Place the panel at the computed anchor inside a full-surface
		// stack. The stack itself is transparent — the overlay's own
		// `on_dismiss` handles taps on the bare areas.
		let ( x, y ) = self.panel_origin( screen_w, screen_h );
		ltk::stack::<Message>()
			.push_translated( panel, ltk::HAlign::Start, ltk::VAlign::Top, x, y )
			.into()
	}
}
