use calendar_models::{VAlarm, AlarmAction, AlarmTrigger};
use chrono::{Duration, DateTime, Utc, NaiveTime};
use wasm_bindgen::JsCast;
use web_sys::{HtmlSelectElement, HtmlInputElement};
use yew::prelude::*;

#[derive(Clone, PartialEq)]
pub enum TriggerType {
    Relative, // Duration before/after event
    Absolute, // Specific date/time
}

#[derive(Clone, PartialEq)]
pub enum RelativeTo {
    Start,
    End,
}

#[derive(Clone, PartialEq)]
pub enum TimeUnit {
    Minutes,
    Hours,
    Days,
    Weeks,
}

#[derive(Properties, PartialEq)]
pub struct AddAlarmModalProps {
    pub is_open: bool,
    pub editing_index: Option<usize>, // If editing an existing alarm
    pub initial_alarm: Option<VAlarm>, // For editing mode
    pub on_close: Callback<()>,
    pub on_save: Callback<VAlarm>,
}

#[function_component(AddAlarmModal)]
pub fn add_alarm_modal(props: &AddAlarmModalProps) -> Html {
    // Form state
    let trigger_type = use_state(|| TriggerType::Relative);
    let relative_to = use_state(|| RelativeTo::Start);
    let time_unit = use_state(|| TimeUnit::Minutes);
    let time_value = use_state(|| 15i32);
    let before_after = use_state(|| true); // true = before, false = after
    let absolute_date = use_state(|| chrono::Local::now().date_naive());
    let absolute_time = use_state(|| NaiveTime::from_hms_opt(9, 0, 0).unwrap());

    // Initialize form with existing alarm data if editing
    {
        let trigger_type = trigger_type.clone();
        let time_value = time_value.clone();
        
        use_effect_with(props.initial_alarm.clone(), move |initial_alarm| {
            if let Some(alarm) = initial_alarm {
                match &alarm.trigger {
                    AlarmTrigger::Duration(duration) => {
                        trigger_type.set(TriggerType::Relative);
                        let minutes = duration.num_minutes().abs();
                        time_value.set(minutes as i32);
                    }
                    AlarmTrigger::DateTime(_) => {
                        trigger_type.set(TriggerType::Absolute);
                    }
                }
            }
        });
    }

    let on_trigger_type_change = {
        let trigger_type = trigger_type.clone();
        Callback::from(move |e: Event| {
            if let Some(target) = e.target_dyn_into::<HtmlSelectElement>() {
                let new_type = match target.value().as_str() {
                    "absolute" => TriggerType::Absolute,
                    _ => TriggerType::Relative,
                };
                trigger_type.set(new_type);
            }
        })
    };


    let on_relative_to_change = {
        let relative_to = relative_to.clone();
        Callback::from(move |e: Event| {
            if let Some(target) = e.target_dyn_into::<HtmlSelectElement>() {
                let new_relative = match target.value().as_str() {
                    "end" => RelativeTo::End,
                    _ => RelativeTo::Start,
                };
                relative_to.set(new_relative);
            }
        })
    };

    let on_time_unit_change = {
        let time_unit = time_unit.clone();
        Callback::from(move |e: Event| {
            if let Some(target) = e.target_dyn_into::<HtmlSelectElement>() {
                let new_unit = match target.value().as_str() {
                    "hours" => TimeUnit::Hours,
                    "days" => TimeUnit::Days,
                    "weeks" => TimeUnit::Weeks,
                    _ => TimeUnit::Minutes,
                };
                time_unit.set(new_unit);
            }
        })
    };

    let on_time_value_change = {
        let time_value = time_value.clone();
        Callback::from(move |e: Event| {
            if let Some(target) = e.target_dyn_into::<HtmlInputElement>() {
                if let Ok(value) = target.value().parse::<i32>() {
                    time_value.set(value.max(1)); // Minimum 1
                }
            }
        })
    };

    let on_before_after_change = {
        let before_after = before_after.clone();
        Callback::from(move |e: Event| {
            if let Some(target) = e.target_dyn_into::<HtmlSelectElement>() {
                let is_before = target.value() == "before";
                before_after.set(is_before);
            }
        })
    };



    let on_save_click = {
        let trigger_type = trigger_type.clone();
        let time_unit = time_unit.clone();
        let time_value = time_value.clone();
        let before_after = before_after.clone();
        let absolute_date = absolute_date.clone();
        let absolute_time = absolute_time.clone();
        let on_save = props.on_save.clone();
        
        Callback::from(move |_| {
            // Create the alarm trigger
            let trigger = match *trigger_type {
                TriggerType::Relative => {
                    let minutes = match *time_unit {
                        TimeUnit::Minutes => *time_value,
                        TimeUnit::Hours => *time_value * 60,
                        TimeUnit::Days => *time_value * 60 * 24,
                        TimeUnit::Weeks => *time_value * 60 * 24 * 7,
                    };
                    
                    let signed_minutes = if *before_after { -minutes } else { minutes } as i64;
                    AlarmTrigger::Duration(Duration::minutes(signed_minutes))
                }
                TriggerType::Absolute => {
                    // Combine date and time to create a DateTime<Utc>
                    let naive_datetime = absolute_date.and_time(*absolute_time);
                    let utc_datetime = DateTime::from_naive_utc_and_offset(naive_datetime, Utc);
                    AlarmTrigger::DateTime(utc_datetime)
                }
            };

            // Create the VAlarm - always use Display action, no custom description
            let alarm = VAlarm {
                action: AlarmAction::Display,
                trigger,
                duration: None,
                repeat: None,
                description: None,
                summary: None,
                attendees: Vec::new(),
                attach: Vec::new(),
            };

            on_save.emit(alarm);
        })
    };

    let on_backdrop_click = {
        let on_close = props.on_close.clone();
        Callback::from(move |e: MouseEvent| {
            if let Some(target) = e.target() {
                if let Some(element) = target.dyn_ref::<web_sys::Element>() {
                    if element.class_list().contains("add-alarm-backdrop") {
                        on_close.emit(());
                    }
                }
            }
        })
    };

    if !props.is_open {
        return html! {};
    }

    html! {
        <div class="add-alarm-backdrop" onclick={on_backdrop_click}>
            <div class="add-alarm-modal">
                <div class="add-alarm-header">
                    <h3>{
                        if props.editing_index.is_some() { 
                            "Edit Reminder" 
                        } else { 
                            "Add Reminder" 
                        }
                    }</h3>
                    <button class="close-button" onclick={Callback::from({
                        let on_close = props.on_close.clone();
                        move |_| on_close.emit(())
                    })}>
                        {"×"}
                    </button>
                </div>

                <div class="add-alarm-content">
                    // Trigger Type Selection
                    <div class="form-group">
                        <label for="trigger-type">{"Trigger Type"}</label>
                        <select id="trigger-type" class="form-input" onchange={on_trigger_type_change}>
                            <option value="relative" selected={matches!(*trigger_type, TriggerType::Relative)}>
                                {"Relative to event time"}
                            </option>
                            <option value="absolute" selected={matches!(*trigger_type, TriggerType::Absolute)}>
                                {"Specific date and time"}
                            </option>
                        </select>
                    </div>

                    // Relative Trigger Configuration
                    if matches!(*trigger_type, TriggerType::Relative) {
                        <div class="form-group">
                            <label>{"When"}</label>
                            <div class="relative-time-inputs">
                                <input 
                                    type="number" 
                                    class="form-input time-value-input"
                                    value={time_value.to_string()}
                                    min="1"
                                    onchange={on_time_value_change}
                                />
                                <select class="form-input time-unit-select" onchange={on_time_unit_change}>
                                    <option value="minutes" selected={matches!(*time_unit, TimeUnit::Minutes)}>{"minute(s)"}</option>
                                    <option value="hours" selected={matches!(*time_unit, TimeUnit::Hours)}>{"hour(s)"}</option>
                                    <option value="days" selected={matches!(*time_unit, TimeUnit::Days)}>{"day(s)"}</option>
                                    <option value="weeks" selected={matches!(*time_unit, TimeUnit::Weeks)}>{"week(s)"}</option>
                                </select>
                                <select class="form-input before-after-select" onchange={on_before_after_change}>
                                    <option value="before" selected={*before_after}>{"before"}</option>
                                    <option value="after" selected={!*before_after}>{"after"}</option>
                                </select>
                                <select class="form-input relative-to-select" onchange={on_relative_to_change}>
                                    <option value="start" selected={matches!(*relative_to, RelativeTo::Start)}>{"event start"}</option>
                                    <option value="end" selected={matches!(*relative_to, RelativeTo::End)}>{"event end"}</option>
                                </select>
                            </div>
                        </div>
                    }

                    // Absolute Trigger Configuration  
                    if matches!(*trigger_type, TriggerType::Absolute) {
                        <div class="form-group">
                            <label>{"Date and Time"}</label>
                            <div class="absolute-time-inputs">
                                <input 
                                    type="date" 
                                    class="form-input"
                                    value={absolute_date.format("%Y-%m-%d").to_string()}
                                />
                                <input 
                                    type="time" 
                                    class="form-input"
                                    value={absolute_time.format("%H:%M").to_string()}
                                />
                            </div>
                        </div>
                    }


                </div>

                <div class="add-alarm-footer">
                    <button class="cancel-button" onclick={Callback::from({
                        let on_close = props.on_close.clone();
                        move |_| on_close.emit(())
                    })}>
                        {"Cancel"}
                    </button>
                    <button class="save-button" onclick={on_save_click}>
                        {if props.editing_index.is_some() { "Update" } else { "Add Reminder" }}
                    </button>
                </div>
            </div>
        </div>
    }
}