use cvkg_core::{View, Never};
use crate::Color;

/// Button with action callback
#[allow(dead_code)]
pub struct Button<F> where F: Fn() {
    pub(crate) label: String,
    pub(crate) on_click: F,
}

impl<F> Button<F> where F: Fn() {
    /// Create a new Button with a label and an action callback.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Button;
    /// let btn = Button::new("Submit", || println!("Clicked"));
    /// ```
    pub fn new(label: impl Into<String>, on_click: F) -> Self {
        Self {
            label: label.into(),
            on_click,
        }
    }
}

impl<F> View for Button<F> where F: Fn() + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Toggle switch
#[allow(dead_code)]
pub struct Toggle<F> where F: Fn(bool) {
    pub(crate) label: String,
    pub(crate) is_on: bool,
    pub(crate) on_change: F,
}

impl<F> Toggle<F> where F: Fn(bool) {
    /// Create a new Toggle switch.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Toggle;
    /// let toggle = Toggle::new("Enable feature", false, |val| println!("Toggled: {}", val));
    /// ```
    pub fn new(label: impl Into<String>, is_on: bool, on_change: F) -> Self {
        Self {
            label: label.into(),
            is_on,
            on_change,
        }
    }
}

impl<F> View for Toggle<F> where F: Fn(bool) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Slider for continuous value selection
#[allow(dead_code)]
pub struct Slider<F> where F: Fn(f32) {
    pub(crate) value: f32,
    pub(crate) range: std::ops::RangeInclusive<f32>,
    pub(crate) on_change: F,
}

impl<F> Slider<F> where F: Fn(f32) {
    /// Create a new Slider.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Slider;
    /// let slider = Slider::new(0.5, 0.0..=1.0, |val| println!("Value: {}", val));
    /// ```
    pub fn new(value: f32, range: std::ops::RangeInclusive<f32>, on_change: F) -> Self {
        Self { value, range, on_change }
    }
}

impl<F> View for Slider<F> where F: Fn(f32) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Stepper for discrete increment/decrement
#[allow(dead_code)]
pub struct Stepper<F> where F: Fn(i32) {
    pub(crate) label: String,
    pub(crate) value: i32,
    pub(crate) on_change: F,
}

impl<F> Stepper<F> where F: Fn(i32) {
    /// Create a new Stepper.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Stepper;
    /// let stepper = Stepper::new("Count", 0, |val| println!("Count: {}", val));
    /// ```
    pub fn new(label: impl Into<String>, value: i32, on_change: F) -> Self {
        Self { label: label.into(), value, on_change }
    }
}

impl<F> View for Stepper<F> where F: Fn(i32) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Single-line text input
#[allow(dead_code)]
pub struct TextField<F> where F: Fn(String) {
    pub(crate) placeholder: String,
    pub(crate) text: String,
    pub(crate) on_change: F,
}

impl<F> TextField<F> where F: Fn(String) {
    /// Create a new TextField.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::TextField;
    /// let field = TextField::new("Enter name", "", |t| println!("Name: {}", t));
    /// ```
    pub fn new(placeholder: impl Into<String>, text: impl Into<String>, on_change: F) -> Self {
        Self { placeholder: placeholder.into(), text: text.into(), on_change }
    }
}

impl<F> View for TextField<F> where F: Fn(String) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Secure password input
#[allow(dead_code)]
pub struct SecureField<F> where F: Fn(String) {
    pub(crate) placeholder: String,
    pub(crate) text: String,
    pub(crate) on_change: F,
}

impl<F> SecureField<F> where F: Fn(String) {
    /// Create a new SecureField.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::SecureField;
    /// let field = SecureField::new("Password", "", |_| {});
    /// ```
    pub fn new(placeholder: impl Into<String>, text: impl Into<String>, on_change: F) -> Self {
        Self { placeholder: placeholder.into(), text: text.into(), on_change }
    }
}

impl<F> View for SecureField<F> where F: Fn(String) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Multi-line text area
#[allow(dead_code)]
pub struct TextEditor<F> where F: Fn(String) {
    pub(crate) text: String,
    pub(crate) on_change: F,
}

impl<F> TextEditor<F> where F: Fn(String) {
    /// Create a new TextEditor.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::TextEditor;
    /// let editor = TextEditor::new("Initial body", |t| {});
    /// ```
    pub fn new(text: impl Into<String>, on_change: F) -> Self {
        Self { text: text.into(), on_change }
    }
}

impl<F> View for TextEditor<F> where F: Fn(String) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// Picker for selection from a list of options
#[allow(dead_code)]
pub struct Picker<F> where F: Fn(usize) {
    pub(crate) selection: usize,
    pub(crate) options: Vec<String>,
    pub(crate) on_change: F,
}

impl<F> Picker<F> where F: Fn(usize) {
    /// Create a new Picker.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::Picker;
    /// let picker = Picker::new(0, vec!["A".into(), "B".into()], |i| {});
    /// ```
    pub fn new(selection: usize, options: Vec<String>, on_change: F) -> Self {
        Self { selection, options, on_change }
    }
}

impl<F> View for Picker<F> where F: Fn(usize) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// DatePicker for calendar date selection
#[allow(dead_code)]
pub struct DatePicker<F> where F: Fn(u64) {
    pub(crate) timestamp: u64,
    pub(crate) on_change: F,
}

impl<F> DatePicker<F> where F: Fn(u64) {
    /// Create a new DatePicker.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::DatePicker;
    /// let date_picker = DatePicker::new(1682855100, |t| {});
    /// ```
    pub fn new(timestamp: u64, on_change: F) -> Self {
        Self { timestamp, on_change }
    }
}

impl<F> View for DatePicker<F> where F: Fn(u64) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}

/// ColorPicker for RGBA color selection
#[allow(dead_code)]
pub struct ColorPicker<F> where F: Fn(Color) {
    pub(crate) color: Color,
    pub(crate) on_change: F,
}

impl<F> ColorPicker<F> where F: Fn(Color) {
    /// Create a new ColorPicker.
    ///
    /// # Examples
    /// ```
    /// use cvkg_components::{ColorPicker, Color};
    /// let color_picker = ColorPicker::new(Color::BLACK, |c| {});
    /// ```
    pub fn new(color: Color, on_change: F) -> Self {
        Self { color, on_change }
    }
}

impl<F> View for ColorPicker<F> where F: Fn(Color) + Send {
    type Body = Never;
    fn body(self) -> Self::Body { unreachable!() }
}
