use leptos::prelude::*;

#[component]
pub fn Dropdown<T, F, I>(
    selected: ReadSignal<T>,
    options: F,
    on_change: Callback<T>,
    display_fn: fn(&T) -> String,
    id: &'static str,
    #[prop(optional, default = false)] open_upward: bool,
) -> impl IntoView
where
    T: Clone + PartialEq + Send + Sync + 'static,
    F: Fn() -> I + Send + 'static,
    I: IntoIterator<Item = T>,
{
    let (is_open, set_is_open) = signal(false);
    
    let toggle_dropdown = move |_| {
        set_is_open.update(|open| *open = !*open);
    };
    
    view! {
        <div class="relative w-full" id=format!("{}-container", id)>
            <button 
                type="button"
                class="flex flex-row justify-between items-center p-[14px] gap-2 w-full h-[46px] bg-[var(--other-light-5)] rounded-[10px] cursor-pointer border-none"
                on:click=toggle_dropdown
                id=format!("{}-button", id)
            >
                <span class="font-semibold text-lg leading-6 tracking-tight text-[var(--main-light)]" id=format!("{}-label", id)>
                    {move || selected.with(|val| display_fn(val))}
                </span>
                <svg 
                    class="w-[22px] h-[22px] text-[var(--main-light-40)] transition-transform duration-200"
                    class:rotate-180=move || is_open.get()
                    fill="currentColor"
                    viewBox="0 0 20 20"
                    id=format!("{}-icon", id)
                >
                    <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
                </svg>
            </button>
            
            {move || is_open.get().then(|| {
                let items: Vec<_> = options().into_iter().collect();
                let items_len = items.len();
                let should_open_upward = open_upward;
                
                view! {
                    <div 
                        class=format!(
                            "absolute left-0 right-0 bg-[#2d2c2c] rounded-[10px] border border-[var(--other-light-20)] z-10 {}",
                            if should_open_upward {
                                "bottom-full mb-1"
                            } else {
                                "top-full mt-1"
                            }
                        )
                        id=format!("{}-menu", id)
                    >
                        <For 
                            each=move || items.clone().into_iter().enumerate()
                            key=|(i, _)| *i
                            children=move |(index, item)| {
                                let item_for_click = item.clone();
                                let item_for_display = item.clone();
                                let is_last = index == items_len - 1;
                                let on_change = on_change.clone();
                                
                                view! {
                                    <button 
                                        type="button"
                                        class="w-full p-[14px] text-left font-semibold text-lg text-[var(--main-light)] hover:bg-[var(--other-light-20)] transition-colors border-none bg-transparent cursor-pointer"
                                        on:click=move |_| {
                                            on_change.run(item_for_click.clone());
                                            set_is_open.set(false);
                                        }
                                        id=format!("{}-option-{}", id, index)
                                    >
                                        {display_fn(&item_for_display)}
                                    </button>
                                    {if !is_last {
                                        view! { <div class="h-px bg-[var(--other-light-20)]"></div> }.into_any()
                                    } else {
                                        view! {}.into_any()
                                    }}
                                }
                            }
                        />
                    </div>
                }
            })}
        </div>
    }
}


