//! Event handling system
//!
//! Implements R-EVENT-LOOP: Non-blocking event polling with timeout.

use anyhow::Result;
use crossterm::event::{self, Event, KeyEvent, MouseEvent};
use std::time::Duration;

/// Event that can occur in the application
#[derive(Clone, Debug)]
pub enum AppEvent {
    /// Timer tick for periodic updates
    Tick,
    /// User pressed a key
    Key(KeyEvent),
    /// User moved or clicked mouse
    Mouse(MouseEvent),
    /// Terminal was resized
    Resize(u16, u16),
}

/// Event handler for non-blocking event polling
pub struct EventHandler {
    tick_rate: Duration,
}

impl EventHandler {
    /// Create a new event handler with specified tick rate
    #[must_use]
    pub const fn new(tick_rate_ms: u64) -> Self {
        Self {
            tick_rate: Duration::from_millis(tick_rate_ms),
        }
    }

    /// Poll for next event with non-blocking timeout
    ///
    /// Returns Some(event) if an event occurred, None if timeout expired.
    /// This implements R-EVENT-LOOP: Non-blocking polling with configurable timeout.
    ///
    /// # Errors
    ///
    /// Returns an error if the operation fails
    pub fn poll(&self) -> Result<Option<AppEvent>> {
        if event::poll(self.tick_rate)? {
            match event::read()? {
                Event::Key(key) => Ok(Some(AppEvent::Key(key))),
                Event::Mouse(mouse) => Ok(Some(AppEvent::Mouse(mouse))),
                Event::Resize(width, height) => Ok(Some(AppEvent::Resize(width, height))),
                _ => Ok(None),
            }
        } else {
            Ok(Some(AppEvent::Tick))
        }
    }

    /// Update tick rate
    pub const fn set_tick_rate(&mut self, tick_rate_ms: u64) {
        self.tick_rate = Duration::from_millis(tick_rate_ms);
    }

    /// Get current tick rate
    #[must_use]
    pub const fn tick_rate(&self) -> Duration {
        self.tick_rate
    }
}

impl Default for EventHandler {
    fn default() -> Self {
        Self::new(250)
    }
}

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

    #[test]
    fn test_event_handler_default() {
        let handler = EventHandler::default();
        assert_eq!(handler.tick_rate(), Duration::from_millis(250));
    }

    #[test]
    fn test_event_handler_set_tick_rate() {
        let mut handler = EventHandler::new(100);
        handler.set_tick_rate(500);
        assert_eq!(handler.tick_rate(), Duration::from_millis(500));
    }

    #[test]
    fn test_app_event_is_copy() {
        // Ensure AppEvent is Copy (can be used multiple times without move)
        let event = AppEvent::Tick;
        let _ = event;
        let _ = event; // Can use event twice because it's Copy
    }
}
