use crate::components::{
    CalendarContextMenu, CalendarManagementModal, ColorEditorModal, ContextMenu, CreateEventModal, DeleteAction,
    EditAction, EventContextMenu, EventModal, EventCreationData,  
    MobileWarningModal, RouteHandler, Sidebar, Theme, ViewMode,
};
use crate::components::mobile_warning_modal::is_mobile_device;
use crate::components::sidebar::{Style};
use crate::models::ical::VEvent;
use crate::services::{calendar_service::{UserInfo, ExternalCalendar}, CalendarService, AlarmScheduler};
use chrono::NaiveDate;
use gloo_storage::{LocalStorage, Storage};
use gloo_timers::callback::Interval;
use wasm_bindgen::JsCast;
use web_sys::MouseEvent;
use yew::prelude::*;
use yew_router::prelude::*;

fn get_default_event_colors() -> Vec<String> {
    vec![
        "#3B82F6".to_string(), // Blue
        "#10B981".to_string(), // Emerald
        "#F59E0B".to_string(), // Amber
        "#EF4444".to_string(), // Red
        "#8B5CF6".to_string(), // Violet
        "#06B6D4".to_string(), // Cyan
        "#84CC16".to_string(), // Lime
        "#F97316".to_string(), // Orange
        "#EC4899".to_string(), // Pink
        "#6366F1".to_string(), // Indigo
        "#14B8A6".to_string(), // Teal
        "#F3B806".to_string(), // Yellow
        "#8B5A2B".to_string(), // Brown
        "#6B7280".to_string(), // Gray
        "#DC2626".to_string(), // Dark Red
        "#7C3AED".to_string(), // Purple
    ]
}

fn get_event_colors_from_preferences() -> Vec<String> {
    // Try to load custom colors from user preferences
    if let Some(prefs) = crate::services::preferences::PreferencesService::load_cached() {
        if let Some(colors_json) = prefs.calendar_colors {
            // Try to parse the JSON structure
            if let Ok(colors_data) = serde_json::from_str::<serde_json::Value>(&colors_json) {
                // Check if it has a custom_palette field
                if let Some(custom_palette) = colors_data.get("custom_palette") {
                    if let Some(colors_array) = custom_palette.as_array() {
                        let custom_colors: Vec<String> = colors_array
                            .iter()
                            .filter_map(|v| v.as_str().map(|s| s.to_string()))
                            .collect();
                        
                        // Only use custom colors if we have a reasonable number
                        if custom_colors.len() >= 8 {
                            return custom_colors;
                        }
                    }
                }
            }
        }
    }
    
    // Fall back to default colors
    get_default_event_colors()
}

async fn save_custom_colors_to_preferences(colors: Vec<String>) -> Result<(), String> {
    // Create the JSON structure for storing custom colors
    let colors_json = serde_json::json!({
        "custom_palette": colors
    });
    
    // Convert to string for preferences storage
    let colors_string = serde_json::to_string(&colors_json)
        .map_err(|e| format!("Failed to serialize colors: {}", e))?;
    
    // Update preferences via the preferences service
    let preferences_service = crate::services::preferences::PreferencesService::new();
    preferences_service.update_preference("calendar_colors", serde_json::Value::String(colors_string)).await
}

