// Integration coverage for `scroll`. The pure clamping math already lives in
// `widget::scroll::tests`; these tests exercise the wiring: `preferred_size`
// claims remaining space, and interactive children inside the viewport remain
// reachable through `UiSurface`'s widget rects.

use ltk::core::{ Canvas, RenderOptions, UiSurface };
use ltk::{ button, column, scroll, text, Color, Element, Point };

#[ derive( Clone, Debug, PartialEq, Eq ) ]
enum Msg
{
	Pressed( u32 ),
}

fn list_view() -> Element<Msg>
{
	scroll(
		column::<Msg>()
			.padding( 0.0 )
			.spacing( 4.0 )
			.push( button( "A" ).on_press( Msg::Pressed( 0 ) ) )
			.push( button( "B" ).on_press( Msg::Pressed( 1 ) ) )
			.push( button( "C" ).on_press( Msg::Pressed( 2 ) ) ),
	).into()
}

#[ test ]
fn scroll_preferred_size_returns_zero_height_to_act_as_filler()
{
	let canvas = Canvas::new( 800, 600 );
	let s = scroll::<Msg>( column::<Msg>() );
	let ( w, h ) = s.preferred_size( 320.0, &canvas );
	assert_eq!( w, 320.0 );
	assert_eq!( h, 0.0 );
}

#[ test ]
fn scroll_with_buttons_exposes_them_through_widget_rects()
{
	let mut surface = UiSurface::<Msg>::new( 320, 480 );
	let _ = surface.render(
		&list_view(),
		RenderOptions::full_canvas( 320, 480 ).background( Color::rgb( 0.1, 0.1, 0.1 ) ),
	);
	// Three interactive buttons are visible inside the scroll viewport.
	assert_eq!( surface.widget_rects().len(), 3 );
}

#[ test ]
fn buttons_inside_scroll_dispatch_their_press_messages()
{
	let mut surface = UiSurface::<Msg>::new( 320, 480 );
	let _ = surface.render(
		&list_view(),
		RenderOptions::full_canvas( 320, 480 ),
	);
	let first = &surface.widget_rects()[ 0 ];
	let msg = surface.handlers( first.flat_idx ).and_then( |h| h.press_msg() );
	assert_eq!( msg, Some( Msg::Pressed( 0 ) ) );
}

#[ test ]
fn hit_test_inside_scroll_returns_button_under_pointer()
{
	let mut surface = UiSurface::<Msg>::new( 320, 480 );
	let _ = surface.render(
		&list_view(),
		RenderOptions::full_canvas( 320, 480 ),
	);
	let first = &surface.widget_rects()[ 0 ];
	let centre = Point
	{
		x: first.rect.x + first.rect.width  * 0.5,
		y: first.rect.y + first.rect.height * 0.5,
	};
	assert_eq!( surface.hit_test( centre ), Some( first.flat_idx ) );
}

#[ test ]
fn empty_scroll_renders_without_panic()
{
	let mut surface = UiSurface::<Msg>::new( 320, 480 );
	let view: Element<Msg> = scroll( column::<Msg>() ).into();
	let out = surface.render(
		&view,
		RenderOptions::full_canvas( 320, 480 ),
	);
	assert!( out.full_redraw );
	assert!( surface.widget_rects().is_empty(), "no buttons inside → no interactive widgets" );
}

#[ test ]
fn scroll_around_text_only_child_produces_no_interactive_widgets()
{
	let mut surface = UiSurface::<Msg>::new( 320, 480 );
	let view: Element<Msg> = scroll(
		column::<Msg>()
			.push( text( "header" ) )
			.push( text( "body" ) ),
	).into();
	let _ = surface.render(
		&view,
		RenderOptions::full_canvas( 320, 480 ),
	);
	// Text is non-interactive — widget_rects only tracks focusable / hittable
	// widgets.
	assert!( surface.widget_rects().is_empty() );
}
