mod app;
mod config;
mod i18n;
mod network;
mod notif_channels;
mod single_instance;
mod storage;
mod system;
mod ui;
mod upower;
mod views;

use ltk::{ App, ThemeMode, ThemePreference };
use app::{ Msg, State, screen_arg_name, screen_by_name };

// Pull every YAML under `locales/` into the rust-i18n runtime registry.
// ltk runs its own `i18n!()` invocation; the two registries merge.
rust_i18n::i18n!( "locales", fallback = "en" );

fn main()
{
	tracing_subscriber::fmt()
		.with_env_filter( tracing_subscriber::EnvFilter::from_default_env() )
		.init();

	// An explicit choice from the Region & Language screen wins over the
	// system locale; a stale unsupported code falls back to detection.
	let saved = config::read_language();
	let code  = saved.as_deref()
		.filter( |c| i18n::SUPPORTED.iter().any( |l| l.code == *c ) )
		.unwrap_or_else( || i18n::detect_locale() );
	i18n::set_locale( code );

	let args = std::env::args().collect::<Vec<_>>();
	let screen_name = screen_arg_name( &args );

	// Hand over to a running instance (navigate + raise) instead of opening
	// a second window.
	let instance = single_instance::claim( screen_name.as_deref() );
	let ( inbox, _bus ) = match instance
	{
		single_instance::Instance::Secondary => return,
		single_instance::Instance::Primary { inbox, conn } => ( inbox, conn ),
	};

	// Command-line flags override the persisted preference for this run.
	let pref = if args.iter().any( |a| a == "--dark"  ) { ThemePreference::Dark  }
	      else if args.iter().any( |a| a == "--light" ) { ThemePreference::Light }
	      else                                          { config::read_theme_pref() };
	use chrono::Timelike as _;
	let hour = chrono::Local::now().hour();
	let mode: ThemeMode = pref.resolve( hour );

	match ltk::ThemeDocument::find( "default" )
	{
		Ok( doc ) =>
		{
			ltk::set_active_document( doc );
			ltk::set_active_mode( mode );
			tracing::info!( "settings theme: default / {:?} (preference: {:?})", mode, pref );
		}
		Err( e ) =>
		{
			tracing::warn!(
				"default theme not loadable ({e}); falling back to embedded \
				 B/W. Install ltk-theme-default or set LTK_THEMES_DIR.",
			);
			ltk::set_active_mode( mode );
		}
	}

	let mut state = State::new();
	state.ipc_inbox = inbox;
	if let Some( screen ) = screen_name.as_deref().and_then( screen_by_name )
	{
		state.update( Msg::Open( screen ) );
	}
	ltk::run( state );
}
