use crate::system;
use crate::ui::prelude::*;

const BATTERY_FULL_COLOR:   Color = Color::hex( 0x34, 0xC7, 0x59 );
const BATTERY_LOW_COLOR:    Color = Color::hex( 0xFF, 0x95, 0x00 );
const BATTERY_CRIT_COLOR:   Color = Color::hex( 0xFF, 0x3B, 0x30 );
const BATTERY_CHARGE_COLOR: Color = Color::hex( 0x00, 0x7A, 0xFF );

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

	if !state.battery_present
	{
		return column::<Msg>()
			.padding( 24.0 )
			.spacing( 16.0 )
			.push( header( &tr!( "home.battery" ) ) )
			.push( t_sec!( tr!( "battery.none_detected" ) ).size( 14.0 ).align_center() )
			.push( spacer() )
			.into();
	}

	let pct       = state.battery_pct.unwrap_or( 0 );
	let used_frac = pct as f32 / 100.0;
	let level_color =
		if state.battery_chg  { BATTERY_CHARGE_COLOR }
		else if pct >= 50     { BATTERY_FULL_COLOR    }
		else if pct >= 20     { BATTERY_LOW_COLOR     }
		else                  { BATTERY_CRIT_COLOR    };

	let status = match ( state.battery_chg, state.ac_online )
	{
		( true,  _     ) => tr!( "battery.charging" ),
		( false, true  ) => tr!( "battery.plugged_not_charging" ),
		( false, false ) => tr!( "battery.on_battery" ),
	};

	let time_line = state.battery_time_secs.map( |s|
	{
		let abs   = s.abs();
		let hours = abs / 3600;
		let mins  = ( abs % 3600 ) / 60;
		let t = if hours > 0 { format!( "{}h {}m", hours, mins ) }
		        else         { format!( "{}m", mins ) };
		if s > 0 { tr!( "battery.until_empty", t = t ) }
		else     { tr!( "battery.until_full", t = t ) }
	} );

	let mut col = column::<Msg>()
		.padding( 24.0 )
		.spacing( 12.0 )
		.push( header( &tr!( "home.battery" ) ) )
		.push( t!( format!( "{}%", pct ) ).size( 56.0 ).align_center() )
		.push( t_sec!( status ).size( 15.0 ).align_center() );

	if let Some( tl ) = time_line
	{
		col = col.push( t_sec!( tl ).size( 13.0 ).align_center() );
	}

	let bar_w = 80.0;
	let bar_h = 24.0_f32;
	col = col.push(
		row::<Msg>()
			.push( seg( used_frac         * bar_w, bar_h, level_color        ) )
			.push( seg( ( 1.0 - used_frac ) * bar_w, bar_h, palette.surface_alt ) )
	);
	let used_lbl = if state.battery_chg { tr!( "battery.charging" ) } else { tr!( "common.used" ) };
	col = col.push( legend_row(
		&used_lbl,
		&format!( "{}%", pct ),
		level_color,
	) );
	col = col.push( legend_row( &tr!( "common.free" ), &format!( "{}%", 100u8.saturating_sub( pct ) ), palette.surface_alt ) );

	// ── Power Mode ──────────────────────────────────────────────────────
	col = col.push( section_sep() );
	col = col.push( t_sec!( tr!( "battery.power_mode" ) ).size( 13.0 ) );
	col = col.push(
		row::<Msg>()
			.spacing( 6.0 )
			.push( pwr_seg( &tr!( "battery.power_save" ),  "power-saver",  &state.power_profile ) )
			.push( pwr_seg( &tr!( "battery.balanced" ),    "balanced",     &state.power_profile ) )
			.push( pwr_seg( &tr!( "battery.performance" ), "performance",  &state.power_profile ) )
	);

	// ── Alerts ──────────────────────────────────────────────────────────
	col = col.push( section_sep() );
	col = col.push( t_sec!( tr!( "battery.alerts" ) ).size( 13.0 ) );
	col = col.push( t_sec!( tr!( "battery.warn_at", val = pct_or_never( state.battery_warn_pct ) ) ).size( 13.0 ) );
	col = col.push(
		slider( system::step_norm( &system::BATTERY_WARN_STEPS, state.battery_warn_pct ) )
			.on_change( |v| Msg::PreviewBatteryWarn( system::step_at( &system::BATTERY_WARN_STEPS, v ) ) )
			.on_release( |v| Msg::SetBatteryWarn( system::step_at( &system::BATTERY_WARN_STEPS, v ) ) )
	);
	col = col.push( t_sec!( tr!( "battery.suspend_at", val = pct_or_never( state.battery_suspend_pct ) ) ).size( 13.0 ) );
	col = col.push(
		slider( system::step_norm( &system::BATTERY_SUSPEND_STEPS, state.battery_suspend_pct ) )
			.on_change( |v| Msg::PreviewBatterySuspend( system::step_at( &system::BATTERY_SUSPEND_STEPS, v ) ) )
			.on_release( |v| Msg::SetBatterySuspend( system::step_at( &system::BATTERY_SUSPEND_STEPS, v ) ) )
	);
	col = col.push( t_sec!( tr!( "battery.suspend_hint" ) ).size( 12.0 ) );

	// ── Health ──────────────────────────────────────────────────────────
	col = col.push( section_sep() );
	col = col.push( t_sec!( tr!( "battery.health" ) ).size( 13.0 ) );
	if let ( Some( design ), Some( now ) ) = ( state.battery_full_design, state.battery_full )
	{
		let ratio_pct = if design > 0 { ( now * 100 / design ) as u32 } else { 100 };
		col = col.push( t_sec!( tr!( "battery.max_capacity", pct = ratio_pct ) ).size( 13.0 ) );
		col = col.push( progress_bar( ratio_pct as f32 / 100.0 ) );
	}
	else
	{
		col = col.push( t_sec!( tr!( "battery.capacity_unavailable" ) ).size( 13.0 ) );
	}
	if let Some( c ) = state.battery_cycles
	{
		col = col.push( t_sec!( tr!( "battery.cycle_count", n = c ) ).size( 13.0 ) );
	}

	col = col.push( section_sep() );
	col = col.push(
		t_sec!( if state.ac_online { tr!( "battery.source_ac" ) } else { tr!( "battery.source_battery" ) } )
			.size( 13.0 )
	);

	col.push( spacer() ).into()
}

fn pct_or_never( pct: u32 ) -> String
{
	if pct == 0 { tr!( "common.never" ).to_string() } else { format!( "{pct}%" ) }
}

fn pwr_seg( label: &str, value: &'static str, current: &str ) -> Element<Msg>
{
	seg_btn( label, current == value, Msg::SetPowerProfile( value.to_string() ) )
}
