use crate::components::CalendarListItem;
use crate::services::calendar_service::{UserInfo, ExternalCalendar};
use web_sys::HtmlSelectElement;
use yew::prelude::*;


#[derive(Clone, PartialEq)]
pub enum ViewMode {
    Month,
    Week,
}

#[derive(Clone, PartialEq)]
pub enum Theme {
    Default,
    Ocean,
    Forest,
    Sunset,
    Purple,
    Dark,
    Rose,
    Mint,
    Midnight,
    Charcoal,
    Nord,
    Dracula,
}

#[derive(Clone, PartialEq)]
pub enum Style {
    Default,
    Google,
    Apple,
}

impl Theme {
    pub fn value(&self) -> &'static str {
        match self {
            Theme::Default => "default",
            Theme::Ocean => "ocean",
            Theme::Forest => "forest",
            Theme::Sunset => "sunset",
            Theme::Purple => "purple",
            Theme::Dark => "dark",
            Theme::Rose => "rose",
            Theme::Mint => "mint",
            Theme::Midnight => "midnight",
            Theme::Charcoal => "charcoal",
            Theme::Nord => "nord",
            Theme::Dracula => "dracula",
        }
    }

    pub fn from_value(value: &str) -> Self {
        match value {
            "ocean" => Theme::Ocean,
            "forest" => Theme::Forest,
            "sunset" => Theme::Sunset,
            "purple" => Theme::Purple,
            "dark" => Theme::Dark,
            "rose" => Theme::Rose,
            "mint" => Theme::Mint,
            "midnight" => Theme::Midnight,
            "charcoal" => Theme::Charcoal,
            "nord" => Theme::Nord,
            "dracula" => Theme::Dracula,
            _ => Theme::Default,
        }
    }
}

impl Style {
    pub fn value(&self) -> &'static str {
        match self {
            Style::Default => "default",
            Style::Google => "google",
            Style::Apple => "apple",
        }
    }

    pub fn from_value(value: &str) -> Self {
        match value {
            "google" => Style::Google,
            "apple" => Style::Apple,
            _ => Style::Default,
        }
    }


    pub fn stylesheet_path(&self) -> Option<&'static str> {
        match self {
            Style::Default => None, // No additional stylesheet needed - uses base styles.css
            Style::Google => Some("google.css"), // Trunk copies to root level
            Style::Apple => Some("apple.css"), // Trunk copies to root level
        }
    }
}

impl Default for ViewMode {
    fn default() -> Self {
        ViewMode::Month
    }
}

#[derive(Properties, PartialEq)]
pub struct SidebarProps {
    pub user_info: Option<UserInfo>,
    pub on_logout: Callback<()>,
    pub on_add_calendar: Callback<()>,
    pub external_calendars: Vec<ExternalCalendar>,
    pub on_external_calendar_toggle: Callback<i32>,
    pub on_external_calendar_delete: Callback<i32>,
    pub on_external_calendar_refresh: Callback<i32>,
    pub color_picker_open: Option<String>,
    pub on_color_change: Callback<(String, String)>,
    pub on_color_picker_toggle: Callback<String>,
    pub available_colors: Vec<String>,
    pub on_color_editor_open: Callback<(usize, String)>, // (index, current_color)
    pub refreshing_calendar_id: Option<i32>,
    pub on_calendar_context_menu: Callback<(MouseEvent, String)>,
    pub on_calendar_visibility_toggle: Callback<String>,
    pub current_view: ViewMode,
    pub on_view_change: Callback<ViewMode>,
    pub current_theme: Theme,
    pub on_theme_change: Callback<Theme>,
    pub current_style: Style,
    pub on_style_change: Callback<Style>,
}