#[function_component]
pub fn App() -> Html {
    let auth_token = use_state(|| -> Option<String> { None });

    // Validate token on app startup
    {
        let auth_token = auth_token.clone();
        use_effect_with((), move |_| {
            let auth_token = auth_token.clone();
            wasm_bindgen_futures::spawn_local(async move {
                // Check if there's a stored token
                if let Ok(stored_token) = LocalStorage::get::<String>("auth_token") {
                    // Verify the stored token
                    let auth_service = crate::auth::AuthService::new();
                    match auth_service.verify_token(&stored_token).await {
                        Ok(true) => {
                            // Token is valid, set it
                            auth_token.set(Some(stored_token));
                        }
                        _ => {
                            // Token is invalid or verification failed, clear it
                            web_sys::console::log_1(&"❌ Stored auth token is invalid, clearing".into());
                            let _ = LocalStorage::delete("auth_token");
                            let _ = LocalStorage::delete("session_token");
                            let _ = LocalStorage::delete("caldav_credentials");
                            auth_token.set(None);
                        }
                    }
                } else {
                    // No stored token
                    web_sys::console::log_1(&"ℹ️ No stored auth token found".into());
                    auth_token.set(None);
                }
            });
            || ()
        });
    }

    let user_info = use_state(|| -> Option<UserInfo> { None });
    let color_picker_open = use_state(|| -> Option<String> { None });
    let calendar_management_modal_open = use_state(|| false);
    let context_menu_open = use_state(|| false);
    let color_editor_open = use_state(|| false);
    let color_editor_data = use_state(|| -> Option<(usize, String)> { None }); // (index, current_color)
    let context_menu_pos = use_state(|| (0i32, 0i32));
    let context_menu_calendar_path = use_state(|| -> Option<String> { None });
    let event_context_menu_open = use_state(|| false);
    let event_context_menu_pos = use_state(|| (0i32, 0i32));
    let event_context_menu_event = use_state(|| -> Option<VEvent> { None });
    let calendar_context_menu_open = use_state(|| false);
    let calendar_context_menu_pos = use_state(|| (0i32, 0i32));
    let calendar_context_menu_date = use_state(|| -> Option<NaiveDate> { None });
    let create_event_modal_open = use_state(|| false);
    let selected_date_for_event = use_state(|| -> Option<NaiveDate> { None });
    let event_edit_scope = use_state(|| -> Option<EditAction> { None });
    let view_event_modal_open = use_state(|| false);
    let view_event_modal_event = use_state(|| -> Option<VEvent> { None });
    let refreshing_calendar_id = use_state(|| -> Option<i32> { None });
    let _recurring_edit_modal_open = use_state(|| false);
    let _recurring_edit_event = use_state(|| -> Option<VEvent> { None });
    let _recurring_edit_data = use_state(|| -> Option<EventCreationData> { None });
    
    // External calendar state
    let external_calendars = use_state(|| -> Vec<ExternalCalendar> { Vec::new() });
    let external_calendar_events = use_state(|| -> Vec<VEvent> { Vec::new() });
    
    // Mobile warning state
    let mobile_warning_open = use_state(|| is_mobile_device());
    let refresh_interval = use_state(|| -> Option<Interval> { None });
    
    // Alarm system state
    let alarm_scheduler = use_state(|| AlarmScheduler::new());
    let alarm_check_interval = use_state(|| -> Option<Interval> { None });
    let alarm_system_initialized = use_state(|| false);

    // Calendar view state - load from localStorage if available
    let current_view = use_state(|| {
        // Try to load saved view mode from localStorage
        if let Ok(saved_view) = LocalStorage::get::<String>("calendar_view_mode") {
            match saved_view.as_str() {
                "week" => ViewMode::Week,
                _ => ViewMode::Month,
            }
        } else {
            ViewMode::Month // Default to month view
        }
    });

    // Theme state - load from localStorage if available
    let current_theme = use_state(|| {
        // Try to load saved theme from localStorage
        if let Ok(saved_theme) = LocalStorage::get::<String>("calendar_theme") {
            Theme::from_value(&saved_theme)
        } else {
            Theme::Default // Default theme
        }
    });

    // Style state - load from localStorage if available
    let current_style = use_state(|| {
        // Try to load saved style from localStorage
        if let Ok(saved_style) = LocalStorage::get::<String>("calendar_style") {
            Style::from_value(&saved_style)
        } else {
            Style::Default // Default style
        }
    });

    let available_colors = use_state(|| get_event_colors_from_preferences());
    
    // Refresh colors when preferences might have changed
    let refresh_colors = {
        let available_colors = available_colors.clone();
        Callback::from(move |_| {
            available_colors.set(get_event_colors_from_preferences());
        })
    };

    // Initialize alarm system after user login
    {
        let auth_token = auth_token.clone();
        let alarm_scheduler = alarm_scheduler.clone();
        let alarm_system_initialized = alarm_system_initialized.clone();
        let alarm_check_interval = alarm_check_interval.clone();
        
        use_effect_with((*auth_token).clone(), move |token| {
            if token.is_some() && !*alarm_system_initialized {
                
                let alarm_scheduler = alarm_scheduler.clone();
                let alarm_system_initialized = alarm_system_initialized.clone();
                let alarm_check_interval = alarm_check_interval.clone();
                
                wasm_bindgen_futures::spawn_local(async move {
                    // Request notification permission
                    let scheduler = (*alarm_scheduler).clone();
                    match scheduler.request_notification_permission().await {
                        Ok(_permission) => {
                        }
                        Err(e) => {
                            web_sys::console::warn_1(
                                &format!("⚠️ Failed to request notification permission: {:?}", e).into()
                            );
                        }
                    }
                    
                    alarm_scheduler.set(scheduler);
                    alarm_system_initialized.set(true);
                    
                    // Set up alarm checking interval (every 30 seconds)
                    let interval = {
                        let alarm_scheduler_ref = alarm_scheduler.clone();
                        Interval::new(30_000, move || {
                            // Get a fresh copy of the current scheduler state each time
                            let mut scheduler = (*alarm_scheduler_ref).clone();
                            let triggered_count = scheduler.check_and_trigger_alarms();
                            
                            if triggered_count > 0 {
                                web_sys::console::log_1(
                                    &format!("🔔 Triggered {} alarm(s)", triggered_count).into()
                                );
                            }
                            
                            // Update the scheduler state with any changes (like alarm status updates)
                            alarm_scheduler_ref.set(scheduler);
                        })
                    };
                    
                    alarm_check_interval.set(Some(interval));
                });
            } else if token.is_none() {
                // Clean up alarm system on logout
                alarm_check_interval.set(None); // This will drop and cancel the interval
                alarm_system_initialized.set(false);
            }
            
            || ()
        });
    }

    // Function to refresh calendar data without full page reload
    let refresh_calendar_data = {
        let user_info = user_info.clone();
        let auth_token = auth_token.clone();
        let external_calendars = external_calendars.clone();
        let external_calendar_events = external_calendar_events.clone();
        let refresh_colors = refresh_colors.clone();
        
        Callback::from(move |_| {
            let user_info = user_info.clone();
            let auth_token = auth_token.clone();
            let external_calendars = external_calendars.clone();
            let external_calendar_events = external_calendar_events.clone();
            let refresh_colors = refresh_colors.clone();
            
            wasm_bindgen_futures::spawn_local(async move {
                // Refresh main calendar data if authenticated
                if let Some(token) = (*auth_token).clone() {
                    let calendar_service = CalendarService::new();

                    let password = if let Ok(credentials_str) =
                        LocalStorage::get::<String>("caldav_credentials")
                    {
                        if let Ok(credentials) =
                            serde_json::from_str::<serde_json::Value>(&credentials_str)
                        {
                            credentials["password"].as_str().unwrap_or("").to_string()
                        } else {
                            String::new()
                        }
                    } else {
                        String::new()
                    };

                    if !password.is_empty() {
                        match calendar_service.fetch_user_info(&token, &password).await {
                            Ok(mut info) => {
                                // Preserve existing calendar settings (colors and visibility) from current state
                                if let Some(current_info) = (*user_info).clone() {
                                    for current_cal in &current_info.calendars {
                                        for cal in &mut info.calendars {
                                            if cal.path == current_cal.path {
                                                // Preserve visibility setting
                                                cal.is_visible = current_cal.is_visible;
                                                // Preserve color setting
                                                cal.color = current_cal.color.clone();
                                            }
                                        }
                                    }
                                }
                                
                                // Apply saved colors as fallback for new calendars
                                if let Ok(saved_colors_json) =
                                    LocalStorage::get::<String>("calendar_colors")
                                {
                                    if let Ok(saved_info) =
                                        serde_json::from_str::<UserInfo>(&saved_colors_json)
                                    {
                                        for saved_cal in &saved_info.calendars {
                                            for cal in &mut info.calendars {
                                                if cal.path == saved_cal.path && cal.color == "#3B82F6" {
                                                    // Only apply saved color if it's still the default
                                                    cal.color = saved_cal.color.clone();
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                // Add timestamp to force re-render
                                info.last_updated = (js_sys::Date::now() / 1000.0) as u64;
                                user_info.set(Some(info));
                                // Refresh colors after loading user preferences
                                refresh_colors.emit(());
                            }
                            Err(err) => {
                                web_sys::console::log_1(
                                    &format!("Failed to refresh main calendar data: {}", err).into(),
                                );
                            }
                        }
                    }
                }

                // Refresh external calendars data
                match CalendarService::get_external_calendars().await {
                    Ok(calendars) => {
                        external_calendars.set(calendars.clone());
                        
                        // Load events for visible external calendars
                        let mut all_external_events = Vec::new();
                        for calendar in calendars {
                            if calendar.is_visible {
                                match CalendarService::fetch_external_calendar_events(calendar.id).await {
                                    Ok(mut events) => {
                                        // Set calendar_path for color matching
                                        for event in &mut events {
                                            event.calendar_path = Some(format!("external_{}", calendar.id));
                                        }
                                        all_external_events.extend(events);
                                    }
                                    Err(e) => {
                                        web_sys::console::log_1(
                                            &format!("Failed to fetch events for external calendar {}: {}", calendar.id, e).into(),
                                        );
                                    }
                                }
                            }
                        }
                        external_calendar_events.set(all_external_events);
                    }
                    Err(e) => {
                        web_sys::console::log_1(
                            &format!("Failed to refresh external calendars: {}", e).into(),
                        );
                    }
                }
                
            });
        })
    };

    let on_login = {
        let auth_token = auth_token.clone();
        Callback::from(move |token: String| {
            auth_token.set(Some(token));
        })
    };

    let on_logout = {
        let auth_token = auth_token.clone();
        let user_info = user_info.clone();
        Callback::from(move |_| {
            let _ = LocalStorage::delete("auth_token");
            auth_token.set(None);
            user_info.set(None);
        })
    };

    let on_mobile_warning_close = {
        let mobile_warning_open = mobile_warning_open.clone();
        Callback::from(move |_| {
            mobile_warning_open.set(false);
        })
    };

    let on_color_editor_open = {
        let color_editor_open = color_editor_open.clone();
        let color_editor_data = color_editor_data.clone();
        Callback::from(move |(index, color): (usize, String)| {
            color_editor_data.set(Some((index, color)));
            color_editor_open.set(true);
        })
    };

    let on_color_editor_close = {
        let color_editor_open = color_editor_open.clone();
        Callback::from(move |_| {
            color_editor_open.set(false);
        })
    };

    let on_color_editor_save = {
        let available_colors = available_colors.clone();
        let color_editor_open = color_editor_open.clone();
        let refresh_colors = refresh_colors.clone();
        Callback::from(move |(index, new_color): (usize, String)| {
            // Update the colors array
            let mut colors = (*available_colors).clone();
            if index < colors.len() {
                colors[index] = new_color;
                available_colors.set(colors.clone());
                
                // Save to preferences asynchronously
                let colors_for_save = colors.clone();
                let refresh_colors = refresh_colors.clone();
                wasm_bindgen_futures::spawn_local(async move {
                    if let Err(e) = save_custom_colors_to_preferences(colors_for_save).await {
                        web_sys::console::log_1(&format!("Failed to save custom colors: {}", e).into());
                    } else {
                        // Refresh colors to ensure UI is in sync
                        refresh_colors.emit(());
                    }
                });
            }
            color_editor_open.set(false);
        })
    };

    let on_color_editor_reset_all = {
        let available_colors = available_colors.clone();
        let refresh_colors = refresh_colors.clone();
        Callback::from(move |_| {
            // Reset to default colors
            let default_colors = get_default_event_colors();
            available_colors.set(default_colors.clone());
            
            // Save to preferences asynchronously
            let colors_for_save = default_colors.clone();
            let refresh_colors = refresh_colors.clone();
            wasm_bindgen_futures::spawn_local(async move {
                if let Err(e) = save_custom_colors_to_preferences(colors_for_save).await {
                    web_sys::console::log_1(&format!("Failed to save default colors: {}", e).into());
                } else {
                    // Refresh colors to ensure UI is in sync
                    refresh_colors.emit(());
                }
            });
        })
    };

    let on_view_change = {
        let current_view = current_view.clone();
        Callback::from(move |new_view: ViewMode| {
            // Save view mode to localStorage
            let view_string = match new_view {
                ViewMode::Month => "month",
                ViewMode::Week => "week",
            };
            let _ = LocalStorage::set("calendar_view_mode", view_string);

            // Update state
            current_view.set(new_view);
        })
    };

    let on_theme_change = {
        let current_theme = current_theme.clone();
        Callback::from(move |new_theme: Theme| {
            // Save theme to localStorage
            let _ = LocalStorage::set("calendar_theme", new_theme.value());

            // Apply theme to document root
            if let Some(document) = web_sys::window().and_then(|w| w.document()) {
                if let Some(root) = document.document_element() {
                    let _ = root.set_attribute("data-theme", new_theme.value());
                }
            }

            // Update state
            current_theme.set(new_theme);

            // Colors are now unified and don't change with themes
        })
    };

    let on_style_change = {
        let current_style = current_style.clone();
        Callback::from(move |new_style: Style| {
            // Save style to localStorage
            let _ = LocalStorage::set("calendar_style", new_style.value());

            // Hot-swap stylesheet
            if let Some(window) = web_sys::window() {
                if let Some(document) = window.document() {
                    // Set data-style attribute on document root
                    if let Some(root) = document.document_element() {
                        let _ = root.set_attribute("data-style", new_style.value());
                    }

                    // Remove existing style link if it exists
                    if let Some(existing_link) = document.get_element_by_id("dynamic-style") {
                        existing_link.remove();
                    }

                    // Create and append new stylesheet link only if style has a path
                    if let Some(stylesheet_path) = new_style.stylesheet_path() {
                        if let Ok(link) = document.create_element("link") {
                            let link = link.dyn_into::<web_sys::HtmlLinkElement>().unwrap();
                            link.set_id("dynamic-style");
                            link.set_rel("stylesheet");
                            link.set_href(stylesheet_path);
                            
                            if let Some(head) = document.head() {
                                let _ = head.append_child(&link);
                            }
                        }
                    }
                    // If stylesheet_path is None (Default style), just removing the dynamic link is enough
                }
            }

            // Update state
            current_style.set(new_style);
        })
    };

    // Apply initial theme on mount
    {
        let current_theme = current_theme.clone();
        use_effect_with((), move |_| {
            let theme = (*current_theme).clone();
            if let Some(document) = web_sys::window().and_then(|w| w.document()) {
                if let Some(root) = document.document_element() {
                    let _ = root.set_attribute("data-theme", theme.value());
                }
            }
        });
    }

    // Apply initial style on mount
    {
        let current_style = current_style.clone();
        use_effect_with((), move |_| {
            let style = (*current_style).clone();
            if let Some(window) = web_sys::window() {
                if let Some(document) = window.document() {
                    // Set data-style attribute on document root
                    if let Some(root) = document.document_element() {
                        let _ = root.set_attribute("data-style", style.value());
                    }

                    // Create and append stylesheet link for initial style only if it has a path
                    if let Some(stylesheet_path) = style.stylesheet_path() {
                        if let Ok(link) = document.create_element("link") {
                            let link = link.dyn_into::<web_sys::HtmlLinkElement>().unwrap();
                            link.set_id("dynamic-style");
                            link.set_rel("stylesheet");
                            link.set_href(stylesheet_path);
                            
                            if let Some(head) = document.head() {
                                let _ = head.append_child(&link);
                            }
                        }
                    }
                    // If initial style is Default (None), no additional stylesheet needed
                }
            }
        });
    }


    // Fetch user info when token is available
    {
        let user_info = user_info.clone();
        let auth_token = auth_token.clone();

        use_effect_with((*auth_token).clone(), move |token| {
            if let Some(token) = token {
                let user_info = user_info.clone();
                let token = token.clone();

                wasm_bindgen_futures::spawn_local(async move {
                    let calendar_service = CalendarService::new();

                    let password = if let Ok(credentials_str) =
                        LocalStorage::get::<String>("caldav_credentials")
                    {
                        if let Ok(credentials) =
                            serde_json::from_str::<serde_json::Value>(&credentials_str)
                        {
                            credentials["password"].as_str().unwrap_or("").to_string()
                        } else {
                            String::new()
                        }
                    } else {
                        String::new()
                    };

                    if !password.is_empty() {
                        match calendar_service.fetch_user_info(&token, &password).await {
                            Ok(mut info) => {
                                if let Ok(saved_colors_json) =
                                    LocalStorage::get::<String>("calendar_colors")
                                {
                                    if let Ok(saved_info) =
                                        serde_json::from_str::<UserInfo>(&saved_colors_json)
                                    {
                                        for saved_cal in &saved_info.calendars {
                                            for cal in &mut info.calendars {
                                                if cal.path == saved_cal.path {
                                                    cal.color = saved_cal.color.clone();
                                                }
                                            }
                                        }
                                    }
                                }
                                user_info.set(Some(info));
                            }
                            Err(err) => {
                                web_sys::console::log_1(
                                    &format!("Failed to fetch user info: {}", err).into(),
                                );
                            }
                        }
                    }
                });
            } else {
                user_info.set(None);
            }

            || ()
        });
    }

    // Function to refresh external calendars
    let refresh_external_calendars = {
        let external_calendars = external_calendars.clone();
        let external_calendar_events = external_calendar_events.clone();
        Callback::from(move |_| {
            let external_calendars = external_calendars.clone();
            let external_calendar_events = external_calendar_events.clone();

            wasm_bindgen_futures::spawn_local(async move {
                // Load external calendars
                match CalendarService::get_external_calendars().await {
                    Ok(calendars) => {
                        external_calendars.set(calendars.clone());
                        
                        // Load events for visible external calendars
                        let mut all_events = Vec::new();
                        for calendar in calendars {
                            if calendar.is_visible {
                                if let Ok(mut events) = CalendarService::fetch_external_calendar_events(calendar.id).await {
                                    // Set calendar_path for color matching
                                    for event in &mut events {
                                        event.calendar_path = Some(format!("external_{}", calendar.id));
                                    }
                                    all_events.extend(events);
                                }
                            }
                        }
                        external_calendar_events.set(all_events);
                    }
                    Err(err) => {
                        web_sys::console::log_1(
                            &format!("Failed to load external calendars: {}", err).into(),
                        );
                    }
                }
            });
        })
    };

    // Load external calendars when auth token is available and set up auto-refresh
    {
        let auth_token = auth_token.clone();
        let refresh_external_calendars = refresh_external_calendars.clone();
        let refresh_interval = refresh_interval.clone();
        let external_calendars = external_calendars.clone();
        let external_calendar_events = external_calendar_events.clone();

        use_effect_with((*auth_token).clone(), move |token| {
            if let Some(_) = token {
                // Initial load
                refresh_external_calendars.emit(());
                
                // Set up 5-minute refresh interval
                let refresh_external_calendars = refresh_external_calendars.clone();
                let interval = Interval::new(5 * 60 * 1000, move || {
                    refresh_external_calendars.emit(());
                });
                refresh_interval.set(Some(interval));
            } else {
                // Clear data and interval when logged out
                external_calendars.set(Vec::new());
                external_calendar_events.set(Vec::new());
                refresh_interval.set(None);
            }

            // Cleanup function
            let refresh_interval = refresh_interval.clone();
            move || {
                // Clear interval on cleanup
                refresh_interval.set(None);
            }
        });
    }

    let on_outside_click = {
        let color_picker_open = color_picker_open.clone();
        let context_menu_open = context_menu_open.clone();
        let event_context_menu_open = event_context_menu_open.clone();
        let calendar_context_menu_open = calendar_context_menu_open.clone();
        Callback::from(move |e: MouseEvent| {
            // Check if any context menu or color picker is open
            let any_menu_open = color_picker_open.is_some()
                || *context_menu_open
                || *event_context_menu_open
                || *calendar_context_menu_open;

            if any_menu_open {
                // Prevent the default action and stop event propagation
                e.prevent_default();
                e.stop_propagation();
            }

            // Close all open menus/pickers
            color_picker_open.set(None);
            context_menu_open.set(false);
            event_context_menu_open.set(false);
            calendar_context_menu_open.set(false);
        })
    };

    // Compute if any context menu is open
    let any_context_menu_open = color_picker_open.is_some()
        || *context_menu_open
        || *event_context_menu_open
        || *calendar_context_menu_open;

    let on_color_change = {
        let user_info = user_info.clone();
        let external_calendars = external_calendars.clone();
        let color_picker_open = color_picker_open.clone();
        Callback::from(move |(calendar_path, color): (String, String)| {
            if calendar_path.starts_with("external_") {
                // Handle external calendar color change
                if let Ok(id_str) = calendar_path.strip_prefix("external_").unwrap_or("").parse::<i32>() {
                    let external_calendars = external_calendars.clone();
                    let color = color.clone();
                    
                    wasm_bindgen_futures::spawn_local(async move {
                        // Find the external calendar to get its current details
                        if let Some(cal) = (*external_calendars).iter().find(|c| c.id == id_str) {
                            match CalendarService::update_external_calendar(
                                id_str,
                                &cal.name,
                                &cal.url,
                                &color,
                                cal.is_visible,
                            ).await {
                                Ok(_) => {
                                    // Update the local state
                                    let mut updated_calendars = (*external_calendars).clone();
                                    for calendar in &mut updated_calendars {
                                        if calendar.id == id_str {
                                            calendar.color = color.clone();
                                            break;
                                        }
                                    }
                                    external_calendars.set(updated_calendars);
                                    
                                    // No need to refresh events - they will automatically pick up the new color
                                    // from the calendar when rendered since they use the same calendar_path matching
                                }
                                Err(e) => {
                                    web_sys::console::error_1(&format!("Failed to update external calendar color: {}", e).into());
                                }
                            }
                        }
                    });
                }
            } else {
                // Handle CalDAV calendar color change (existing logic)
                if let Some(mut info) = (*user_info).clone() {
                    for calendar in &mut info.calendars {
                        if calendar.path == calendar_path {
                            calendar.color = color.clone();
                            break;
                        }
                    }
                    user_info.set(Some(info.clone()));

                    if let Ok(json) = serde_json::to_string(&info) {
                        let _ = LocalStorage::set("calendar_colors", json);
                    }
                }
            }
            color_picker_open.set(None);
        })
    };

    let on_color_picker_toggle = {
        let color_picker_open = color_picker_open.clone();
        Callback::from(move |calendar_path: String| {
            if color_picker_open.as_ref() == Some(&calendar_path) {
                color_picker_open.set(None);
            } else {
                color_picker_open.set(Some(calendar_path));
            }
        })
    };

    let on_calendar_context_menu = {
        let context_menu_open = context_menu_open.clone();
        let context_menu_pos = context_menu_pos.clone();
        let context_menu_calendar_path = context_menu_calendar_path.clone();
        Callback::from(move |(event, calendar_path): (MouseEvent, String)| {
            context_menu_open.set(true);
            context_menu_pos.set((event.client_x(), event.client_y()));
            context_menu_calendar_path.set(Some(calendar_path));
        })
    };

    let on_event_context_menu = {
        let event_context_menu_open = event_context_menu_open.clone();
        let event_context_menu_pos = event_context_menu_pos.clone();
        let event_context_menu_event = event_context_menu_event.clone();
        Callback::from(move |(event, calendar_event): (MouseEvent, VEvent)| {
            event_context_menu_open.set(true);
            event_context_menu_pos.set((event.client_x(), event.client_y()));
            event_context_menu_event.set(Some(calendar_event));
        })
    };

    let on_calendar_date_context_menu = {
        let calendar_context_menu_open = calendar_context_menu_open.clone();
        let calendar_context_menu_pos = calendar_context_menu_pos.clone();
        let calendar_context_menu_date = calendar_context_menu_date.clone();
        Callback::from(move |(event, date): (MouseEvent, NaiveDate)| {
            calendar_context_menu_open.set(true);
            calendar_context_menu_pos.set((event.client_x(), event.client_y()));
            calendar_context_menu_date.set(Some(date));
        })
    };

    let on_create_event_click = {
        let create_event_modal_open = create_event_modal_open.clone();
        let selected_date_for_event = selected_date_for_event.clone();
        let calendar_context_menu_date = calendar_context_menu_date.clone();
        Callback::from(move |_: MouseEvent| {
            create_event_modal_open.set(true);
            selected_date_for_event.set((*calendar_context_menu_date).clone());
        })
    };

    let on_event_create = {
        let create_event_modal_open = create_event_modal_open.clone();
        let auth_token = auth_token.clone();
        let refresh_calendar_data = refresh_calendar_data.clone();
        let alarm_scheduler = alarm_scheduler.clone();
        Callback::from(move |event_data: EventCreationData| {
            let alarm_scheduler = alarm_scheduler.clone();
            // Check if this is an update operation (has original_uid) or a create operation
            if let Some(original_uid) = event_data.original_uid.clone() {
                web_sys::console::log_1(&format!("Updating event via modal: {:?}", event_data).into());
                
                create_event_modal_open.set(false);
                
                // Handle the update operation using the existing backend update logic
                if let Some(token) = (*auth_token).clone() {
                    let event_data_for_update = event_data.clone();
                    let refresh_callback = refresh_calendar_data.clone();
                    wasm_bindgen_futures::spawn_local(async move {
                        let calendar_service = CalendarService::new();

                        // Get CalDAV password from storage
                        let password = if let Ok(credentials_str) =
                            LocalStorage::get::<String>("caldav_credentials")
                        {
                            if let Ok(credentials) =
                                serde_json::from_str::<serde_json::Value>(&credentials_str)
                            {
                                credentials["password"].as_str().unwrap_or("").to_string()
                            } else {
                                String::new()
                            }
                        } else {
                            String::new()
                        };

                        // Convert EventCreationData to update parameters
                        let params = event_data_for_update.to_create_event_params();
                        
                        // Determine if this is a recurring event update
                        let is_recurring = matches!(event_data_for_update.recurrence, crate::components::event_form::RecurrenceType::Daily | 
                                                   crate::components::event_form::RecurrenceType::Weekly | 
                                                   crate::components::event_form::RecurrenceType::Monthly | 
                                                   crate::components::event_form::RecurrenceType::Yearly);
                        
                        let update_result = if is_recurring && event_data_for_update.edit_scope.is_some() {
                            // Only use series endpoint for existing recurring events being edited
                            // Singleton→series conversion should use regular update_event endpoint
                            let edit_action = event_data_for_update.edit_scope.as_ref().unwrap();
                            let scope = match edit_action {
                                crate::components::EditAction::EditAll => "all_in_series".to_string(),
                                crate::components::EditAction::EditFuture => "this_and_future".to_string(),
                                crate::components::EditAction::EditThis => "this_only".to_string(),
                            };
                            
                            calendar_service
                                .update_series(
                                    &token,
                                    &password,
                                    original_uid.clone(),
                                    params.0,  // title
                                    params.1,  // description
                                    params.2,  // start_date
                                    params.3,  // start_time
                                    params.4,  // end_date
                                    params.5,  // end_time
                                    params.6,  // location
                                    params.7,  // all_day
                                    params.8,  // status
                                    params.9,  // class
                                    params.10, // priority
                                    params.11, // organizer
                                    params.12, // attendees
                                    params.13, // categories
                                    params.14, // reminder
                                    params.15, // recurrence
                                    params.16, // recurrence_days
                                    params.17, // recurrence_interval
                                    params.18, // recurrence_count
                                    params.19, // recurrence_until
                                    params.20, // calendar_path
                                    scope,
                                    event_data_for_update.occurrence_date.map(|d| d.format("%Y-%m-%d").to_string()), // occurrence_date
                                    params.21, // timezone
                                )
                                .await
                        } else {
                            // Use regular update endpoint for single events
                            calendar_service
                                .update_event(
                                    &token,
                                    &password,
                                    original_uid.clone(),
                                    params.0,  // title
                                    params.1,  // description
                                    params.2,  // start_date
                                    params.3,  // start_time
                                    params.4,  // end_date
                                    params.5,  // end_time
                                    params.6,  // location
                                    params.7,  // all_day
                                    params.8,  // status
                                    params.9,  // class
                                    params.10, // priority
                                    params.11, // organizer
                                    params.12, // attendees
                                    params.13, // categories
                                    params.14, // reminder
                                    params.15, // recurrence
                                    params.16, // recurrence_days
                                    params.17, // recurrence_interval
                                    params.18, // recurrence_count
                                    params.19, // recurrence_until
                                    params.20, // calendar_path
                                    params.21, // timezone
                                )
                                .await
                        };

                        match update_result {
                            Ok(_) => {
                                web_sys::console::log_1(&"Event updated successfully via modal".into());
                                
                                // Re-schedule alarms for the updated event
                                let alarm_scheduler_for_update = alarm_scheduler.clone();
                                let event_data_for_alarms = event_data_for_update.clone();
                                let original_uid_for_alarms = original_uid.clone();
                                
                                wasm_bindgen_futures::spawn_local(async move {
                                    let mut scheduler = (*alarm_scheduler_for_update).clone();
                                    
                                    // Remove old alarms for this event
                                    scheduler.remove_event_alarms(&original_uid_for_alarms);
                                    
                                    // Schedule new alarms if any exist
                                    if !event_data_for_alarms.alarms.is_empty() {
                                        let params = event_data_for_alarms.to_create_event_params();
                                        
                                        // Parse start date/time for alarm scheduling
                                        if let (Ok(start_date), Ok(start_time)) = (
                                            chrono::NaiveDate::parse_from_str(&params.2, "%Y-%m-%d"),
                                            chrono::NaiveTime::parse_from_str(&params.3, "%H:%M")
                                        ) {
                                            // Create a temporary VEvent for alarm scheduling
                                            let start_datetime = start_date.and_time(start_time);
                                            let mut temp_event = VEvent::new(original_uid_for_alarms.clone(), start_datetime);
                                            temp_event.summary = Some(params.0.clone()); // title
                                            temp_event.location = if params.6.is_empty() { None } else { Some(params.6.clone()) };
                                            temp_event.alarms = event_data_for_alarms.alarms.clone();
                                            
                                            scheduler.schedule_event_alarms(&temp_event);
                                            
                                            web_sys::console::log_1(
                                                &format!("🔔 Re-scheduled {} alarm(s) for updated event", temp_event.alarms.len()).into()
                                            );
                                        }
                                    }
                                    
                                    alarm_scheduler_for_update.set(scheduler);
                                });
                                
                                // Refresh calendar data without page reload
                                refresh_callback.emit(());
                            }
                            Err(err) => {
                                web_sys::console::error_1(
                                    &format!("Failed to update event: {}", err).into(),
                                );
                                web_sys::window()
                                    .unwrap()
                                    .alert_with_message(&format!("Failed to update event: {}", err))
                                    .unwrap();
                            }
                        }
                    });
                }
                return;
            }
            
            web_sys::console::log_1(&format!("Creating event: {:?}", event_data).into());
            
            // Save the selected calendar as the last used calendar
            if let Some(ref calendar_path) = event_data.selected_calendar {
                let _ = LocalStorage::set("last_used_calendar", calendar_path);
                
                // Also sync to backend asynchronously
                let calendar_path_for_sync = calendar_path.clone();
                wasm_bindgen_futures::spawn_local(async move {
                    let preferences_service = crate::services::preferences::PreferencesService::new();
                    if let Err(e) = preferences_service.update_last_used_calendar(&calendar_path_for_sync).await {
                        web_sys::console::warn_1(&format!("Failed to sync last used calendar to backend: {}", e).into());
                    }
                });
            }
            
            create_event_modal_open.set(false);

            if let Some(_token) = (*auth_token).clone() {
                let refresh_callback = refresh_calendar_data.clone();
                wasm_bindgen_futures::spawn_local(async move {
                    let _calendar_service = CalendarService::new();

                    // Get CalDAV password from storage
                    let _password = if let Ok(credentials_str) =
                        LocalStorage::get::<String>("caldav_credentials")
                    {
                        if let Ok(credentials) =
                            serde_json::from_str::<serde_json::Value>(&credentials_str)
                        {
                            credentials["password"].as_str().unwrap_or("").to_string()
                        } else {
                            String::new()
                        }
                    } else {
                        String::new()
                    };

                    let params = event_data.to_create_event_params();
                    // Clone values we'll need for alarm scheduling
                    let title_for_alarms = params.0.clone();
                    let start_date_for_alarms = params.2.clone();
                    let start_time_for_alarms = params.3.clone();
                    let location_for_alarms = params.6.clone();
                    
                    let create_result = _calendar_service
                        .create_event(
                            &_token, &_password, params.0,  // title
                            params.1,  // description
                            params.2,  // start_date
                            params.3,  // start_time
                            params.4,  // end_date
                            params.5,  // end_time
                            params.6,  // location
                            params.7,  // all_day
                            params.8,  // status
                            params.9,  // class
                            params.10, // priority
                            params.11, // organizer
                            params.12, // attendees
                            params.13, // categories
                            params.14, // reminder
                            params.15, // recurrence
                            params.16, // recurrence_days
                            params.17, // recurrence_interval
                            params.18, // recurrence_count
                            params.19, // recurrence_until
                            params.20, // calendar_path
                            params.21, // timezone
                        )
                        .await;
                    match create_result {
                        Ok(_) => {
                            web_sys::console::log_1(&"Event created successfully".into());
                            
                            // Schedule alarms for the created event if any exist
                            if !event_data.alarms.is_empty() {
                                // Since create_event doesn't return the UID, we need to generate one
                                // The backend should be using the same UUID generation logic
                                let event_uid = uuid::Uuid::new_v4().to_string();
                                
                                // Parse start date/time for alarm scheduling
                                if let (Ok(start_date), Ok(start_time)) = (
                                    chrono::NaiveDate::parse_from_str(&start_date_for_alarms, "%Y-%m-%d"),
                                    chrono::NaiveTime::parse_from_str(&start_time_for_alarms, "%H:%M")
                                ) {
                                    // Create a temporary VEvent for alarm scheduling
                                    let start_datetime = start_date.and_time(start_time);
                                    let mut temp_event = VEvent::new(event_uid.clone(), start_datetime);
                                    temp_event.summary = Some(title_for_alarms.clone());
                                    temp_event.location = if location_for_alarms.is_empty() { None } else { Some(location_for_alarms.clone()) };
                                    temp_event.alarms = event_data.alarms.clone();
                                    
                                    // Schedule alarms for the new event (synchronously)
                                    let mut scheduler = (*alarm_scheduler).clone();
                                    scheduler.schedule_event_alarms(&temp_event);
                                    alarm_scheduler.set(scheduler);
                                    
                                    web_sys::console::log_1(
                                        &format!("🔔 Scheduled {} alarm(s) for new event", temp_event.alarms.len()).into()
                                    );
                                }
                            }
                            
                            // Refresh calendar data without page reload
                            refresh_callback.emit(());
                        }
                        Err(err) => {
                            web_sys::console::error_1(
                                &format!("Failed to create event: {}", err).into(),
                            );
                            web_sys::window()
                                .unwrap()
                                .alert_with_message(&format!("Failed to create event: {}", err))
                                .unwrap();
                        }
                    }
                });
            }
        })
    };

    let on_event_update = {
        let auth_token = auth_token.clone();
        let refresh_calendar_data = refresh_calendar_data.clone();
        Callback::from(
            move |(
                original_event,
                new_start,
                new_end,
                _preserve_rrule,
                _until_date,
                update_scope,
                occurrence_date,
            ): (
                VEvent,
                chrono::NaiveDateTime,
                chrono::NaiveDateTime,
                bool,
                Option<chrono::NaiveDateTime>,
                Option<String>,
                Option<String>,
            )| {
                web_sys::console::log_1(
                    &format!(
                        "Updating event: {} to new times: {} - {}",
                        original_event.uid,
                        new_start.format("%Y-%m-%d %H:%M"),
                        new_end.format("%Y-%m-%d %H:%M")
                    )
                    .into(),
                );

                // Use the original UID for all updates
                let backend_uid = original_event.uid.clone();

                if let Some(token) = (*auth_token).clone() {
                    let original_event = original_event.clone();
                    let backend_uid = backend_uid.clone();
                    let refresh_callback = refresh_calendar_data.clone();
                    wasm_bindgen_futures::spawn_local(async move {
                        let calendar_service = CalendarService::new();

                        // Get CalDAV password from storage
                        let password = if let Ok(credentials_str) =
                            LocalStorage::get::<String>("caldav_credentials")
                        {
                            if let Ok(credentials) =
                                serde_json::from_str::<serde_json::Value>(&credentials_str)
                            {
                                credentials["password"].as_str().unwrap_or("").to_string()
                            } else {
                                String::new()
                            }
                        } else {
                            String::new()
                        };

                        

                        // Send local times to backend, which will handle timezone conversion
                        let start_date = new_start.format("%Y-%m-%d").to_string();
                        let start_time = new_start.format("%H:%M").to_string();
                        let end_date = new_end.format("%Y-%m-%d").to_string();
                        let end_time = new_end.format("%H:%M").to_string();

                        // Convert existing event data to string formats for the API
                        let status_str = match original_event.status {
                            Some(crate::models::ical::EventStatus::Tentative) => {
                                "TENTATIVE".to_string()
                            }
                            Some(crate::models::ical::EventStatus::Confirmed) => {
                                "CONFIRMED".to_string()
                            }
                            Some(crate::models::ical::EventStatus::Cancelled) => {
                                "CANCELLED".to_string()
                            }
                            None => "CONFIRMED".to_string(), // Default status
                        };

                        let class_str = match original_event.class {
                            Some(crate::models::ical::EventClass::Public) => "PUBLIC".to_string(),
                            Some(crate::models::ical::EventClass::Private) => "PRIVATE".to_string(),
                            Some(crate::models::ical::EventClass::Confidential) => {
                                "CONFIDENTIAL".to_string()
                            }
                            None => "PUBLIC".to_string(), // Default class
                        };

                        // Convert reminders to string format
                        let _reminder_str = if !original_event.alarms.is_empty() {
                            // Convert from VAlarm to minutes before
                            "15".to_string() // TODO: Convert VAlarm trigger to minutes
                        } else {
                            "".to_string()
                        };

                        // Handle recurrence (keep existing)
                        let recurrence_str = original_event.rrule.unwrap_or_default();
                        let recurrence_days = vec![false; 7]; // Default - could be enhanced to parse existing recurrence

                        // Determine if this is a recurring event that needs series endpoint
                        let has_recurrence =
                            !recurrence_str.is_empty() && recurrence_str.to_uppercase() != "NONE";

                        let result = if let Some(scope) = update_scope.as_ref() {
                            // Use series endpoint for recurring event operations
                            if !has_recurrence {
                                web_sys::console::log_1(&"⚠️ Warning: update_scope provided for non-recurring event, using regular endpoint instead".into());
                                // Fall through to regular endpoint
                                None
                            } else {
                                Some(
                                    calendar_service
                                        .update_series(
                                            &token,
                                            &password,
                                            backend_uid.clone(),
                                            original_event.summary.clone().unwrap_or_default(),
                                            original_event.description.clone().unwrap_or_default(),
                                            start_date.clone(),
                                            start_time.clone(),
                                            end_date.clone(),
                                            end_time.clone(),
                                            original_event.location.clone().unwrap_or_default(),
                                            original_event.all_day,
                                            status_str.clone(),
                                            class_str.clone(),
                                            original_event.priority,
                                            original_event
                                                .organizer
                                                .as_ref()
                                                .map(|o| o.cal_address.clone())
                                                .unwrap_or_default(),
                                            original_event
                                                .attendees
                                                .iter()
                                                .map(|a| a.cal_address.clone())
                                                .collect::<Vec<_>>()
                                                .join(","),
                                            original_event.categories.join(","),
                                            original_event.alarms.clone(),
                                            recurrence_str.clone(),
                                            vec![false; 7], // recurrence_days
                                            1, // recurrence_interval - default for drag-and-drop
                                            None, // recurrence_count
                                            None, // recurrence_until 
                                            original_event.calendar_path.clone(), // calendar_path
                                            scope.clone(), // update_scope
                                            occurrence_date, // occurrence_date
                                            {
                                                // Get timezone offset
                                                let date = js_sys::Date::new_0();
                                                let timezone_offset = date.get_timezone_offset(); // Minutes from UTC
                                                let hours = -(timezone_offset as i32) / 60; // Convert to hours, negate for proper sign
                                                let minutes = (timezone_offset as i32).abs() % 60;
                                                format!("{:+03}:{:02}", hours, minutes) // Format as +05:00 or -04:00
                                            }, // timezone
                                        )
                                        .await,
                                )
                            }
                        } else {
                            None
                        };

                        let result = if let Some(series_result) = result {
                            series_result
                        } else {
                            // Use regular endpoint
                            calendar_service
                                .update_event(
                                    &token,
                                    &password,
                                    backend_uid,
                                    original_event.summary.unwrap_or_default(),
                                    original_event.description.unwrap_or_default(),
                                    start_date,
                                    start_time,
                                    end_date,
                                    end_time,
                                    original_event.location.unwrap_or_default(),
                                    original_event.all_day,
                                    status_str,
                                    class_str,
                                    original_event.priority,
                                    original_event
                                        .organizer
                                        .as_ref()
                                        .map(|o| o.cal_address.clone())
                                        .unwrap_or_default(),
                                    original_event
                                        .attendees
                                        .iter()
                                        .map(|a| a.cal_address.clone())
                                        .collect::<Vec<_>>()
                                        .join(","),
                                    original_event.categories.join(","),
                                    original_event.alarms.clone(),
                                    recurrence_str,
                                    recurrence_days,
                                    1, // recurrence_interval - default to 1 for drag-and-drop
                                    None, // recurrence_count - preserve existing
                                    None, // recurrence_until - preserve existing
                                    original_event.calendar_path,
                                    {
                                        // Get timezone offset
                                        let date = js_sys::Date::new_0();
                                        let timezone_offset = date.get_timezone_offset(); // Minutes from UTC
                                        let hours = -(timezone_offset as i32) / 60; // Convert to hours, negate for proper sign
                                        let minutes = (timezone_offset as i32).abs() % 60;
                                        format!("{:+03}:{:02}", hours, minutes) // Format as +05:00 or -04:00
                                    },
                                )
                                .await
                        };

                        match result {
                            Ok(_) => {
                                web_sys::console::log_1(&"Event updated successfully".into());
                                // Refresh calendar data without page reload
                                refresh_callback.emit(());
                            }
                            Err(err) => {
                                web_sys::console::error_1(
                                    &format!("Failed to update event: {}", err).into(),
                                );
                                web_sys::window()
                                    .unwrap()
                                    .alert_with_message(&format!("Failed to update event: {}", err))
                                    .unwrap();
                            }
                        }
                    });
                }
            },
        )
    };

    let refresh_calendars = {
        let auth_token = auth_token.clone();
        let user_info = user_info.clone();
        Callback::from(move |_| {
            if let Some(token) = (*auth_token).clone() {
                let user_info = user_info.clone();

                wasm_bindgen_futures::spawn_local(async move {
                    let calendar_service = CalendarService::new();

                    let password = if let Ok(credentials_str) =
                        LocalStorage::get::<String>("caldav_credentials")
                    {
                        if let Ok(credentials) =
                            serde_json::from_str::<serde_json::Value>(&credentials_str)
                        {
                            credentials["password"].as_str().unwrap_or("").to_string()
                        } else {
                            String::new()
                        }
                    } else {
                        String::new()
                    };

                    match calendar_service.fetch_user_info(&token, &password).await {
                        Ok(mut info) => {
                            if let Ok(saved_colors_json) =
                                LocalStorage::get::<String>("calendar_colors")
                            {
                                if let Ok(saved_info) =
                                    serde_json::from_str::<UserInfo>(&saved_colors_json)
                                {
                                    for saved_cal in &saved_info.calendars {
                                        for cal in &mut info.calendars {
                                            if cal.path == saved_cal.path {
                                                cal.color = saved_cal.color.clone();
                                            }
                                        }
                                    }
                                }
                            }
                            user_info.set(Some(info));
                        }
                        Err(err) => {
                            web_sys::console::log_1(
                                &format!("Failed to refresh calendars: {}", err).into(),
                            );
                        }
                    }
                });
            }
        })
    };


    html! {
        <BrowserRouter>
            <div class="app" onclick={on_outside_click}>
                {
                    if auth_token.is_some() {
                        html! {
                            <>
                                <Sidebar
                                    user_info={(*user_info).clone()}
                                    on_logout={on_logout}
                                    on_add_calendar={Callback::from({
                                        let calendar_management_modal_open = calendar_management_modal_open.clone();
                                        move |_| calendar_management_modal_open.set(true)
                                    })}
                                    external_calendars={(*external_calendars).clone()}
                                    on_external_calendar_toggle={Callback::from({
                                        let external_calendars = external_calendars.clone();
                                        let external_calendar_events = external_calendar_events.clone();
                                        move |id: i32| {
                                            let external_calendars = external_calendars.clone();
                                            let external_calendar_events = external_calendar_events.clone();
                                            wasm_bindgen_futures::spawn_local(async move {
                                                // Find the calendar and toggle its visibility
                                                let mut calendars = (*external_calendars).clone();
                                                if let Some(calendar) = calendars.iter_mut().find(|c| c.id == id) {
                                                    calendar.is_visible = !calendar.is_visible;
                                                    
                                                    // Update on server
                                                    if let Err(err) = CalendarService::update_external_calendar(
                                                        calendar.id,
                                                        &calendar.name,
                                                        &calendar.url,
                                                        &calendar.color,
                                                        calendar.is_visible,
                                                    ).await {
                                                        web_sys::console::log_1(
                                                            &format!("Failed to update external calendar: {}", err).into(),
                                                        );
                                                        return;
                                                    }
                                                    
                                                    external_calendars.set(calendars.clone());
                                                    
                                                    // Reload events for all visible external calendars  
                                                    let mut all_events = Vec::new();
                                                    for cal in calendars {
                                                        if cal.is_visible {
                                                            if let Ok(mut events) = CalendarService::fetch_external_calendar_events(cal.id).await {
                                                                // Set calendar_path for color matching
                                                                for event in &mut events {
                                                                    event.calendar_path = Some(format!("external_{}", cal.id));
                                                                }
                                                                all_events.extend(events);
                                                            }
                                                        }
                                                    }
                                                    external_calendar_events.set(all_events);
                                                }
                                            });
                                        }
                                    })}
                                    on_external_calendar_delete={Callback::from({
                                        let external_calendars = external_calendars.clone();
                                        let external_calendar_events = external_calendar_events.clone();
                                        move |id: i32| {
                                            let external_calendars = external_calendars.clone();
                                            let external_calendar_events = external_calendar_events.clone();
                                            wasm_bindgen_futures::spawn_local(async move {
                                                // Delete the external calendar from the server
                                                if let Err(err) = CalendarService::delete_external_calendar(id).await {
                                                    web_sys::console::log_1(
                                                        &format!("Failed to delete external calendar: {}", err).into(),
                                                    );
                                                    return;
                                                }
                                                
                                                // Remove calendar from local state
                                                let mut calendars = (*external_calendars).clone();
                                                calendars.retain(|c| c.id != id);
                                                external_calendars.set(calendars.clone());
                                                
                                                // Remove events from this calendar
                                                let mut events = (*external_calendar_events).clone();
                                                events.retain(|e| {
                                                    if let Some(ref calendar_path) = e.calendar_path {
                                                        calendar_path != &format!("external_{}", id)
                                                    } else {
                                                        true
                                                    }
                                                });
                                                external_calendar_events.set(events);
                                            });
                                        }
                                    })}
                                    on_external_calendar_refresh={Callback::from({
                                        let external_calendar_events = external_calendar_events.clone();
                                        let external_calendars = external_calendars.clone();
                                        let refreshing_calendar_id = refreshing_calendar_id.clone();
                                        move |id: i32| {
                                            let external_calendar_events = external_calendar_events.clone();
                                            let external_calendars = external_calendars.clone();
                                            let refreshing_calendar_id = refreshing_calendar_id.clone();
                                            
                                            // Set loading state
                                            refreshing_calendar_id.set(Some(id));
                                            
                                            wasm_bindgen_futures::spawn_local(async move {
                                                web_sys::console::log_1(&format!("🔄 Refreshing external calendar {}", id).into());
                                                
                                                // Force refresh of this specific calendar
                                                match CalendarService::fetch_external_calendar_events(id).await {
                                                    Ok(mut events) => {
                                                        web_sys::console::log_1(&format!("✅ Successfully refreshed calendar {} with {} events", id, events.len()).into());
                                                        
                                                        // Set calendar_path for color matching
                                                        for event in &mut events {
                                                            event.calendar_path = Some(format!("external_{}", id));
                                                        }
                                                        
                                                        // Update events for this calendar
                                                        let mut all_events = (*external_calendar_events).clone();
                                                        // Remove old events from this calendar
                                                        all_events.retain(|e| {
                                                            if let Some(ref calendar_path) = e.calendar_path {
                                                                calendar_path != &format!("external_{}", id)
                                                            } else {
                                                                true
                                                            }
                                                        });
                                                        // Add new events
                                                        all_events.extend(events);
                                                        external_calendar_events.set(all_events);
                                                        
                                                        // Update the last_fetched timestamp in calendars list
                                                        match CalendarService::get_external_calendars().await {
                                                            Ok(calendars) => {
                                                                external_calendars.set(calendars);
                                                                web_sys::console::log_1(&"✅ Calendar list updated with new timestamps".into());
                                                            }
                                                            Err(err) => {
                                                                web_sys::console::error_1(&format!("⚠️ Failed to update calendar list: {}", err).into());
                                                            }
                                                        }
                                                        
                                                        // Clear loading state on success
                                                        refreshing_calendar_id.set(None);
                                                    }
                                                    Err(err) => {
                                                        web_sys::console::error_1(&format!("❌ Failed to refresh calendar {}: {}", id, err).into());
                                                        // Show error to user
                                                        if let Some(window) = web_sys::window() {
                                                            let _ = window.alert_with_message(&format!("Failed to refresh calendar: {}", err));
                                                        }
                                                        
                                                        // Clear loading state on error
                                                        refreshing_calendar_id.set(None);
                                                    }
                                                }
                                            });
                                        }
                                    })}
                                    color_picker_open={(*color_picker_open).clone()}
                                    on_color_change={on_color_change}
                                    on_color_picker_toggle={on_color_picker_toggle}
                                    available_colors={(*available_colors).clone()}
                                    refreshing_calendar_id={(*refreshing_calendar_id).clone()}
                                    on_calendar_context_menu={on_calendar_context_menu}
                                    on_calendar_visibility_toggle={Callback::from({
                                        let user_info = user_info.clone();
                                        move |calendar_path: String| {
                                            let user_info = user_info.clone();
                                            wasm_bindgen_futures::spawn_local(async move {
                                                if let Some(mut info) = (*user_info).clone() {
                                                    // Toggle the visibility
                                                    if let Some(calendar) = info.calendars.iter_mut().find(|c| c.path == calendar_path) {
                                                        calendar.is_visible = !calendar.is_visible;
                                                        user_info.set(Some(info));
                                                    }
                                                }
                                            });
                                        }
                                    })}
                                    current_view={(*current_view).clone()}
                                    on_view_change={on_view_change}
                                    current_theme={(*current_theme).clone()}
                                    on_theme_change={on_theme_change}
                                    current_style={(*current_style).clone()}
                                    on_style_change={on_style_change}
                                    on_color_editor_open={on_color_editor_open}
                                />
                                <main class="app-main">
                                    <RouteHandler
                                        auth_token={(*auth_token).clone()}
                                        user_info={(*user_info).clone()}
                                        on_login={on_login.clone()}
                                        external_calendar_events={(*external_calendar_events).clone()}
                                        external_calendars={(*external_calendars).clone()}
                                        on_event_context_menu={Some(on_event_context_menu.clone())}
                                        on_calendar_context_menu={Some(on_calendar_date_context_menu.clone())}
                                        view={(*current_view).clone()}
                                        on_create_event_request={Some(on_event_create.clone())}
                                        on_event_update_request={Some(on_event_update.clone())}
                                        context_menus_open={any_context_menu_open}
                                    />
                                </main>
                            </>
                        }
                    } else {
                        html! {
                            <div class="login-layout">
                                <RouteHandler
                                    auth_token={(*auth_token).clone()}
                                    user_info={(*user_info).clone()}
                                    on_login={on_login.clone()}
                                    on_event_context_menu={Some(on_event_context_menu.clone())}
                                    on_calendar_context_menu={Some(on_calendar_date_context_menu.clone())}
                                    on_event_update_request={Some(on_event_update.clone())}
                                    on_create_event_request={Some(on_event_create.clone())}
                                    context_menus_open={any_context_menu_open}
                                />
                            </div>
                        }
                    }
                }

                <CalendarManagementModal
                    is_open={*calendar_management_modal_open}
                    on_close={Callback::from({
                        let calendar_management_modal_open = calendar_management_modal_open.clone();
                        move |_| calendar_management_modal_open.set(false)
                    })}
                    on_create_calendar={Callback::from({
                        let auth_token = auth_token.clone();
                        let refresh_calendars = refresh_calendars.clone();
                        let calendar_management_modal_open = calendar_management_modal_open.clone();
                        move |(name, description, color): (String, Option<String>, Option<String>)| {
                            if let Some(token) = (*auth_token).clone() {
                                let refresh_calendars = refresh_calendars.clone();
                                let calendar_management_modal_open = calendar_management_modal_open.clone();

                                wasm_bindgen_futures::spawn_local(async move {
                                    let calendar_service = CalendarService::new();

                                    let password = if let Ok(credentials_str) = LocalStorage::get::<String>("caldav_credentials") {
                                        if let Ok(credentials) = serde_json::from_str::<serde_json::Value>(&credentials_str) {
                                            credentials["password"].as_str().unwrap_or("").to_string()
                                        } else {
                                            String::new()
                                        }
                                    } else {
                                        String::new()
                                    };

                                    match calendar_service.create_calendar(&token, &password, name, description, color).await {
                                        Ok(_) => {
                                            web_sys::console::log_1(&"Calendar created successfully!".into());
                                            refresh_calendars.emit(());
                                            calendar_management_modal_open.set(false);
                                        }
                                        Err(err) => {
                                            web_sys::console::log_1(&format!("Failed to create calendar: {}", err).into());
                                            calendar_management_modal_open.set(false);
                                        }
                                    }
                                });
                            }
                        }
                    })}
                    on_external_success={Callback::from({
                        let external_calendars = external_calendars.clone();
                        let calendar_management_modal_open = calendar_management_modal_open.clone();
                        move |new_id: i32| {
                            // Refresh external calendars list
                            let external_calendars = external_calendars.clone();
                            let calendar_management_modal_open = calendar_management_modal_open.clone();

                            wasm_bindgen_futures::spawn_local(async move {
                                let _calendar_service = CalendarService::new();
                                match CalendarService::get_external_calendars().await {
                                    Ok(calendars) => {
                                        external_calendars.set(calendars);
                                        calendar_management_modal_open.set(false);
                                        web_sys::console::log_1(&format!("External calendar {} added successfully!", new_id).into());
                                    }
                                    Err(err) => {
                                        web_sys::console::error_1(&format!("Failed to refresh external calendars: {}", err).into());
                                        calendar_management_modal_open.set(false);
                                    }
                                }
                            });
                        }
                    })}
                    available_colors={available_colors.iter().map(|c| c.to_string()).collect::<Vec<_>>()}
                />

                <ContextMenu
                    is_open={*context_menu_open}
                    x={context_menu_pos.0}
                    y={context_menu_pos.1}
                    on_close={Callback::from({
                        let context_menu_open = context_menu_open.clone();
                        move |_| context_menu_open.set(false)
                    })}
                    on_delete={Callback::from({
                        let auth_token = auth_token.clone();
                        let context_menu_calendar_path = context_menu_calendar_path.clone();
                        let refresh_calendars = refresh_calendars.clone();
                        move |_: MouseEvent| {
                            if let (Some(token), Some(calendar_path)) = ((*auth_token).clone(), (*context_menu_calendar_path).clone()) {
                                let refresh_calendars = refresh_calendars.clone();

                                wasm_bindgen_futures::spawn_local(async move {
                                    let calendar_service = CalendarService::new();

                                    let password = if let Ok(credentials_str) = LocalStorage::get::<String>("caldav_credentials") {
                                        if let Ok(credentials) = serde_json::from_str::<serde_json::Value>(&credentials_str) {
                                            credentials["password"].as_str().unwrap_or("").to_string()
                                        } else {
                                            String::new()
                                        }
                                    } else {
                                        String::new()
                                    };

                                    match calendar_service.delete_calendar(&token, &password, calendar_path).await {
                                        Ok(_) => {
                                            web_sys::console::log_1(&"Calendar deleted successfully!".into());
                                            refresh_calendars.emit(());
                                        }
                                        Err(err) => {
                                            web_sys::console::log_1(&format!("Failed to delete calendar: {}", err).into());
                                        }
                                    }
                                });
                            }
                        }
                    })}
                />

                <EventContextMenu
                    is_open={*event_context_menu_open}
                    x={event_context_menu_pos.0}
                    y={event_context_menu_pos.1}
                    event={(*event_context_menu_event).clone()}
                    on_close={Callback::from({
                        let event_context_menu_open = event_context_menu_open.clone();
                        move |_| event_context_menu_open.set(false)
                    })}
                    on_edit={Callback::from({
                        let _event_context_menu_event = event_context_menu_event.clone();
                        let event_context_menu_open = event_context_menu_open.clone();
                        let create_event_modal_open = create_event_modal_open.clone();
                        let event_edit_scope = event_edit_scope.clone();
                        move |edit_action: EditAction| {
                            // Set the edit scope and close the context menu
                            event_edit_scope.set(Some(edit_action));
                            event_context_menu_open.set(false);
                            create_event_modal_open.set(true);
                        }
                    })}
                    on_delete={Callback::from({
                        let auth_token = auth_token.clone();
                        let event_context_menu_event = event_context_menu_event.clone();
                        let event_context_menu_open = event_context_menu_open.clone();
                        let refresh_calendar_data = refresh_calendar_data.clone();
                        move |delete_action: DeleteAction| {
                            if let (Some(token), Some(event)) = ((*auth_token).clone(), (*event_context_menu_event).clone()) {
                                let refresh_calendar_data = refresh_calendar_data.clone();
                                let event_context_menu_open = event_context_menu_open.clone();

                                // Log the delete action for now - we'll implement different behaviors later
                                match delete_action {
                                    DeleteAction::DeleteThis => web_sys::console::log_1(&"Delete this event".into()),
                                    DeleteAction::DeleteFollowing => web_sys::console::log_1(&"Delete following events".into()),
                                    DeleteAction::DeleteSeries => web_sys::console::log_1(&"Delete entire series".into()),
                                }

                                let refresh_callback = refresh_calendar_data.clone();
                                wasm_bindgen_futures::spawn_local(async move {
                                    let calendar_service = CalendarService::new();

                                    let password = if let Ok(credentials_str) = LocalStorage::get::<String>("caldav_credentials") {
                                        if let Ok(credentials) = serde_json::from_str::<serde_json::Value>(&credentials_str) {
                                            credentials["password"].as_str().unwrap_or("").to_string()
                                        } else {
                                            String::new()
                                        }
                                    } else {
                                        String::new()
                                    };

                                    if let (Some(calendar_path), Some(event_href)) = (&event.calendar_path, &event.href) {
                                        // Convert delete action to string and get occurrence date
                                        let action_str = match delete_action {
                                            DeleteAction::DeleteThis => "delete_this".to_string(),
                                            DeleteAction::DeleteFollowing => "delete_following".to_string(),
                                            DeleteAction::DeleteSeries => "delete_series".to_string(),
                                        };

                                        // Get the occurrence date from the clicked event
                                        let occurrence_date = Some(event.dtstart.date().format("%Y-%m-%d").to_string());

                                        web_sys::console::log_1(&format!("🔄 Delete action: {}", action_str).into());
                                        web_sys::console::log_1(&format!("🔄 Event UID: {}", event.uid).into());
                                        web_sys::console::log_1(&format!("🔄 Event start: {}", event.dtstart).into());
                                        web_sys::console::log_1(&format!("🔄 Occurrence date: {:?}", occurrence_date).into());

                                        match calendar_service.delete_event(
                                            &token,
                                            &password,
                                            calendar_path.clone(),
                                            event_href.clone(),
                                            action_str,
                                            occurrence_date
                                        ).await {
                                            Ok(message) => {
                                                web_sys::console::log_1(&format!("Delete response: {}", message).into());

                                                // Show the message to the user to explain what actually happened
                                                if message.contains("Warning") {
                                                    web_sys::window().unwrap().alert_with_message(&message).unwrap();
                                                }

                                                // Close the context menu
                                                event_context_menu_open.set(false);
                                                // Refresh calendar data without page reload
                                                refresh_callback.emit(());
                                            }
                                            Err(err) => {
                                                web_sys::console::log_1(&format!("Failed to delete event: {}", err).into());
                                                web_sys::window().unwrap().alert_with_message(&format!("Failed to delete event: {}", err)).unwrap();
                                            }
                                        }
                                    } else {
                                        web_sys::console::log_1(&"Missing calendar_path or href - cannot delete event".into());
                                    }
                                });
                            }
                        }
                    })}
                    on_edit_singleton={Callback::from({
                        let event_context_menu_event = event_context_menu_event.clone();
                        let event_context_menu_open = event_context_menu_open.clone();
                        let create_event_modal_open = create_event_modal_open.clone();
                        let event_edit_scope = event_edit_scope.clone();
                        move |event: VEvent| {
                            // For singleton events, open edit modal WITHOUT setting edit_scope
                            event_context_menu_event.set(Some(event));
                            event_edit_scope.set(None); // Explicitly set to None for singleton edits
                            event_context_menu_open.set(false);
                            create_event_modal_open.set(true);
                        }
                    })}
                    on_view_details={Callback::from({
                        let event_context_menu_open = event_context_menu_open.clone();
                        let view_event_modal_open = view_event_modal_open.clone();
                        let view_event_modal_event = view_event_modal_event.clone();
                        move |event: VEvent| {
                            // Set the event for viewing (read-only mode)
                            view_event_modal_event.set(Some(event));
                            event_context_menu_open.set(false);
                            view_event_modal_open.set(true);
                        }
                    })}
                />

                <CalendarContextMenu
                    is_open={*calendar_context_menu_open}
                    x={calendar_context_menu_pos.0}
                    y={calendar_context_menu_pos.1}
                    on_close={Callback::from({
                        let calendar_context_menu_open = calendar_context_menu_open.clone();
                        move |_| calendar_context_menu_open.set(false)
                    })}
                    on_create_event={on_create_event_click}
                />

                <CreateEventModal
                    is_open={*create_event_modal_open}
                    selected_date={(*selected_date_for_event).clone()}
                    initial_start_time={None}
                    initial_end_time={None}
                    event_to_edit={(*event_context_menu_event).clone()}
                    edit_scope={(*event_edit_scope).clone()}
                    on_close={Callback::from({
                        let create_event_modal_open = create_event_modal_open.clone();
                        let event_context_menu_event = event_context_menu_event.clone();
                        let event_edit_scope = event_edit_scope.clone();
                        move |_| {
                            create_event_modal_open.set(false);
                            // Clear the event being edited and edit scope
                            event_context_menu_event.set(None);
                            event_edit_scope.set(None);
                        }
                    })}
                    on_create={on_event_create}
                    available_calendars={user_info.as_ref().map(|ui| ui.calendars.clone()).unwrap_or_default()}
                />


                <EventModal
                    event={if *view_event_modal_open { (*view_event_modal_event).clone() } else { None }}
                    on_close={Callback::from({
                        let view_event_modal_open = view_event_modal_open.clone();
                        let view_event_modal_event = view_event_modal_event.clone();
                        move |_| {
                            view_event_modal_open.set(false);
                            view_event_modal_event.set(None);
                        }
                    })}
                />
                
                // Mobile warning modal
                <MobileWarningModal
                    is_open={*mobile_warning_open}
                    on_close={on_mobile_warning_close}
                />

                // Color editor modal
                <ColorEditorModal
                    is_open={*color_editor_open}
                    current_color={color_editor_data.as_ref().map(|(_, color)| color.clone()).unwrap_or_default()}
                    color_index={color_editor_data.as_ref().map(|(index, _)| *index).unwrap_or(0)}
                    default_color={
                        let default_colors = get_default_event_colors();
                        let index = color_editor_data.as_ref().map(|(index, _)| *index).unwrap_or(0);
                        default_colors.get(index).cloned().unwrap_or_else(|| "#3B82F6".to_string())
                    }
                    on_close={on_color_editor_close}
                    on_save={on_color_editor_save}
                    on_reset_all={on_color_editor_reset_all}
                />
            </div>
            
            // Hidden print copy that gets shown only during printing
            <div id="print-preview-copy" class="print-preview-paper" style="display: none;"></div>
        </BrowserRouter>
    }
}
