// Screen 06 — Navigation mode.

use ltk::
{
	Color, Corners, Element,
	column, container, flex, pressable, row, scroll, spacer, text,
};

use crate::app::Msg;
use crate::assets;
use crate::flow::Screen;
use crate::i18n::tr;
use crate::state::{ NavigationMode, State };
use crate::ui::chrome;
use crate::ui::theme as t;

pub fn view( state: &State ) -> Element<Msg>
{
	let palette = ltk::theme_palette();

	// Derive the phone-illustration size from the viewport so the
	// two cards always fit side by side: each card takes roughly
	// half the page minus the page padding and inter-card spacing,
	// the illustration sits inside the card's own padding, and the
	// whole thing is capped so a desktop-sized viewport doesn't
	// inflate the phone mockups to billboard scale.
	let card_inner = card_illustration_size( state.viewport.0 );

	let cards = row::<Msg>()
		.spacing( t::ITEM_SPACING )
		.push( flex( option_card(
			&tr!( "navigation.gestures_title" ),
			&tr!( "navigation.gestures_subtitle" ),
			assets::NAV_GESTURES,
			state.navigation == Some( NavigationMode::Gestures ),
			palette.accent,
			Msg::SelectNavigation( NavigationMode::Gestures ),
			card_inner,
		) ) )
		.push( flex( option_card(
			&tr!( "navigation.buttons_title" ),
			&tr!( "navigation.buttons_subtitle" ),
			assets::NAV_THREE_BUTTON,
			state.navigation == Some( NavigationMode::ThreeButton ),
			palette.accent,
			Msg::SelectNavigation( NavigationMode::ThreeButton ),
			card_inner,
		) ) );

	let cta = state.navigation.map( |_| Msg::Next );

	let content = column::<Msg>()
		.spacing( t::SECTION_SPACING )
		.push( chrome::title_block(
			&tr!( "navigation.title" ),
			Some( &tr!( "navigation.subtitle" ) ),
		) )
		.push( cards );

	let body = column::<Msg>()
		.padding( t::PAGE_PADDING_H )
		.spacing( t::SECTION_SPACING )
		.push( chrome::top_bar( Screen::Navigation, true, state.mode ) )
		.push( scroll( content ) )
		.push( chrome::primary_cta( &tr!( "common.continue" ), cta ) );

	chrome::page( body )
}

/// Pixel size for the phone mockup inside each option card. The
/// illustration is roughly square, so the same value drives both the
/// preferred raster size and the height it claims inside the card
/// column. Caps at 220 so the card doesn't blow up on desktop
/// viewports; floors at 96 so the mockup stays recognisable on
/// narrow phone-class screens.
fn card_illustration_size( viewport_w: u32 ) -> u32
{
	let page    = viewport_w.saturating_sub( ( t::PAGE_PADDING_H * 2.0 ) as u32 );
	let per_card = page.saturating_sub( t::ITEM_SPACING as u32 ) / 2;
	// Subtract the card's own internal padding (12 each side) to
	// land on the available width for the illustration itself.
	let inner = per_card.saturating_sub( 24 );
	inner.clamp( 96, 220 )
}

fn option_card(
	title:    &str,
	subtitle: &str,
	svg:      &[ u8 ],
	selected: bool,
	accent:   Color,
	on_press: Msg,
	size:     u32,
) -> Element<Msg>
{
	let palette = ltk::theme_palette();

	let illustration: Element<Msg> = assets::illustration_widget::<Msg>( svg, size )
		.unwrap_or_else( || spacer().into() );

	// The "card" is only the rounded rectangle around the
	// illustration. Title and subtitle live below as plain centred
	// text inside the same `pressable` so the whole option is still
	// tap-able, but the selection highlight (cyan accent border)
	// affects only the illustration frame.
	let frame = container::<Msg>( illustration )
		.background( palette.surface )
		.border(
			if selected { accent } else { palette.divider },
			if selected { 2.0 } else { 1.0 },
		)
		.radius( Corners::all( t::CARD_RADIUS ) )
		.padding( 12.0 );

	let inner = column::<Msg>()
		.spacing( t::TIGHT_SPACING )
		.align_center_x( true )
		.push( frame )
		.push( text( title.to_string() )
			.size( t::BODY_SIZE )
			.color( palette.text_primary )
			.weight( 700 )
			.align_center() )
		.push( text( subtitle.to_string() )
			.size( t::SMALL_SIZE )
			.color( palette.text_secondary )
			.align_center()
			.wrap( true ) );

	pressable::<Msg>( inner )
		.on_press( on_press )
		.into()
}
