//! # Shared Reference Pattern with Immutable State
//!
//! This example demonstrates implementing the `Widget` trait on a shared reference (`&Widget`)
//! with immutable state. This is the recommended pattern for most widgets in modern Ratatui
//! applications, as it allows widgets to be reused without being consumed.
//!
//! This example runs with the Ratatui library code in the branch that you are currently
//! reading. See the [`latest`] branch for the code which works with the most recent Ratatui
//! release.
//!
//! [`latest`]: https://github.com/ratatui/ratatui/tree/latest
//!
//! ## When to Use This Pattern
//!
//! - You want to reuse widgets across multiple renders
//! - Your widget doesn't need to modify its state during rendering
//! - You want the benefits of Ratatui's widget ecosystem
//! - You're building modern, efficient Ratatui applications
//!
//! ## Trade-offs
//!
//! **Pros:**
//! - Reusable - widget can be rendered multiple times without reconstruction
//! - Efficient - no cloning or reconstruction needed
//! - Standard - integrates with Ratatui's widget ecosystem
//! - Modern - follows current Ratatui best practices
//!
//! **Cons:**
//! - Immutable - cannot modify widget state during rendering
//! - External state - requires external state management for dynamic behavior
//!
//! ## Example Usage
//!
//! The widget implements `Widget for &Counter`, allowing it to be rendered by reference
//! while keeping its internal data immutable during rendering.

use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::widgets::Widget;
use ratatui_state_examples::is_exit_key_pressed;

/// Demonstrates the shared reference pattern for immutable widget rendering.
///
/// Creates a counter widget that can be rendered multiple times by reference,
/// with state updates happening outside the widget's render method.
fn main() -> color_eyre::Result<()> {
    color_eyre::install()?;
    ratatui::run(|terminal| {
        let mut counter = Counter::new();
        loop {
            terminal.draw(|frame| {
                // Widget is rendered by reference, can be reused
                frame.render_widget(&counter, frame.area());
            })?;
            // State updates happen outside of rendering
            counter.increment();
            if is_exit_key_pressed()? {
                break Ok(());
            }
        }
    })
}

/// A counter widget with immutable rendering behavior.
///
/// Implements `Widget` on a shared reference, allowing the widget to be rendered
/// multiple times without being consumed while keeping its data immutable during rendering.
struct Counter {
    count: usize,
}

impl Counter {
    /// Create a new counter.
    fn new() -> Self {
        Self { count: 0 }
    }

    /// Increment the counter value.
    ///
    /// This method modifies the counter's state outside of the rendering process,
    /// maintaining the separation between state updates and rendering.
    fn increment(&mut self) {
        self.count += 1;
    }
}

impl Widget for &Counter {
    fn render(self, area: Rect, buf: &mut Buffer) {
        // Rendering is immutable - no state changes occur here
        format!("Counter: {}", self.count).render(area, buf);
    }
}
