// Reusable composite widgets shared across screens.
//
// Each helper returns an `Element<Msg>` so screens can drop them into
// columns/rows without further plumbing. Nothing here owns state — the
// caller passes the bits it needs (selection flags, callbacks, …).

use ltk::
{
	Corners, Element,
	column, container, pressable, row, spacer, text, radio,
};

use crate::app::Msg;
use crate::ui::theme as t;

// ── Selectable list row ──────────────────────────────────────────────────────

/// One row of a selectable list (e.g. disk partitions). Two stacked
/// labels on the left, a radio button on the right, the whole row is
/// pressable so tapping anywhere selects.
pub fn select_row(
	title:    &str,
	subtitle: Option<&str>,
	selected: bool,
	on_select: Msg,
) -> Element<Msg>
{
	let palette   = ltk::theme_palette();
	let primary   = palette.text_primary;
	let secondary = palette.text_secondary;

	let mut left = column::<Msg>().spacing( 2.0 );
	left = left.push(
		text( title.to_string() )
			.size( t::BODY_SIZE )
			.color( primary ),
	);
	if let Some( s ) = subtitle
	{
		left = left.push(
			text( s.to_string() )
				.size( t::SMALL_SIZE )
				.color( secondary ),
		);
	}

	let r = radio::<Msg>( selected )
		.on_select( on_select.clone() );

	let body = row::<Msg>()
		.spacing( t::ITEM_SPACING )
		.padding( 12.0 )
		.push( left )
		.push( spacer() )
		.push( r );

	pressable::<Msg>( body )
		.on_press( on_select )
		.into()
}

// ── Card with title + bullet body ───────────────────────────────────────────

/// Soft white "info card" used by Welcome, Permissions privacy
/// reassurance, and the install-finish summary.
pub fn info_card( title: Option<&str>, lines: &[ String ] ) -> Element<Msg>
{
	let palette   = ltk::theme_palette();
	let primary   = palette.text_primary;

	let mut col = column::<Msg>().spacing( t::TIGHT_SPACING ).padding( 16.0 );
	if let Some( t ) = title
	{
		col = col.push(
			text( t.to_string() )
				.size( t::BODY_SIZE )
				.color( primary ),
		);
	}
	for line in lines
	{
		col = col.push(
			text( line.clone() )
				.size( t::BODY_SIZE )
				.color( primary ),
		);
	}

	container::<Msg>( col )
		.background( palette.surface )
		.radius( Corners::all( t::CARD_RADIUS ) )
		.into()
}

// ── Pill option (storage, navigation choice) ─────────────────────────────────

/// A wide pill button used for big-decision rows (Save in local
/// device, Proton, Dropbox). Looks like a primary or secondary button
/// at full row width.
pub fn pill_option(
	label:    &str,
	selected: bool,
	on_press: Msg,
) -> Element<Msg>
{
	pill_option_inner( label, None, selected, on_press )
}

/// Brand-iconed variant of [`pill_option`]. The icon (a Proton /
/// Dropbox / similar SVG embedded via `assets::brand_icon!`) sits
/// inline with the label, both centred together inside the pill.
pub fn pill_option_branded(
	label:    &str,
	icon:     &[ u8 ],
	selected: bool,
	on_press: Msg,
) -> Element<Msg>
{
	pill_option_inner( label, Some( icon ), selected, on_press )
}

fn pill_option_inner(
	label:    &str,
	icon:     Option<&[ u8 ]>,
	selected: bool,
	on_press: Msg,
) -> Element<Msg>
{
	let palette = ltk::theme_palette();
	let bg      = if selected { palette.accent } else { palette.surface };
	let fg      = palette.text_primary;

	let mut inner = row::<Msg>()
		.spacing( t::TIGHT_SPACING )
		.padding( 14.0 )
		.push( spacer() );
	if let Some( bytes ) = icon
	{
		if let Some( el ) = crate::assets::illustration_widget::<Msg>( bytes, 20 )
		{
			inner = inner.push( el );
		}
	}
	inner = inner
		.push( text( label.to_string() ).size( t::BODY_SIZE ).color( fg ) )
		.push( spacer() );

	pressable::<Msg>(
		container::<Msg>( inner )
			.background( bg )
			.radius( Corners::all( t::PILL_RADIUS ) ),
	)
	.on_press( on_press )
	.into()
}
