use std::{
    collections::HashMap,
    fmt::Display,
    hash::Hash,
};
use dioxus::prelude::*;
use crate::{
    ButtonProps,
    InputMode,
    InputProps,
};
type SubmitCallback<Id> = Box<dyn Fn(&HashMap<Id, String>)>;
#[derive(Clone)]
pub struct UseForm<Id: Hash + Eq + 'static> {
    data: Signal<HashMap<Id, String>>,
    onsubmit: Signal<SubmitCallback<Id>>,
}
impl<Id: Clone + Hash + Eq + Display> UseForm<Id> {
    pub fn input(&self, id: Id) -> InputProps {
        let value = self.data.read().get(&id).cloned().unwrap_or_default();
        let placeholder = id.to_string();
        let mut data = self.data;
        InputProps {
            onchange: EventHandler::new(move |txt| {
                data.write().insert(id.clone(), txt);
            }),
            theme: None,
            mode: InputMode::default(),
            value,
            placeholder: Some(placeholder),
            auto_focus: false,
        }
    }
    pub fn submit(&self) -> ButtonProps {
        let submit = self.onsubmit;
        let data = self.data;
        ButtonProps {
            theme: None,
            onpress: Some(EventHandler::new(move |_| {
                (submit.peek())(&data.read());
            })),
            children: None,
            onclick: None,
        }
    }
}
pub fn use_form<Id: Hash + Eq + Clone>(
    onsubmit: impl Fn(&HashMap<Id, String>) + 'static,
) -> UseForm<Id> {
    use_hook(|| UseForm {
        data: Signal::new(HashMap::default()),
        onsubmit: Signal::new(Box::new(onsubmit)),
    })
}