use super::icons::Icon;
use crate::components::outlined_box::OutlinedBox;
use crate::gradient::Gradient;
use leptos::prelude::*;

#[component]
pub fn Button(
    #[prop(into, optional)] icon: MaybeProp<Icon>,

    #[prop(into, optional)] text: MaybeProp<String>,

    #[prop(optional)] color: Gradient,

    #[prop(into, optional)] highlight: MaybeProp<bool>,

    #[prop(into, optional)] disabled: MaybeProp<bool>,

    #[prop(into, optional)] on_click: MaybeProp<Callback<()>>,
) -> impl IntoView {
    let margin = "mx-2 my-1 sm:mx-5 sm:my-2.5";

    let icon_view = move || {
        icon.get().map(|i| {
            let icon_view = i.into_view();
            let mut classes = "self-center".to_string();
            classes.push(' ');
            classes.push_str(margin);
            classes.push(' ');
            classes.push_str(color.class_text());

            view! { <div class=classes>{icon_view}</div> }
        })
    };

    let separator = move || {
        (icon.read().is_some() && text.read().is_some()).then(|| {
            let mut classes = "w-0.5 bg-linear-to-br min-w-0.5".to_string();
            classes.push(' ');
            classes.push_str(color.class_from());
            classes.push(' ');
            classes.push_str(color.class_to());

            view! { <div class=classes /> }
        })
    };

    let text_view = move || {
        text.get().map(|text| {
            let mut classes = "self-center uppercase w-full text-sm sm:text-base md:text-lg font-thin".to_string();
            classes.push(' ');
            classes.push_str(margin);

            view! { <div class=classes>{text}</div> }
        })
    };

    let class = move || {
        let mut classes = vec![];
        if disabled.get().unwrap_or_default() {
            classes.extend(["brightness-50"]);
        } else {
            classes.extend(["cursor-pointer", "hover:brightness-125", "active:brightness-90"]);
        }
        classes.join(" ")
    };

    let on_click = move |_| {
        if let Some(cb) = on_click.get() {
            cb.run(());
        }
    };

    let prop_disabled = move || disabled.get();

    view! {
        <button type="button" class=class prop:disabled=prop_disabled on:click=on_click>
            <OutlinedBox color highlight>
                <div class="flex items-stretch">{icon_view} {separator} {text_view}</div>
            </OutlinedBox>
        </button>
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn baseline() {
        let text = "foo";
        let onclick = |_| {};

        view! { <Button text on:click=onclick /> };
    }

    #[test]
    fn simple() {
        let icon = Icon::ForwardSolid;
        let text = "foo";
        let onclick = |_| {};

        view! { <Button icon text on:click=onclick /> };
    }
}
