use crate::constants::common::*;
use crate::window::WindowLabel;
use parking_lot::Mutex;
use std::collections::HashMap;
use tauri::{AppHandle, Manager, Runtime};

// 使用lazy_static宏创建全局静态变量，用于存储各个窗口的缩放因子
// parking_lot::Mutex 确保线程安全，性能更佳，不会返回 Result
// HashMap存储窗口标签和对应的缩放因子
lazy_static::lazy_static! {
    /// 全局窗口缩放因子映射表
    /// key: 窗口标签(WindowLabel)
    /// value: 缩放因子(f64)
    static ref WINDOW_SCALE_FACTORS: Mutex<HashMap<WindowLabel, f64>> = Mutex::new(HashMap::new());
}

/// 获取指定窗口的当前缩放级别
///
/// # 参数
/// * `window_label` - 窗口标签
///
/// # 返回值
/// 返回窗口当前的缩放因子，默认为1.0(100%)
fn get_window_scale(window_label: WindowLabel) -> f64 {
    WINDOW_SCALE_FACTORS.lock().get(&window_label).copied().unwrap_or(DEFAULT_SCALE_FACTOR)
}

/// 设置指定窗口的缩放级别
///
/// # 参数
/// * `window_label` - 窗口标签
/// * `scale` - 新的缩放因子
fn set_window_scale(window_label: WindowLabel, scale: f64) {
    let mut scales = WINDOW_SCALE_FACTORS.lock();
    scales.insert(window_label, scale);
}

/// 处理窗口放大事件
///
/// # 功能说明
/// 1. 获取主窗口对象
/// 2. 获取当前窗口缩放级别
/// 3. 计算新的缩放级别(增加5%)
/// 4. 限制最大缩放为2倍(200%)
/// 5. 更新窗口缩放级别并应用到窗口
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_zoom_in<R: Runtime>(app: &AppHandle<R>) {
    // 获取标签为"main"的窗口对象
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label) {
        let window_label = WindowLabel::MAIN;

        // 在异步运行时中执行缩放逻辑，避免阻塞主线程
        tauri::async_runtime::spawn(async move {
            // 获取当前窗口缩放级别
            let current_scale = get_window_scale(window_label);

            // 计算新的缩放级别 (每次放大5%)
            let new_scale = current_scale * ZOOM_IN_MULTIPLIER;

            // 限制最大缩放为2倍
            let clamped_scale = new_scale.min(MAX_ZOOM_LEVEL);

            // 设置新的缩放级别
            set_window_scale(window_label, clamped_scale);

            // 应用缩放到窗口
            if let Err(e) = window.set_zoom(clamped_scale) {
                log::error!("设置窗口缩放失败: {}", e);
            }
        });
    }
}

/// 处理窗口缩小事件
///
/// # 功能说明
/// 1. 获取主窗口对象
/// 2. 获取当前窗口缩放级别
/// 3. 计算新的缩放级别(减少5%)
/// 4. 限制最小缩放为0.8倍(80%)
/// 5. 更新窗口缩放级别并应用到窗口
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_zoom_out<R: Runtime>(app: &AppHandle<R>) {
    // 获取标签为"main"的窗口对象
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label) {
        let window_label = WindowLabel::MAIN;

        // 在异步运行时中执行缩放逻辑，避免阻塞主线程
        tauri::async_runtime::spawn(async move {
            // 获取当前窗口缩放级别
            let current_scale = get_window_scale(window_label);

            // 计算新的缩放级别 (每次缩小5%)
            let new_scale = current_scale * ZOOM_OUT_MULTIPLIER;

            // 限制最小缩放为0.8倍
            let clamped_scale = new_scale.max(MIN_ZOOM_LEVEL);

            // 设置新的缩放级别
            set_window_scale(window_label, clamped_scale);

            // 应用缩放到窗口
            if let Err(e) = window.set_zoom(clamped_scale) {
                log::error!("设置窗口缩放失败: {}", e);
            }
        });
    }
}

/// 处理窗口重置缩放事件
///
/// # 功能说明
/// 1. 获取主窗口对象
/// 2. 将窗口缩放级别重置为默认值(1.0)
/// 3. 更新窗口缩放级别并应用到窗口
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_zoom_reset<R: Runtime>(app: &AppHandle<R>) {
    // 获取标签为"main"的窗口对象
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label) {
        let window_label = WindowLabel::MAIN;

        // 在异步运行时中执行缩放逻辑，避免阻塞主线程
        tauri::async_runtime::spawn(async move {
            // 重置缩放为1.0 (默认大小)
            set_window_scale(window_label, DEFAULT_SCALE_FACTOR);

            if let Err(e) = window.set_zoom(DEFAULT_SCALE_FACTOR) {
                log::error!("重置窗口缩放失败: {}", e);
            }
        });
    }
}

/// 处理窗口最小化事件
///
/// # 功能说明
/// 将主窗口最小化到任务栏或dock
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_minimize<R: Runtime>(app: &AppHandle<R>) {
    // 获取标签为"main"的窗口对象
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label) {
        // 在异步运行时中执行最小化操作，避免阻塞主线程
        tauri::async_runtime::spawn(async move {
            if let Err(e) = window.minimize() {
                log::error!("最小化窗口失败: {}", e);
            }
        });
    }
}

/// 处理窗口还原事件
///
/// # 功能说明
/// 将主窗口从最小化状态还原到正常状态
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_restore<R: Runtime>(app: &AppHandle<R>) {
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label) {
        tauri::async_runtime::spawn(async move {
            if let Err(e) = window.unminimize() {
                log::error!("还原窗口失败: {}", e);
            }
        });
    }
}

/// 处理窗口最大化事件
///
/// # 功能说明
/// 切换主窗口的最大化状态
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_maximize<R: Runtime>(app: &AppHandle<R>) {
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label) {
        // 切换最大化状态
        match window.is_maximized() {
            Ok(is_maximized) => {
                if let Err(e) = if is_maximized { window.unmaximize() } else { window.maximize() } {
                    log::error!("切换窗口最大化状态失败: {}", e);
                }
            }
            Err(e) => {
                log::error!("获取窗口最大化状态失败: {}", e);
            }
        }
    }
}

/// 处理窗口关闭事件
///
/// # 功能说明
/// 关闭主窗口
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_close<R: Runtime>(app: &AppHandle<R>) {
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label)
        && let Err(e) = window.close()
    {
        log::error!("关闭窗口失败: {}", e);
    }
}

/// 处理窗口全屏事件
///
/// # 功能说明
/// 切换主窗口的全屏状态
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_fullscreen<R: Runtime>(app: &AppHandle<R>) {
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label) {
        // 切换全屏状态
        match window.is_fullscreen() {
            Ok(is_fullscreen) => {
                if let Err(e) = window.set_fullscreen(!is_fullscreen) {
                    log::error!("切换窗口全屏状态失败: {}", e);
                }
            }
            Err(e) => {
                log::error!("获取窗口全屏状态失败: {}", e);
            }
        }
    }
}

/// 处理窗口刷新事件
///
/// # 功能说明
/// 刷新主窗口的页面内容
///
/// # 参数
/// * `app` - Tauri应用句柄
pub fn handle_refresh<R: Runtime>(app: &AppHandle<R>) {
    let label = WindowLabel::MAIN.as_ref();
    if let Some(window) = app.get_webview_window(label)
        && let Err(e) = window.eval("window.location.reload()")
    {
        log::error!("刷新页面失败: {}", e);
    }
}
