/// Platform-aware sizing constants.
///
/// Platform HIG minimum touch targets, safe area handling, and
/// density-independent pixel conventions.

/// Which platform family the app is running on.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PlatformFamily {
    /// iOS / iPadOS
    Ios,
    /// Android
    Android,
    /// macOS
    Macos,
    /// Windows
    Windows,
    /// Linux desktop
    Linux,
    /// Web browser
    Web,
}

/// Platform-specific sizing constants.
#[derive(Debug, Clone)]
pub struct PlatformSizing {
    /// Minimum touch target dimension in dp (height and width).
    pub min_touch_target: f32,
    /// Standard icon size in dp.
    pub icon_size: f32,
    /// Standard small icon size in dp.
    pub icon_size_sm: f32,
    /// Standard navigation bar height in dp.
    pub nav_bar_height: f32,
    /// Standard tab bar height in dp.
    pub tab_bar_height: f32,
    /// Standard status bar height in dp (approximate; actual is platform-provided).
    pub status_bar_height: f32,
}

impl PlatformSizing {
    /// Sizing constants for a given platform.
    pub fn for_platform(platform: PlatformFamily) -> Self {
        match platform {
            PlatformFamily::Ios => Self {
                min_touch_target: 44.0,  // Apple HIG
                icon_size: 24.0,
                icon_size_sm: 16.0,
                nav_bar_height: 44.0,
                tab_bar_height: 49.0,
                status_bar_height: 44.0, // approximate; varies with notch
            },
            PlatformFamily::Android => Self {
                min_touch_target: 48.0,  // Material Design
                icon_size: 24.0,
                icon_size_sm: 18.0,
                nav_bar_height: 56.0,
                tab_bar_height: 56.0,
                status_bar_height: 24.0,
            },
            PlatformFamily::Macos => Self {
                min_touch_target: 44.0,  // macOS HIG
                icon_size: 16.0,
                icon_size_sm: 12.0,
                nav_bar_height: 28.0,
                tab_bar_height: 36.0,
                status_bar_height: 0.0,  // macOS status bar is system chrome
            },
            PlatformFamily::Windows => Self {
                min_touch_target: 44.0,
                icon_size: 16.0,
                icon_size_sm: 12.0,
                nav_bar_height: 40.0,
                tab_bar_height: 40.0,
                status_bar_height: 0.0,
            },
            PlatformFamily::Linux => Self {
                min_touch_target: 44.0,
                icon_size: 16.0,
                icon_size_sm: 12.0,
                nav_bar_height: 36.0,
                tab_bar_height: 36.0,
                status_bar_height: 0.0,
            },
            PlatformFamily::Web => Self {
                min_touch_target: 44.0,  // WCAG 2.5.5 recommended
                icon_size: 20.0,
                icon_size_sm: 16.0,
                nav_bar_height: 64.0,
                tab_bar_height: 48.0,
                status_bar_height: 0.0,
            },
        }
    }

    /// Is the given width adequate for a touch target?
    pub fn is_touch_adequate(&self, width: f32, height: f32) -> bool {
        width >= self.min_touch_target && height >= self.min_touch_target
    }
}

/// Safe area insets — space reserved by system chrome.
///
/// These are provided at runtime by the platform. The values here
/// are conservative defaults for simulation.
#[derive(Debug, Clone, Copy, Default)]
pub struct SafeAreaInsets {
    pub top: f32,
    pub right: f32,
    pub bottom: f32,
    pub left: f32,
}

impl SafeAreaInsets {
    /// No safe area insets (desktop platforms).
    pub fn none() -> Self {
        Self::default()
    }

    /// Typical iPhone safe area (notch at top, home indicator at bottom).
    pub fn iphone_notch() -> Self {
        Self {
            top: 44.0,
            right: 0.0,
            bottom: 34.0,
            left: 0.0,
        }
    }

    /// Dynamic island (iPhone 14 Pro+).
    pub fn iphone_dynamic_island() -> Self {
        Self {
            top: 59.0,
            right: 0.0,
            bottom: 34.0,
            left: 0.0,
        }
    }

    /// Total horizontal safe area.
    pub fn horizontal(&self) -> f32 {
        self.left + self.right
    }

    /// Total vertical safe area.
    pub fn vertical(&self) -> f32 {
        self.top + self.bottom
    }
}

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

    #[test]
    fn ios_min_touch_target() {
        let sizing = PlatformSizing::for_platform(PlatformFamily::Ios);
        assert_eq!(sizing.min_touch_target, 44.0);
    }

    #[test]
    fn android_min_touch_target() {
        let sizing = PlatformSizing::for_platform(PlatformFamily::Android);
        assert_eq!(sizing.min_touch_target, 48.0);
    }

    #[test]
    fn touch_adequate_check() {
        let sizing = PlatformSizing::for_platform(PlatformFamily::Ios);
        assert!(sizing.is_touch_adequate(44.0, 44.0));
        assert!(!sizing.is_touch_adequate(40.0, 44.0));
        assert!(!sizing.is_touch_adequate(44.0, 40.0));
    }

    #[test]
    fn safe_area_horizontal() {
        let sa = SafeAreaInsets {
            top: 44.0,
            right: 16.0,
            bottom: 34.0,
            left: 16.0,
        };
        assert_eq!(sa.horizontal(), 32.0);
    }

    #[test]
    fn safe_area_vertical() {
        let sa = SafeAreaInsets::iphone_notch();
        assert_eq!(sa.vertical(), 78.0);
    }

    #[test]
    fn no_safe_area_is_zero() {
        let sa = SafeAreaInsets::none();
        assert_eq!(sa.horizontal(), 0.0);
        assert_eq!(sa.vertical(), 0.0);
    }
}
