use cvkg_core::{View, Never, Renderer, Rect};
use crate::{Color, FontWeight, Orientation};

/// Text view for displaying strings
#[allow(dead_code)]
pub struct Text {
    pub(crate) content: String,
    pub(crate) font_size: f32,
    pub(crate) font_weight: FontWeight,
    pub(crate) color: Color,
}

impl Text {
    /// Create a new Text component with the given content.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Text;
    /// let label = Text::new("Hello World");
    /// ```
    pub fn new(content: impl Into<String>) -> Self {
        Self {
            content: content.into(),
            font_size: 14.0,
            font_weight: FontWeight::Regular,
            color: Color::BLACK,
        }
    }
}

impl View for Text {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
    
    fn render(&self, renderer: &mut dyn Renderer, rect: Rect) {
        renderer.draw_text(&self.content, rect.x, rect.y, self.font_size, self.color.as_array());
    }
}


/// Divider for separating content
#[allow(dead_code)]
pub struct Divider {
    pub(crate) orientation: Orientation,
    pub(crate) width: f32,
    pub(crate) color: Color,
}

impl Divider {
    /// Create a horizontal Divider.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Divider;
    /// let div = Divider::horizontal();
    /// ```
    pub fn horizontal() -> Self {
        Self {
            orientation: Orientation::Horizontal,
            width: 1.0,
            color: Color::BLACK,
        }
    }
}

impl View for Divider {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Spacer for flexible layout gaps
#[allow(dead_code)]
pub struct Spacer {
    pub(crate) min_length: f32,
}

impl Spacer {
    /// Create a new Spacer with a minimum length.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Spacer;
    /// let spacer = Spacer::new(10.0);
    /// ```
    pub fn new(min_length: f32) -> Self {
        Self { min_length }
    }
}

impl View for Spacer {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Canvas for custom drawing
#[allow(dead_code)]
pub struct Canvas<F> where F: Fn(&mut dyn std::any::Any) {
    pub(crate) draw_func: F,
}

impl<F> Canvas<F> where F: Fn(&mut dyn std::any::Any) {
    /// Create a new Canvas with a drawing closure.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Canvas;
    /// let canvas = Canvas::new(|_ctx| {});
    /// ```
    pub fn new(draw_func: F) -> Self {
        Self { draw_func }
    }
}

impl<F> View for Canvas<F> where F: Fn(&mut dyn std::any::Any) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Shape types for drawing primitives
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ShapeType {
    Rectangle,
    Circle,
    RoundedRectangle { corner_radius: f32 },
}

/// A standard vector Shape
#[allow(dead_code)]
pub struct Shape {
    pub(crate) shape_type: ShapeType,
    pub(crate) fill: Color,
}

impl Shape {
    /// Create a new rounded rectangle Shape.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Shape;
    /// let rect = Shape::rounded_rect(8.0);
    /// ```
    pub fn rounded_rect(corner_radius: f32) -> Self {
        Self {
            shape_type: ShapeType::RoundedRectangle { corner_radius },
            fill: Color::BLACK,
        }
    }
}

impl View for Shape {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }

    fn render(&self, renderer: &mut dyn Renderer, rect: Rect) {
        match self.shape_type {
            ShapeType::Rectangle => renderer.fill_rect(rect, self.fill.as_array()),
            ShapeType::RoundedRectangle { corner_radius } => {
                renderer.fill_rounded_rect(rect, corner_radius, self.fill.as_array());
            }
            ShapeType::Circle => {
                let radius = rect.width.min(rect.height) / 2.0;
                renderer.fill_rounded_rect(rect, radius, self.fill.as_array());
            }
        }
    }
}

