// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>

use smithay_client_toolkit::reexports::client::QueueHandle;
use wayland_protocols::wp::text_input::zv3::client::zwp_text_input_v3;

use crate::app::App;
use crate::event_loop::app_data::AppData;
use crate::event_loop::surface::SurfaceFocus;
use crate::tree::find_widget;
use crate::types::Rect;
use crate::widget::WidgetHandlers;

impl<A: App> AppData<A>
{
	pub( crate ) fn activate_text_input( &mut self, qh: &QueueHandle<Self> )
	{
		if let ( Some( manager ), None ) = ( &self.text_input_manager, &self.text_input )
		{
			let seats: Vec<_> = self.seat_state.seats().collect();
			if let Some( seat ) = seats.into_iter().next()
			{
				let ti = manager.get_text_input( &seat, qh, () );
				ti.enable();
				ti.set_content_type(
					zwp_text_input_v3::ContentHint::None,
					zwp_text_input_v3::ContentPurpose::Normal,
				);
				ti.commit();
				self.text_input = Some( ti );
			}
		}
	}

	pub( crate ) fn deactivate_text_input( &mut self )
	{
		if let Some( ti ) = self.text_input.take()
		{
			ti.disable();
			ti.commit();
			ti.destroy();
		}
	}

	/// Snapshot a focused-widget's geometry needed by the pointer
	/// hit-testers for text editing. Returns `None` when the widget
	/// isn't a TextEdit or its rect is missing — the helper above
	/// short-circuits in that case.
	pub( crate ) fn text_input_geometry(
		&self,
		focus: SurfaceFocus,
		idx:   usize,
	) -> Option<( Rect, String, bool, bool, crate::widget::text::TextAlign, f32 )>
	{
		let ss = self.surface( focus );
		let widget = find_widget( &ss.widget_rects, idx )?;
		let ( value_handler, multiline, secure, align, font_size ) = match &widget.handlers
		{
			WidgetHandlers::TextEdit { value, multiline, secure, align, font_size, .. } =>
				( value.clone(), *multiline, *secure, *align, *font_size ),
			_ => return None,
		};
		// Prefer the *pending* value (typed-but-not-yet-applied) when
		// it exists — that's what the user sees right now and what
		// the cursor measurements should be relative to.
		let value = ss.pending_text_values.get( &idx )
			.cloned()
			.unwrap_or( value_handler );
		Some( ( widget.rect, value, multiline, secure, align, font_size ) )
	}
}
