use crate::components::{ViewMode, WeekView, MonthView};
use crate::models::ical::VEvent;
use crate::services::calendar_service::{UserInfo, ExternalCalendar};
use chrono::NaiveDate;
use std::collections::HashMap;
use wasm_bindgen::{closure::Closure, JsCast};
use yew::prelude::*;

#[derive(Properties, PartialEq)]
pub struct PrintPreviewModalProps {
    pub on_close: Callback<()>,
    pub view_mode: ViewMode,
    pub current_date: NaiveDate,
    pub selected_date: NaiveDate,
    pub events: HashMap<NaiveDate, Vec<VEvent>>,
    pub user_info: Option<UserInfo>,
    pub external_calendars: Vec<ExternalCalendar>,
    pub time_increment: u32,
    pub today: NaiveDate,
}

#[function_component]
pub fn PrintPreviewModal(props: &PrintPreviewModalProps) -> Html {
    let start_hour = use_state(|| 6u32);
    let end_hour = use_state(|| 22u32);
    let zoom_level = use_state(|| 0.4f64); // Default 40% zoom

    let close_modal = {
        let on_close = props.on_close.clone();
        Callback::from(move |_| {
            on_close.emit(());
        })
    };

    let backdrop_click = {
        let on_close = props.on_close.clone();
        Callback::from(move |e: MouseEvent| {
            if e.target() == e.current_target() {
                on_close.emit(());
            }
        })
    };

    let on_start_hour_change = {
        let start_hour = start_hour.clone();
        let end_hour = end_hour.clone();
        Callback::from(move |e: Event| {
            let target = e.target_dyn_into::<web_sys::HtmlSelectElement>();
            if let Some(select) = target {
                if let Ok(hour) = select.value().parse::<u32>() {
                    if hour < *end_hour {
                        start_hour.set(hour);
                    }
                }
            }
        })
    };

    let on_end_hour_change = {
        let start_hour = start_hour.clone();
        let end_hour = end_hour.clone();
        Callback::from(move |e: Event| {
            let target = e.target_dyn_into::<web_sys::HtmlSelectElement>();
            if let Some(select) = target {
                if let Ok(hour) = select.value().parse::<u32>() {
                    if hour > *start_hour && hour <= 24 {
                        end_hour.set(hour);
                    }
                }
            }
        })
    };

    let on_print = {
        let start_hour = *start_hour;
        let end_hour = *end_hour;
        let view_mode = props.view_mode.clone();
        Callback::from(move |_: MouseEvent| {
            if let Some(window) = web_sys::window() {
                if let Some(document) = window.document() {
                    if let Some(body) = document.body() {
                        // Add print attributes to body for CSS targeting
                        if view_mode == ViewMode::Week {
                            let _ = body.set_attribute("data-print-start-hour", &start_hour.to_string());
                            let _ = body.set_attribute("data-print-end-hour", &end_hour.to_string());
                        }
                        let _ = body.set_attribute("data-print-mode", "true");

                        // Trigger print
                        if let Err(e) = window.print() {
                            web_sys::console::log_1(&format!("Print failed: {:?}", e).into());
                        }

                        // Clean up attributes after a short delay
                        let cleanup_body = body.clone();
                        let cleanup_callback = Closure::wrap(Box::new(move || {
                            let _ = cleanup_body.remove_attribute("data-print-start-hour");
                            let _ = cleanup_body.remove_attribute("data-print-end-hour");
                            let _ = cleanup_body.remove_attribute("data-print-mode");
                        }) as Box<dyn FnMut()>);

                        let _ = window.set_timeout_with_callback_and_timeout_and_arguments_0(
                            cleanup_callback.as_ref().unchecked_ref(),
                            1000
                        );
                        cleanup_callback.forget();
                    }
                }
            }
        })
    };

    let format_hour = |hour: u32| -> String {
        if hour == 0 {
            "12 AM".to_string()
        } else if hour < 12 {
            format!("{} AM", hour)
        } else if hour == 12 {
            "12 PM".to_string()
        } else {
            format!("{} PM", hour - 12)
        }
    };

    // Calculate dynamic base unit for print preview
    let calculate_print_dimensions = |start_hour: u32, end_hour: u32, time_increment: u32| -> (f64, f64, f64) {
        let visible_hours = (end_hour - start_hour) as f64;
        let slots_per_hour = if time_increment == 15 { 4.0 } else { 2.0 };
        let header_height = 50.0; // Fixed week header height in print preview
        let header_border = 2.0;   // Week header bottom border (2px solid)
        let container_spacing = 8.0; // Additional container spacing/margins
        let total_overhead = header_height + header_border + container_spacing;
        let available_height = 720.0 - total_overhead; // Available for time content
        let base_unit = available_height / (visible_hours * slots_per_hour);
        let pixels_per_hour = base_unit * slots_per_hour;
        
        (base_unit, pixels_per_hour, available_height)
    };

    // Calculate print dimensions for the current hour range
    let (base_unit, pixels_per_hour, _available_height) = calculate_print_dimensions(*start_hour, *end_hour, props.time_increment);
    

    html! {
        <div class="modal-backdrop print-preview-modal-backdrop" onclick={backdrop_click}>
            <div class="modal-content print-preview-modal">
                <div class="modal-header">
                    <h3>{"Print Preview"}</h3>
                    <button class="modal-close" onclick={close_modal.clone()}>{"×"}</button>
                </div>
                <div class="modal-body print-preview-body">
                    <div class="print-preview-controls">
                        {
                            if props.view_mode == ViewMode::Week {
                                html! {
                                    <>
                                        <div class="control-group">
                                            <label for="start-hour">{"Start Hour:"}</label>
                                            <select id="start-hour" onchange={on_start_hour_change}>
                                                {
                                                    (0..24).map(|hour| {
                                                        html! {
                                                            <option value={hour.to_string()} selected={hour == *start_hour}>
                                                                {format_hour(hour)}
                                                            </option>
                                                        }
                                                    }).collect::<Html>()
                                                }
                                            </select>
                                        </div>
                                        <div class="control-group">
                                            <label for="end-hour">{"End Hour:"}</label>
                                            <select id="end-hour" onchange={on_end_hour_change}>
                                                {
                                                    (1..=24).map(|hour| {
                                                        html! {
                                                            <option value={hour.to_string()} selected={hour == *end_hour}>
                                                                {if hour == 24 { "12 AM".to_string() } else { format_hour(hour) }}
                                                            </option>
                                                        }
                                                    }).collect::<Html>()
                                                }
                                            </select>
                                        </div>
                                        <div class="hour-range-info">
                                            {format!("Will print from {} to {}", 
                                                format_hour(*start_hour), 
                                                if *end_hour == 24 { "12 AM".to_string() } else { format_hour(*end_hour) }
                                            )}
                                        </div>
                                    </>
                                }
                            } else {
                                html! {
                                    <div class="month-info">
                                        {"Will print entire month view"}
                                    </div>
                                }
                            }
                        }
                        <div class="zoom-display-info">
                            <label>{"Zoom: "}</label>
                            <span>{format!("{}%", (*zoom_level * 100.0) as i32)}</span>
                            <span class="zoom-hint">{"(scroll to zoom)"}</span>
                        </div>
                        <div class="preview-actions">
                            <button class="btn-primary" onclick={on_print}>{"Print"}</button>
                            <button class="btn-secondary" onclick={close_modal}>{"Cancel"}</button>
                        </div>
                    </div>
                    <div class="print-preview-display" onwheel={{
                        let zoom_level = zoom_level.clone();
                        Callback::from(move |e: WheelEvent| {
                            e.prevent_default(); // Prevent page scroll
                            let delta_y = e.delta_y();
                            let zoom_change = if delta_y < 0.0 { 1.1 } else { 1.0 / 1.1 };
                            let new_zoom = (*zoom_level * zoom_change).clamp(0.2, 1.5);
                            zoom_level.set(new_zoom);
                        })
                    }}>
                        <div class="print-preview-paper" 
                                     data-start-hour={start_hour.to_string()} 
                                     data-end-hour={end_hour.to_string()}
                                     style={format!(
                                         "--print-start-hour: {}; --print-end-hour: {}; --print-base-unit: {:.2}; --print-pixels-per-hour: {:.2}; transform: scale({}); transform-origin: top center;", 
                                         *start_hour, *end_hour, base_unit, pixels_per_hour, *zoom_level
                                     )}>
                            <div class="print-preview-content">
                                {
                                    match props.view_mode {
                                        ViewMode::Week => html! {
                                            <WeekView
                                                key={format!("week-preview-{}-{}", *start_hour, *end_hour)}
                                                current_date={props.current_date}
                                                today={props.today}
                                                events={props.events.clone()}
                                                on_event_click={Callback::noop()}
                                                user_info={props.user_info.clone()}
                                                external_calendars={props.external_calendars.clone()}
                                                time_increment={props.time_increment}
                                                print_mode={true}
                                                print_pixels_per_hour={Some(pixels_per_hour)}
                                                print_start_hour={Some(*start_hour)}
                                            />
                                        },
                                        ViewMode::Month => html! {
                                            <MonthView
                                                key={format!("month-preview-{}-{}", *start_hour, *end_hour)}
                                                current_month={props.current_date}
                                                selected_date={Some(props.selected_date)}
                                                today={props.today}
                                                events={props.events.clone()}
                                                on_day_select={None::<Callback<NaiveDate>>}
                                                on_event_click={Callback::noop()}
                                                user_info={props.user_info.clone()}
                                                external_calendars={props.external_calendars.clone()}
                                            />
                                        },
                                    }
                                }
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    }
}