use yew::prelude::*;
use yewdux::prelude::*;

use wasm_bindgen::JsCast;
use web_sys::{EventTarget, FormData, HtmlFormElement};

use crate::components::states::MainState;
use plate_tool_lib::plate::*;
use plate_tool_lib::plate_instances::PlateInstance;

pub fn new_plate_callback(
    dispatch: Dispatch<MainState>,
    close_callback: Callback<()>,
) -> Callback<SubmitEvent> {
    Callback::from(move |e: SubmitEvent| {
        e.prevent_default();
        close_callback.emit(());
        let target: Option<EventTarget> = e.target();
        let form = target.and_then(|t| t.dyn_into::<HtmlFormElement>().ok());
        if let Some(form) = form {
            if let Ok(form_data) = FormData::new_with_form(&form) {
                let name = form_data.get("new_plate_name").as_string().unwrap();
                let format = match form_data.get("plate_format").as_string().unwrap().as_str() {
                    "6" => PlateFormat::W6,
                    "12" => PlateFormat::W12,
                    "24" => PlateFormat::W24,
                    "48" => PlateFormat::W48,
                    "96" => PlateFormat::W96,
                    "384" => PlateFormat::W384,
                    "1536" => PlateFormat::W1536,
                    "3456" => PlateFormat::W3456,
                    _ => unreachable!(),
                };
                if let Some(pt_string) = form_data.get("new_plate_type").as_string() {
                    let plate_type = match pt_string.as_str() {
                        "src" => PlateType::Source,
                        "dest" => PlateType::Destination,
                        _ => PlateType::Source,
                    };
                    dispatch.reduce_mut(|s| {
                        if plate_type == PlateType::Source {
                            s.add_source_plate(PlateInstance::new(PlateType::Source, format, name))
                        } else {
                            s.add_dest_plate(PlateInstance::new(
                                PlateType::Destination,
                                format,
                                name,
                            ))
                        }
                    });
                }
            }
        }
    })
}

pub fn onclose(close_callback: Callback<()>) -> Callback<Event> {
    Callback::from(move |_: Event| {
        close_callback.emit(());
    })
}
