use std::sync::Arc;

use ltk::theme::typography;
use ltk::{ column, img_widget, text, Element, ImageData };

fn load_theme_logo() -> ImageData
{
	ltk::theme_logo_rgba( 512 )
		.expect( "smartcast: active theme has no branding/{mode}/logo/horizontal.svg" )
}

#[ derive( Clone ) ]
pub enum Msg {}

pub struct SmartcastApp
{
	wallpaper:  ltk::WallpaperBundle,
	logo_light: ImageData,
	logo_dark:  ImageData,
	qr_image:   ImageData,
	url:        String,
	surface_w:  u32,
	surface_h:  u32,
}

impl SmartcastApp
{
	pub fn new() -> Self
	{
		let ip  = crate::smartcast::local_ip();
		let url = format!( "http://{}:8080", ip );
		let ( qr_rgba, qr_w, qr_h ) = crate::smartcast::generate_qr_rgba( &url, 512 );
		crate::smartcast::start_server( 8080 );

		let prev = ltk::active_mode();
		ltk::set_active_mode( ltk::ThemeMode::Light );
		let logo_light = load_theme_logo();
		ltk::set_active_mode( ltk::ThemeMode::Dark );
		let logo_dark = load_theme_logo();
		ltk::set_active_mode( prev );

		Self
		{
			wallpaper:  ltk::wallpaper_bundle_or_solid(),
			logo_light,
			logo_dark,
			qr_image:   ( Arc::new( qr_rgba ), qr_w, qr_h ),
			url,
			surface_w:  0,
			surface_h:  0,
		}
	}

	fn logo( &self ) -> &ImageData
	{
		match ltk::active_mode()
		{
			ltk::ThemeMode::Dark  => &self.logo_dark,
			ltk::ThemeMode::Light => &self.logo_light,
		}
	}
}

impl ltk::App for SmartcastApp
{
	type Message = Msg;

	fn view( &self ) -> Element<Msg>
	{
		let ( logo_rgba, logo_w, logo_h ) = self.logo();
		let logo = column::<Msg>()
			.max_width( 200.0 )
			.padding( 0.0 )
			.spacing( 0.0 )
			.push( img_widget( logo_rgba.clone(), *logo_w, *logo_h ) );

		let ( qr_rgba, qr_w, qr_h ) = &self.qr_image;
		let qr = column::<Msg>()
			.max_width( 240.0 )
			.padding( 0.0 )
			.spacing( 0.0 )
			.push( img_widget( qr_rgba.clone(), *qr_w, *qr_h ) );

		let content = column()
			.padding( 48.0 )
			.spacing( 32.0 )
			.push( ltk::spacer() )
			.push( logo )
			.push( ltk::spacer() )
			.push( qr )
			.push(
				text( self.url.clone() )
					.size( typography::BODY_S )
					.color( ltk::theme_palette().text_secondary )
					.align_center()
			)
			.push( ltk::spacer() );

		ltk::backdrop( content.into(), &self.wallpaper, self.surface_w, self.surface_h )
	}

	fn update( &mut self, _msg: Msg ) {}

	fn on_resize( &mut self, width: u32, height: u32 )
	{
		self.surface_w = width;
		self.surface_h = height;
	}

	fn shell_mode( &self ) -> ltk::ShellMode
	{
		ltk::ShellMode::Layer( ltk::Layer::Top )
	}
}
