use crate::config::ChartConfig;
use crate::error::Result;
use crate::types::{Candle, Point, Viewport};

/// Adapts an external data source into the canonical types consumed by the
/// charting pipeline.
pub trait DataAdapter {
    /// Returns the data as a sequence of OHLCV candles.
    fn candles(&self) -> Result<Vec<Candle>>;

    /// Returns the data as a sequence of 2-D points (e.g. for line charts).
    fn points(&self) -> Result<Vec<Point>>;
}

/// A technical indicator that can be computed over candle data.
pub trait Indicator {
    /// Human-readable name of the indicator (e.g. "SMA(20)").
    fn name(&self) -> &str;

    /// Computes the indicator values from the given candles and returns them
    /// as a series of points suitable for overlay rendering.
    fn compute(&self, candles: &[Candle]) -> Vec<Point>;
}

/// A renderer that can draw a chart onto some output grid / buffer.
pub trait ChartRenderer {
    /// Renders chart data into the provided `grid`.
    ///
    /// The concrete type behind `grid` is renderer-specific (e.g. a 2-D
    /// character buffer). Implementations should downcast via
    /// [`Any::downcast_mut`](https://doc.rust-lang.org/std/any/trait.Any.html#method.downcast_mut).
    fn render(
        &self,
        config: &ChartConfig,
        viewport: &Viewport,
        grid: &mut dyn std::any::Any,
    ) -> Result<()>;
}
