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

use super::*;
use crate::layout::spacer::spacer;
use crate::render::Canvas;
use crate::types::WidgetId;

#[ derive( Clone, Debug, PartialEq, Eq ) ]
enum Msg { Tap, Hold, Drag, Cancel }

#[ test ]
fn new_defaults_have_no_handlers()
{
	let p = Pressable::<Msg>::new( spacer() );
	assert!( p.on_press.is_none() );
	assert!( p.on_long_press.is_none() );
	assert!( p.on_drag_start.is_none() );
	assert!( p.on_escape.is_none() );
	assert!( !p.swallow );
	assert!( p.id.is_none() );
	assert!( !p.has_handler() );
}

#[ test ]
fn on_press_builder_arms_tap_message()
{
	let p = Pressable::new( spacer() ).on_press( Msg::Tap );
	assert_eq!( p.on_press, Some( Msg::Tap ) );
	assert!( p.has_handler() );
}

#[ test ]
fn on_long_press_builder_arms_long_press_message()
{
	let p = Pressable::new( spacer() ).on_long_press( Msg::Hold );
	assert_eq!( p.on_long_press, Some( Msg::Hold ) );
	assert!( p.has_handler() );
}

#[ test ]
fn on_drag_start_builder_arms_drag_message()
{
	let p = Pressable::new( spacer() ).on_drag_start( Msg::Drag );
	assert_eq!( p.on_drag_start, Some( Msg::Drag ) );
	assert!( p.has_handler() );
}

#[ test ]
fn has_handler_is_true_when_any_callback_is_set()
{
	assert!( Pressable::<Msg>::new( spacer() ).on_press( Msg::Tap ).has_handler() );
	assert!( Pressable::<Msg>::new( spacer() ).on_long_press( Msg::Hold ).has_handler() );
	assert!( Pressable::<Msg>::new( spacer() ).on_drag_start( Msg::Drag ).has_handler() );
	assert!( Pressable::<Msg>::new( spacer() )
		.on_press( Msg::Tap ).on_long_press( Msg::Hold ).on_drag_start( Msg::Drag ).has_handler() );
}

#[ test ]
fn on_escape_builder_arms_escape_message()
{
	let p = Pressable::new( spacer() ).on_escape( Msg::Cancel );
	assert_eq!( p.on_escape, Some( Msg::Cancel ) );
	assert!( p.has_handler() );
}

#[ test ]
fn swallow_builder_makes_pressable_hit_testable_without_callbacks()
{
	let p = Pressable::<Msg>::new( spacer() ).swallow( true );
	assert!( p.swallow );
	assert!( p.on_press.is_none() );
	assert!( p.has_handler() );
}

#[ test ]
fn swallow_off_with_no_callbacks_is_invisible_to_input()
{
	let p = Pressable::<Msg>::new( spacer() ).swallow( false );
	assert!( !p.has_handler() );
}

#[ test ]
fn id_builder_assigns_widget_id()
{
	let id = WidgetId( "my_card" );
	let p = Pressable::<Msg>::new( spacer() ).id( id );
	assert_eq!( p.id, Some( id ) );
}

#[ test ]
fn preferred_size_delegates_to_child()
{
	let canvas = Canvas::new( 800, 600 );
	let child  = spacer().width( 50.0 ).height( 30.0 );
	let p      = Pressable::<Msg>::new( child );
	assert_eq!( p.preferred_size( 400.0, &canvas ), ( 50.0, 30.0 ) );
}
