/// Border radius scale.
///
/// Use named tokens, not raw pixel values. Swap out the RadiusScale
/// in the theme to change the visual "softness" of the entire UI at once.

/// Named border radius tokens.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Radius {
    /// 0 — sharp corners
    None,
    /// 4dp — subtle rounding (list items, small chips)
    Sm,
    /// 8dp — default card / button rounding
    Md,
    /// 12dp — more prominent rounding (modals, drawers)
    Lg,
    /// 16dp — very rounded (bottom sheets, large cards)
    Xl,
    /// 9999dp — fully pill-shaped
    Full,
    /// Explicit dp value (escape hatch)
    Custom(u32),
}

impl Radius {
    /// Resolve to dp.
    pub fn dp(&self) -> u32 {
        match self {
            Radius::None => 0,
            Radius::Sm => 4,
            Radius::Md => 8,
            Radius::Lg => 12,
            Radius::Xl => 16,
            Radius::Full => 9999,
            Radius::Custom(v) => *v,
        }
    }

    /// CSS border-radius string.
    pub fn to_css(&self) -> String {
        match self {
            Radius::Full => "9999px".to_string(),
            other => format!("{}px", other.dp()),
        }
    }
}

/// Theme-level radius scale.
#[derive(Debug, Clone)]
pub struct RadiusScale {
    pub sm: u32,
    pub md: u32,
    pub lg: u32,
    pub xl: u32,
}

impl RadiusScale {
    pub fn default() -> Self {
        Self {
            sm: 4,
            md: 8,
            lg: 12,
            xl: 16,
        }
    }

    /// Resolve a Radius token to dp using this scale.
    pub fn resolve(&self, radius: &Radius) -> u32 {
        match radius {
            Radius::None => 0,
            Radius::Sm => self.sm,
            Radius::Md => self.md,
            Radius::Lg => self.lg,
            Radius::Xl => self.xl,
            Radius::Full => 9999,
            Radius::Custom(v) => *v,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn radius_none_is_zero() {
        assert_eq!(Radius::None.dp(), 0);
    }

    #[test]
    fn radius_full_is_large() {
        assert_eq!(Radius::Full.dp(), 9999);
    }

    #[test]
    fn radius_css_full() {
        assert_eq!(Radius::Full.to_css(), "9999px");
    }

    #[test]
    fn radius_css_md() {
        assert_eq!(Radius::Md.to_css(), "8px");
    }

    #[test]
    fn radius_custom() {
        assert_eq!(Radius::Custom(20).dp(), 20);
    }

    #[test]
    fn radius_scale_default() {
        let scale = RadiusScale::default();
        assert_eq!(scale.resolve(&Radius::Md), 8);
        assert_eq!(scale.resolve(&Radius::Lg), 12);
    }
}
