use icons::Check;
use leptos::prelude::*;
use tw_merge::tw_merge;

#[component]
pub fn Checkbox(
    #[prop(into, optional)] class: String,
    #[prop(into, optional)] checked: Signal<bool>,
    #[prop(into, optional)] disabled: Signal<bool>,
    #[prop(into, optional)] on_checked_change: Option<Callback<bool>>,
    #[prop(into, optional, default = "Checkbox".to_string())] aria_label: String,
) -> impl IntoView {
    let checked_state = move || if checked.get() { "checked" } else { "unchecked" };

    let checkbox_class = tw_merge!(
        "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
        class
    );

    view! {
        <button
            data-name="Checkbox"
            class=checkbox_class
            data-state=checked_state
            type="button"
            role="checkbox"
            aria-checked=move || checked.get().to_string()
            aria-label=aria_label
            disabled=move || disabled.get()
            on:click=move |_| {
                if !disabled.get() {
                    if let Some(callback) = on_checked_change {
                        callback.run(!checked.get());
                    }
                }
            }
        >
            <span data-name="CheckboxIndicator" class="flex justify-center items-center text-current transition-none">
                {move || { checked.get().then(|| view! { <Check class="size-3.5".to_string() /> }) }}
            </span>
        </button>
    }
}