use std::process::Command;
use std::fs;

pub fn brightness() -> f32
{
	let max = read_backlight( "max_brightness" ).unwrap_or( 100.0 );
	let cur = read_backlight( "brightness" ).unwrap_or( 50.0 );
	if max > 0.0 { cur / max } else { 0.5 }
}

pub fn set_brightness( val: f32 )
{
	let pct = ( val * 100.0 ).round() as u32;
	let _ = Command::new( "brightnessctl" )
		.args( ["set", &format!( "{}%", pct )] ).output();
}

fn read_backlight( file: &str ) -> Option<f32>
{
	let base = "/sys/class/backlight";
	let entries = fs::read_dir( base ).ok()?;
	for entry in entries.flatten()
	{
		let path = entry.path().join( file );
		if let Ok( val ) = fs::read_to_string( &path )
		{
			if let Ok( n ) = val.trim().parse::<f32>() { return Some( n ); }
		}
	}
	None
}

/// Read either `charge_<field>` (mAh-class batteries) or `energy_<field>`
/// (mWh-class batteries) — drivers expose only one of the pair, but the
/// caller usually doesn't care which because the ratio is the same.
fn read_battery_metric( field: &str ) -> Option<u64>
{
	let base = "/sys/class/power_supply";
	for entry in fs::read_dir( base ).ok()?.flatten()
	{
		let typ = fs::read_to_string( entry.path().join( "type" ) ).unwrap_or_default();
		if typ.trim() != "Battery" { continue; }
		for name in [ format!( "charge_{field}" ), format!( "energy_{field}" ) ]
		{
			if let Ok( s ) = fs::read_to_string( entry.path().join( &name ) )
			{
				if let Ok( n ) = s.trim().parse::<u64>() { return Some( n ); }
			}
		}
	}
	None
}

pub fn battery_full_design() -> Option<u64> { read_battery_metric( "full_design" ) }
pub fn battery_full()        -> Option<u64> { read_battery_metric( "full" ) }

pub fn battery_cycle_count() -> Option<u32>
{
	let base = "/sys/class/power_supply";
	for entry in fs::read_dir( base ).ok()?.flatten()
	{
		let typ = fs::read_to_string( entry.path().join( "type" ) ).unwrap_or_default();
		if typ.trim() != "Battery" { continue; }
		if let Ok( s ) = fs::read_to_string( entry.path().join( "cycle_count" ) )
		{
			if let Ok( n ) = s.trim().parse::<u32>() { return Some( n ); }
		}
	}
	None
}

pub fn ac_online() -> bool
{
	let base = "/sys/class/power_supply";
	if let Ok( entries ) = fs::read_dir( base )
	{
		for entry in entries.flatten()
		{
			let typ = fs::read_to_string( entry.path().join( "type" ) ).unwrap_or_default();
			if typ.trim() != "Mains" { continue; }
			if let Ok( s ) = fs::read_to_string( entry.path().join( "online" ) )
			{
				return s.trim() == "1";
			}
		}
	}
	false
}

// ─── Power profile (power-profiles-daemon) ──────────────────────────

pub fn power_profile() -> String
{
	Command::new( "powerprofilesctl" ).arg( "get" ).output().ok()
		.and_then( |o| String::from_utf8( o.stdout ).ok() )
		.map( |s| s.trim().to_string() )
		.unwrap_or_else( || "balanced".into() )
}

pub fn set_power_profile( p: &str )
{
	let _ = Command::new( "powerprofilesctl" ).args( ["set", p] ).output();
}
