use std::rc::Rc;
use uuid::Uuid;
use wasm_bindgen::JsCast;
use web_sys::{EventTarget, HtmlElement};
use yew::prelude::*;
use yewdux::prelude::*;

use crate::components::states::{CurrentTransfer, MainState};
use plate_tool_lib::transfer_region::Region;

type NoParamsCallback = Box<dyn Fn(())>;

pub fn open_plate_info_callback(
    plate_menu_id: UseStateHandle<Option<Uuid>>,
) -> Callback<MouseEvent> {
    Callback::from(move |e: MouseEvent| {
        let target: Option<EventTarget> = e.target();
        let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
        if let Some(li) = li {
            if let Ok(id) = li.id().as_str().parse::<u128>() {
                plate_menu_id.set(Some(Uuid::from_u128(id)));
            }
        }
    })
}

pub fn plate_info_close_callback(
    plate_menu_id: UseStateHandle<Option<Uuid>>,
) -> NoParamsCallback {
    Box::new(move |_| {
        plate_menu_id.set(None);
    })
}

pub fn plate_info_delete_callback(
    main_dispatch: Dispatch<MainState>,
    plate_menu_id: UseStateHandle<Option<Uuid>>,
) -> NoParamsCallback {
    Box::new(move |_| {
        if let Some(id) = *plate_menu_id {
            main_dispatch.reduce_mut(|state| {
                state.del_plate(id);
            });
        }
    })
}

pub fn source_plate_select_callback(
    main_dispatch: Dispatch<MainState>,
    ct_dispatch: Dispatch<CurrentTransfer>,
) -> Callback<MouseEvent> {
    Callback::from(move |e: MouseEvent| {
        let target: Option<EventTarget> = e.target();
        let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
        if let Some(li) = li {
            if let Ok(id) = li.id().as_str().parse::<u128>() {
                ct_dispatch.reduce_mut(|state| {
                    state.transfer.transfer_region.source_region = Region::default();
                    state.transfer.transfer_region.dest_region = Region::default();
                });
                main_dispatch.reduce_mut(|state| {
                    state.selected_source_plate = Uuid::from_u128(id);
                    state.selected_transfer = Uuid::nil();
                });
            }
        }
    })
}

pub fn destination_plate_select_callback(
    main_dispatch: Dispatch<MainState>,
    ct_dispatch: Dispatch<CurrentTransfer>,
) -> Callback<MouseEvent> {
    Callback::from(move |e: MouseEvent| {
        let target: Option<EventTarget> = e.target();
        let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
        if let Some(li) = li {
            if let Ok(id) = li.id().as_str().parse::<u128>() {
                ct_dispatch.reduce_mut(|state| {
                    state.transfer.transfer_region.source_region = Region::default();
                    state.transfer.transfer_region.dest_region = Region::default();
                });
                main_dispatch.reduce_mut(|state| {
                    state.selected_dest_plate = Uuid::from_u128(id);
                    state.selected_transfer = Uuid::nil();
                });
            }
        }
    })
}

pub fn transfer_select_callback(main_state: Rc<MainState>, main_dispatch: Dispatch<MainState>, ct_dispatch: Dispatch<CurrentTransfer>) -> Callback<MouseEvent> {
    Callback::from(move |e: MouseEvent| {
        let target: Option<EventTarget> = e.target();
        let li = target.and_then(|t| t.dyn_into::<HtmlElement>().ok());
        if let Some(li) = li {
            if let Ok(id) = li.id().as_str().parse::<u128>() {
                let id = Uuid::from_u128(id);
                if let Some(transfer) = main_state
                    .transfers
                    .iter()
                    .find(|transfer| transfer.get_uuid() == id)
                {
                    main_dispatch.reduce_mut(|state| {
                        state.selected_source_plate = transfer.source_id;
                        state.selected_dest_plate = transfer.dest_id;
                        state.selected_transfer = id;
                    });
                    ct_dispatch.reduce_mut(|state| {
                        state.transfer = transfer.clone();
                    });
                }
            }
        }
    })
}
