//! Presentation tokens for the calls UI, resolved against the active ltk
//! theme. The eydos design uses a few colours beyond ltk's eight canonical
//! palette slots (accept-green, a vivid danger red, a tertiary text level,
//! tab chips and a per-contact avatar palette). Those live as extra slots in
//! the default theme; this module reads them by name, falling back to the
//! design value when a foreign theme lacks the slot.

use ltk::{ theme_color_or, Color, Length };

/// Shortcut for [`Length::fluid`] — surface-proportional design pixel
/// calibrated against the reference width set via `ltk::set_fluid_reference`
/// (412 px for the eydos mobile reference). Was `Length::dp` before ltk
/// split the two modes; `dp` now means the constant-physical-size unit, so
/// this stays on `fluid` to preserve the original scaling behaviour.
pub fn dp( px: f32 ) -> Length
{
	Length::fluid( px )
}

const AVATAR_SLOTS: u32 = 9;

pub fn accept() -> Color
{
	theme_color_or( "accept", Color::hex( 0x00, 0xB4, 0x1A ) )
}

pub fn danger() -> Color
{
	theme_color_or( "danger", Color::hex( 0xF0, 0x00, 0x13 ) )
}

pub fn text_tertiary() -> Color
{
	theme_color_or( "text-tertiary", Color::hex( 0x80, 0x7E, 0x88 ) )
}

pub fn chip() -> Color
{
	theme_color_or( "chip", Color::hex( 0xEA, 0xE9, 0xEB ) )
}

pub fn chip_active() -> Color
{
	theme_color_or( "chip-active", Color::hex( 0x0A, 0x03, 0x2E ) )
}

pub fn chip_active_fg() -> Color
{
	theme_color_or( "chip-active-fg", Color::WHITE )
}

/// Deterministic avatar colour for a contact, hashed from a stable seed
/// (the display name) the same way the design mockup does it.
pub fn avatar_color( seed: &str ) -> Color
{
	let mut h: u32 = 0;
	for b in seed.bytes()
	{
		h = h.wrapping_mul( 31 ).wrapping_add( b as u32 );
	}
	let n = ( h % AVATAR_SLOTS ) + 1;
	theme_color_or( &format!( "avatar-{n}" ), Color::hex( 0x04, 0xD9, 0xFE ) )
}

/// Up-to-two-letter initials for an avatar bubble.
pub fn initials( name: &str ) -> String
{
	let mut letters = name
		.split_whitespace()
		.filter_map( |w| w.chars().next() );

	let text = match ( letters.next(), letters.next() )
	{
		( Some( a ), Some( b ) ) => format!( "{a}{b}" ),
		( Some( a ), None )      => a.to_string(),
		_                        => "?".to_string(),
	};
	text.to_uppercase()
}
