use crate::components::{Login, ViewMode};
use crate::models::ical::VEvent;
use crate::services::calendar_service::{UserInfo, ExternalCalendar};
use yew::prelude::*;
use yew_router::prelude::*;

#[derive(Clone, Routable, PartialEq)]
pub enum Route {
    #[at("/")]
    Home,
    #[at("/login")]
    Login,
    #[at("/calendar")]
    Calendar,
}

#[derive(Properties, PartialEq)]
pub struct RouteHandlerProps {
    pub auth_token: Option<String>,
    pub user_info: Option<UserInfo>,
    pub on_login: Callback<String>,
    #[prop_or_default]
    pub external_calendar_events: Vec<VEvent>,
    #[prop_or_default]
    pub external_calendars: Vec<ExternalCalendar>,
    #[prop_or_default]
    pub on_event_context_menu: Option<Callback<(web_sys::MouseEvent, VEvent)>>,
    #[prop_or_default]
    pub on_calendar_context_menu: Option<Callback<(web_sys::MouseEvent, chrono::NaiveDate)>>,
    #[prop_or_default]
    pub view: ViewMode,
    #[prop_or_default]
    pub on_create_event_request: Option<Callback<crate::components::EventCreationData>>,
    #[prop_or_default]
    pub on_event_update_request: Option<
        Callback<(
            VEvent,
            chrono::NaiveDateTime,
            chrono::NaiveDateTime,
            bool,
            Option<chrono::NaiveDateTime>,
            Option<String>,
            Option<String>,
        )>,
    >,
    #[prop_or_default]
    pub context_menus_open: bool,
}

#[function_component(RouteHandler)]
pub fn route_handler(props: &RouteHandlerProps) -> Html {
    let auth_token = props.auth_token.clone();
    let user_info = props.user_info.clone();
    let on_login = props.on_login.clone();
    let external_calendar_events = props.external_calendar_events.clone();
    let external_calendars = props.external_calendars.clone();
    let on_event_context_menu = props.on_event_context_menu.clone();
    let on_calendar_context_menu = props.on_calendar_context_menu.clone();
    let view = props.view.clone();
    let on_create_event_request = props.on_create_event_request.clone();
    let on_event_update_request = props.on_event_update_request.clone();
    let context_menus_open = props.context_menus_open;

    html! {
        <Switch<Route> render={move |route| {
            let auth_token = auth_token.clone();
            let user_info = user_info.clone();
            let on_login = on_login.clone();
            let external_calendar_events = external_calendar_events.clone();
            let external_calendars = external_calendars.clone();
            let on_event_context_menu = on_event_context_menu.clone();
            let on_calendar_context_menu = on_calendar_context_menu.clone();
            let view = view.clone();
            let on_create_event_request = on_create_event_request.clone();
            let on_event_update_request = on_event_update_request.clone();
            let context_menus_open = context_menus_open;

            match route {
                Route::Home => {
                    if auth_token.is_some() {
                        html! { <Redirect<Route> to={Route::Calendar}/> }
                    } else {
                        html! { <Redirect<Route> to={Route::Login}/> }
                    }
                }
                Route::Login => {
                    if auth_token.is_some() {
                        html! { <Redirect<Route> to={Route::Calendar}/> }
                    } else {
                        html! { <Login {on_login} /> }
                    }
                }
                Route::Calendar => {
                    if auth_token.is_some() {
                        html! {
                            <CalendarView
                                user_info={user_info}
                                external_calendar_events={external_calendar_events}
                                external_calendars={external_calendars}
                                on_event_context_menu={on_event_context_menu}
                                on_calendar_context_menu={on_calendar_context_menu}
                                view={view}
                                on_create_event_request={on_create_event_request}
                                on_event_update_request={on_event_update_request}
                                context_menus_open={context_menus_open}
                            />
                        }
                    } else {
                        html! { <Redirect<Route> to={Route::Login}/> }
                    }
                }
            }
        }} />
    }
}

#[derive(Properties, PartialEq)]
pub struct CalendarViewProps {
    pub user_info: Option<UserInfo>,
    #[prop_or_default]
    pub external_calendar_events: Vec<VEvent>,
    #[prop_or_default]
    pub external_calendars: Vec<ExternalCalendar>,
    #[prop_or_default]
    pub on_event_context_menu: Option<Callback<(web_sys::MouseEvent, VEvent)>>,
    #[prop_or_default]
    pub on_calendar_context_menu: Option<Callback<(web_sys::MouseEvent, chrono::NaiveDate)>>,
    #[prop_or_default]
    pub view: ViewMode,
    #[prop_or_default]
    pub on_create_event_request: Option<Callback<crate::components::EventCreationData>>,
    #[prop_or_default]
    pub on_event_update_request: Option<
        Callback<(
            VEvent,
            chrono::NaiveDateTime,
            chrono::NaiveDateTime,
            bool,
            Option<chrono::NaiveDateTime>,
            Option<String>,
            Option<String>,
        )>,
    >,
    #[prop_or_default]
    pub context_menus_open: bool,
}

use crate::components::Calendar;

#[function_component(CalendarView)]
pub fn calendar_view(props: &CalendarViewProps) -> Html {
    html! {
        <div class="calendar-view">
            <Calendar
                user_info={props.user_info.clone()}
                external_calendar_events={props.external_calendar_events.clone()}
                external_calendars={props.external_calendars.clone()}
                on_event_context_menu={props.on_event_context_menu.clone()}
                on_calendar_context_menu={props.on_calendar_context_menu.clone()}
                view={props.view.clone()}
                on_create_event_request={props.on_create_event_request.clone()}
                on_event_update_request={props.on_event_update_request.clone()}
                context_menus_open={props.context_menus_open}
            />
        </div>
    }
}