#[function_component(Sidebar)]
pub fn sidebar(props: &SidebarProps) -> Html {
    let external_context_menu_open = use_state(|| None::<i32>);
    let on_view_change = {
        let on_view_change = props.on_view_change.clone();
        Callback::from(move |e: Event| {
            let target = e.target_dyn_into::<HtmlSelectElement>();
            if let Some(select) = target {
                let value = select.value();
                let new_view = match value.as_str() {
                    "week" => ViewMode::Week,
                    _ => ViewMode::Month,
                };
                on_view_change.emit(new_view);
            }
        })
    };

    let on_theme_change = {
        let on_theme_change = props.on_theme_change.clone();
        Callback::from(move |e: Event| {
            let target = e.target_dyn_into::<HtmlSelectElement>();
            if let Some(select) = target {
                let value = select.value();
                let new_theme = Theme::from_value(&value);
                on_theme_change.emit(new_theme);
            }
        })
    };

    let on_style_change = {
        let on_style_change = props.on_style_change.clone();
        Callback::from(move |e: Event| {
            let target = e.target_dyn_into::<HtmlSelectElement>();
            if let Some(select) = target {
                let value = select.value();
                let new_style = Style::from_value(&value);
                on_style_change.emit(new_style);
            }
        })
    };

    let on_external_calendar_context_menu = {
        let external_context_menu_open = external_context_menu_open.clone();
        Callback::from(move |(e, cal_id): (MouseEvent, i32)| {
            e.prevent_default();
            external_context_menu_open.set(Some(cal_id));
        })
    };

    let on_external_calendar_delete = {
        let on_external_calendar_delete = props.on_external_calendar_delete.clone();
        let external_context_menu_open = external_context_menu_open.clone();
        Callback::from(move |cal_id: i32| {
            on_external_calendar_delete.emit(cal_id);
            external_context_menu_open.set(None);
        })
    };

    let close_external_context_menu = {
        let external_context_menu_open = external_context_menu_open.clone();
        Callback::from(move |_| {
            external_context_menu_open.set(None);
        })
    };

    html! {
        <aside class="app-sidebar">
            <div class="sidebar-header">
                <h1>{"Runway"}</h1>
                {
                    if let Some(ref info) = props.user_info {
                        html! {
                            <div class="user-info">
                                <div class="username">{&info.username}</div>
                                <div class="server-url">{&info.server_url}</div>
                            </div>
                        }
                    } else {
                        html! { <div class="user-info loading">{"Loading..."}</div> }
                    }
                }
            </div>
            {
                if let Some(ref info) = props.user_info {
                    if !info.calendars.is_empty() {
                        html! {
                            <div class="calendar-list">
                                <h3>{"My Calendars"}</h3>
                                <ul>
                                    {
                                        info.calendars.iter().map(|cal| {
                                            html! {
                                                <CalendarListItem
                                                    calendar={cal.clone()}
                                                    color_picker_open={props.color_picker_open.as_ref() == Some(&cal.path)}
                                                    on_color_change={props.on_color_change.clone()}
                                                    on_color_picker_toggle={props.on_color_picker_toggle.clone()}
                                                    available_colors={props.available_colors.clone()}
                                                    on_color_editor_open={props.on_color_editor_open.clone()}
                                                    on_context_menu={props.on_calendar_context_menu.clone()}
                                                    on_visibility_toggle={props.on_calendar_visibility_toggle.clone()}
                                                />
                                            }
                                        }).collect::<Html>()
                                    }
                                </ul>
                            </div>
                        }
                    } else {
                        html! { <div class="no-calendars">{"No calendars found"}</div> }
                    }
                } else {
                    html! {}
                }
            }
            
            // External calendars section
            <div class="external-calendar-list">
                <h3>{"External Calendars"}</h3>
                {
                    if !props.external_calendars.is_empty() {
                        html! {
                            <ul class="external-calendar-items">
                                {
                                    props.external_calendars.iter().map(|cal| {
                                        let on_toggle = {
                                            let on_external_calendar_toggle = props.on_external_calendar_toggle.clone();
                                            let cal_id = cal.id;
                                            Callback::from(move |_| {
                                                on_external_calendar_toggle.emit(cal_id);
                                            })
                                        };
                                        
                                        html! {
                                            <li class="external-calendar-item">
                                                <div 
                                                    class={if props.color_picker_open.as_ref() == Some(&format!("external_{}", cal.id)) { 
                                                        "external-calendar-info color-picker-active" 
                                                    } else { 
                                                        "external-calendar-info" 
                                                    }}
                                                    oncontextmenu={{
                                                        let on_context_menu = on_external_calendar_context_menu.clone();
                                                        let cal_id = cal.id;
                                                        Callback::from(move |e: MouseEvent| {
                                                            on_context_menu.emit((e, cal_id));
                                                        })
                                                    }}
                                                >
                                                    <input
                                                        type="checkbox"
                                                        checked={cal.is_visible}
                                                        onchange={on_toggle}
                                                    />
                                                    <span 
                                                        class="external-calendar-color" 
                                                        style={format!("background-color: {}", cal.color)}
                                                        onclick={{
                                                            let on_color_picker_toggle = props.on_color_picker_toggle.clone();
                                                            let external_id = format!("external_{}", cal.id);
                                                            Callback::from(move |e: MouseEvent| {
                                                                e.stop_propagation();
                                                                on_color_picker_toggle.emit(external_id.clone());
                                                            })
                                                        }}
                                                    >
                                                        {
                                                            if props.color_picker_open.as_ref() == Some(&format!("external_{}", cal.id)) {
                                                                html! {
                                                                    <div class="color-picker-dropdown">
                                                                        {
                                                                            props.available_colors.iter().map(|color| {
                                                                                let color_str = color.clone();
                                                                                let external_id = format!("external_{}", cal.id);
                                                                                let on_color_change = props.on_color_change.clone();
                                                                                
                                                                                let on_color_select = Callback::from(move |_: MouseEvent| {
                                                                                    on_color_change.emit((external_id.clone(), color_str.clone()));
                                                                                });

                                                                                let on_color_right_click = {
                                                                                    let on_color_editor_open = props.on_color_editor_open.clone();
                                                                                    let color_index = props.available_colors.iter().position(|c| c == color).unwrap_or(0);
                                                                                    let color_str = color.clone();
                                                                                    Callback::from(move |e: MouseEvent| {
                                                                                        e.prevent_default();
                                                                                        e.stop_propagation();
                                                                                        on_color_editor_open.emit((color_index, color_str.clone()));
                                                                                    })
                                                                                };
                                                                                
                                                                                let is_selected = cal.color == *color;
                                                                                
                                                                                html! {
                                                                                    <div
                                                                                        key={color.clone()}
                                                                                        class={if is_selected { "color-option selected" } else { "color-option" }}
                                                                                        style={format!("background-color: {}", color)}
                                                                                        onclick={on_color_select}
                                                                                        oncontextmenu={on_color_right_click}
                                                                                    />
                                                                                }
                                                                            }).collect::<Html>()
                                                                        }
                                                                    </div>
                                                                }
                                                            } else {
                                                                html! {}
                                                            }
                                                        }
                                                    </span>
                                                    <span class="external-calendar-name">{&cal.name}</span>
                                                    <div class="external-calendar-actions">
                                                        {
                                                            if let Some(last_fetched) = cal.last_fetched {
                                                                let local_time = last_fetched.with_timezone(&chrono::Local);
                                                                html! {
                                                                    <span class="last-updated" title={format!("Last updated: {}", local_time.format("%Y-%m-%d %H:%M"))}>
                                                                        {format!("{}", local_time.format("%H:%M"))}
                                                                    </span>
                                                                }
                                                            } else {
                                                                html! {
                                                                    <span class="last-updated">{"Never"}</span>
                                                                }
                                                            }
                                                        }
                                                        <button 
                                                            class="external-calendar-refresh-btn" 
                                                            title="Refresh calendar"
                                                            onclick={{
                                                                let on_refresh = props.on_external_calendar_refresh.clone();
                                                                let cal_id = cal.id;
                                                                Callback::from(move |e: MouseEvent| {
                                                                    e.stop_propagation();
                                                                    on_refresh.emit(cal_id);
                                                                })
                                                            }}
                                                            disabled={props.refreshing_calendar_id == Some(cal.id)}
                                                        >
                                                            {
                                                                if props.refreshing_calendar_id == Some(cal.id) {
                                                                    html! { <i class="fas fa-spinner fa-spin"></i> }
                                                                } else {
                                                                    html! { <i class="fas fa-sync-alt"></i> }
                                                                }
                                                            }
                                                        </button>
                                                    </div>
                                                </div>
                                                {
                                                    if *external_context_menu_open == Some(cal.id) {
                                                        html! {
                                                            <>
                                                                <div 
                                                                    class="context-menu-overlay" 
                                                                    onclick={close_external_context_menu.clone()}
                                                                    style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 999;"
                                                                />
                                                                <div class="context-menu" style="position: absolute; top: 0; right: 0; background: white; border: 1px solid #ccc; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); z-index: 1000; min-width: 120px;">
                                                                    <div 
                                                                        class="context-menu-item" 
                                                                        style="padding: 8px 12px; cursor: pointer; color: #d73a49;"
                                                                        onclick={{
                                                                            let on_delete = on_external_calendar_delete.clone();
                                                                            let cal_id = cal.id;
                                                                            Callback::from(move |_| {
                                                                                on_delete.emit(cal_id);
                                                                            })
                                                                        }}
                                                                    >
                                                                        {"Delete Calendar"}
                                                                    </div>
                                                                </div>
                                                            </>
                                                        }
                                                    } else {
                                                        html! {}
                                                    }
                                                }
                                            </li>
                                        }
                                    }).collect::<Html>()
                                }
                            </ul>
                        }
                    } else {
                        html! {}
                    }
                }
            </div>
            
            <div class="sidebar-footer">
                <button onclick={props.on_add_calendar.reform(|_| ())} class="add-calendar-button">
                    {"+ Add Calendar"}
                </button>

                <div class="view-selector">
                    <select class="view-selector-dropdown" onchange={on_view_change}>
                        <option value="month" selected={matches!(props.current_view, ViewMode::Month)}>{"Month"}</option>
                        <option value="week" selected={matches!(props.current_view, ViewMode::Week)}>{"Week"}</option>
                    </select>
                </div>

                <div class="theme-selector">
                    <select class="theme-selector-dropdown" onchange={on_theme_change}>
                        <option value="default" selected={matches!(props.current_theme, Theme::Default)}>{"Default"}</option>
                        <option value="ocean" selected={matches!(props.current_theme, Theme::Ocean)}>{"Ocean"}</option>
                        <option value="forest" selected={matches!(props.current_theme, Theme::Forest)}>{"Forest"}</option>
                        <option value="sunset" selected={matches!(props.current_theme, Theme::Sunset)}>{"Sunset"}</option>
                        <option value="purple" selected={matches!(props.current_theme, Theme::Purple)}>{"Purple"}</option>
                        <option value="dark" selected={matches!(props.current_theme, Theme::Dark)}>{"Dark"}</option>
                        <option value="rose" selected={matches!(props.current_theme, Theme::Rose)}>{"Rose"}</option>
                        <option value="mint" selected={matches!(props.current_theme, Theme::Mint)}>{"Mint"}</option>
                        <option value="midnight" selected={matches!(props.current_theme, Theme::Midnight)}>{"Midnight"}</option>
                        <option value="charcoal" selected={matches!(props.current_theme, Theme::Charcoal)}>{"Charcoal"}</option>
                        <option value="nord" selected={matches!(props.current_theme, Theme::Nord)}>{"Nord"}</option>
                        <option value="dracula" selected={matches!(props.current_theme, Theme::Dracula)}>{"Dracula"}</option>
                    </select>
                </div>

                <div class="style-selector">
                    <select class="style-selector-dropdown" onchange={on_style_change}>
                        <option value="default" selected={matches!(props.current_style, Style::Default)}>{"Default"}</option>
                        <option value="google" selected={matches!(props.current_style, Style::Google)}>{"Google Calendar"}</option>
                        <option value="apple" selected={matches!(props.current_style, Style::Apple)}>{"Apple Calendar"}</option>
                    </select>
                </div>

                <button onclick={props.on_logout.reform(|_| ())} class="logout-button">{"Logout"}</button>
            </div>
        </aside>
    }
}
