use std::sync::Arc;
use std::time::Instant;

use crate::launcher::icon_cache::IconCache;
use crate::message::Message;
use crate::splash::{ SplashEntry, LANDSCAPE_CARD_FRAC, PULSE_AMPLITUDE, PULSE_PERIOD };

const RADIUS:        f32 = 24.0;
const TEXT_SIZE:     f32 = 22.0;
const ICON_TEXT_GAP: f32 = 16.0;

/// Build the splash overlay for `entry`. Portrait fills the screen,
/// landscape draws a centred card of exactly 30% × 30%.
pub fn build(
	entry:         &SplashEntry,
	icon_cache:    &mut IconCache,
	default_icon:  &( Arc<Vec<u8>>, u32, u32 ),
	screen_width:  u32,
	screen_height: u32,
) -> ltk::Element<Message>
{
	let palette  = ltk::theme_palette();
	let portrait = screen_height > screen_width;

	let ( card_w, card_h, icon_size ) = if portrait
	{
		let cw = screen_width  as f32;
		let ch = screen_height as f32;
		( cw, ch, cw * 0.5 )
	} else {
		let cw = ( screen_width  as f32 ) * LANDSCAPE_CARD_FRAC;
		let ch = ( screen_height as f32 ) * LANDSCAPE_CARD_FRAC;
		( cw, ch, ch * 0.25 )
	};

	let max_icon = icon_size * ( 1.0 + PULSE_AMPLITUDE );
	let icon_px  = max_icon.max( 1.0 ).ceil() as u32;
	let ( rgba, iw, ih ) = entry.icon.as_ref()
		.and_then( |p| icon_cache.get_or_load_sized( p, icon_px ) )
		.unwrap_or_else( || default_icon.clone() );

	let phase     = Instant::now().duration_since( entry.started_at ).as_secs_f32()
		/ PULSE_PERIOD.as_secs_f32();
	let pulse     = 0.5 * ( 1.0 - ( phase * std::f32::consts::TAU ).cos() );
	let cur_icon  = icon_size * ( 1.0 + PULSE_AMPLITUDE * pulse );

	let icon_slot: ltk::Element<Message> = ltk::stack::<Message>()
		.fit_content()
		.push( ltk::spacer().width( max_icon ).height( max_icon ) )
		.push_aligned(
			ltk::img_widget( rgba, iw, ih ).size( cur_icon, cur_icon ),
			ltk::HAlign::Center,
			ltk::VAlign::Center,
		)
		.into();

	let content: ltk::Element<Message> = ltk::column::<Message>()
		.padding( 0.0 )
		.spacing( 0.0 )
		.align_center_x( true )
		.fit_content()
		.push( icon_slot )
		.push( ltk::spacer().height( ICON_TEXT_GAP ) )
		.push(
			ltk::text( entry.name.clone() )
				.size( TEXT_SIZE )
				.color( palette.text_primary )
				.align_center(),
		)
		.into();

	let card_body: ltk::Element<Message> = ltk::stack::<Message>()
		.fit_content()
		.push( ltk::spacer().width( card_w ).height( card_h ) )
		.push_aligned( content, ltk::HAlign::Center, ltk::VAlign::Center )
		.into();

	if portrait
	{
		ltk::container( card_body )
			.background( palette.surface )
			.into()
	}
	else
	{
		let card: ltk::Element<Message> = ltk::container( card_body )
			.background( palette.surface )
			.radius( RADIUS )
			.into();
		ltk::stack::<Message>()
			.push( ltk::spacer().width( screen_width as f32 ).height( screen_height as f32 ) )
			.push_aligned( card, ltk::HAlign::Center, ltk::VAlign::Center )
			.into()
	}
}
