//! Configuration types for chunked data processing.
//!
//! ## Purpose
//!
//! This module provides configuration types used by the streaming and online
//! adapters to control how data is processed in chunks. These types define
//! policies for boundary handling, overlap merging, and update modes.
//!
//! ## Design notes
//!
//! * Configuration types are simple enums with clear semantics.
//! * Each type provides sensible defaults for common use cases.
//! * All types implement standard traits (Debug, Clone, Copy, PartialEq, Eq).
//! * Documentation includes usage recommendations for each variant.
//!
//! ## Configuration Types
//!
//! ### BoundaryPolicy
//! Controls how edge points are handled when there's insufficient context
//! for smoothing at the start and end of data streams.
//!
//! ### MergeStrategy
//! Defines how smoothed values from different chunks are combined in
//! overlapping regions to ensure smooth transitions.
//!
//! ### UpdateMode
//! Specifies how the sliding window is re-smoothed when new points arrive
//! in online/streaming mode, trading off accuracy for speed.
//!
//! ## Visibility
//!
//! All configuration types ([`BoundaryPolicy`], [`MergeStrategy`],
//! [`UpdateMode`]) are part of the public API and are re-exported
//! through the prelude for convenient access.

// ============================================================================
// Configuration Types
// ============================================================================

/// Policy for handling boundaries at the start and end of the data stream.
///
/// Controls how edge points are handled when there's insufficient context
/// for smoothing. Different policies are appropriate for different data
/// characteristics.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum BoundaryPolicy {
    /// Extend the first/last values to fill neighborhoods.
    ///
    /// Replicates edge values to provide context for boundary points.
    /// This is the most common choice and works well for most data.
    ///
    /// **Best for**: Monotonic trends, time series with stable endpoints,
    /// general-purpose smoothing.
    ///
    /// **Example**: `[1, 2, 3]` → `[1, 1, 2, 3, 3, 3]` (with padding)
    #[default]
    Extend,

    /// Reflect values around the boundary.
    ///
    /// Mirrors values across the boundary to create symmetric context.
    /// Useful when data has natural symmetry or periodicity.
    ///
    /// **Best for**: Periodic or symmetric data, signal processing.
    ///
    /// **Example**: `[1, 2, 3]` → `[2, 1, 1, 2, 3, 3, 2]` (with reflection)
    Reflect,

    /// Use zero padding at boundaries.
    ///
    /// No extrapolation beyond data boundaries. Points near edges use
    /// fewer neighbors or are padded with zeros.
    ///
    /// **Best for**: Data known to approach zero at boundaries, sparse data.
    ///
    /// **Example**: `[1, 2, 3]` → `[0, 0, 1, 2, 3, 0, 0]` (with padding)
    Zero,
}

/// Strategy for merging overlapping regions between chunks.
///
/// Controls how smoothed values from different chunks are combined in
/// overlapping regions. The choice affects smoothness and accuracy at
/// chunk boundaries.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MergeStrategy {
    /// Simple average of overlapping smoothed values.
    ///
    /// Computes the arithmetic mean of values from both chunks.
    ///
    /// **Formula**: `(v1 + v2) / 2`
    ///
    /// **Best for**: Chunks with similar quality, uniform data density.
    Average,

    /// Weighted average favoring the chunk center.
    ///
    /// Uses distance-based weights that favor values from the center of
    /// each chunk, where smoothing is most accurate. This is the default
    /// and recommended strategy for most use cases.
    ///
    /// **Formula**: `v1·(1-α) + v2·α` where `α = position / overlap_length`
    ///
    /// **Best for**: General use, minimizing boundary artifacts, smooth transitions.
    #[default]
    WeightedAverage,

    /// Take the value from the first chunk in processing order.
    ///
    /// No blending; simply uses the first chunk's value in overlap regions.
    ///
    /// **Best for**: When first chunk is known to be more reliable,
    /// debugging, fastest processing.
    TakeFirst,

    /// Take the value from the last chunk in processing order.
    ///
    /// No blending; simply uses the last chunk's value in overlap regions.
    ///
    /// **Best for**: When later chunks are known to be more reliable,
    /// sequential processing.
    TakeLast,
}

/// Update mode for online LOWESS.
///
/// Controls how the sliding window is re-smoothed when new points arrive
/// in online/streaming mode. Trades off accuracy for speed.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum UpdateMode {
    /// Recompute smooth for all points in window.
    ///
    /// When a new point arrives, the entire window is re-smoothed from
    /// scratch. This is the most accurate but slowest option.
    ///
    /// **Complexity**: O(window_size²) per update
    ///
    /// **Best for**: High accuracy requirements, small windows, infrequent updates.
    Full,

    /// Only compute smooth for the new point.
    ///
    /// When a new point arrives, only that point is smoothed using the
    /// current window. Previous points retain their smoothed values.
    /// This is faster but less accurate as the window evolves.
    ///
    /// **Complexity**: O(window_size) per update
    ///
    /// **Best for**: Real-time processing, large windows, frequent updates.
    #[default]
    Incremental,
}
