use crate::audio::play_prompt_tone_imp;
use crate::window::{WindowLabel, create_popup_window::create_popup_window_impl, derive::TargetLocation};
use tauri::{AppHandle, Runtime, tray::TrayIconBuilder};

/// 创建并设置系统托盘图标
///
/// 该函数会检查是否已存在相同ID的托盘图标以避免重复添加，
/// 并为托盘图标绑定点击事件处理函数，点击时直接打开弹出框窗口。
pub fn setup_tray<R: Runtime>(app: &AppHandle<R>) -> Result<(), String> {
    let tray_id = WindowLabel::MAIN_TRAY.as_ref();
    // 检查是否已经存在托盘图标，避免重复添加
    if app.tray_by_id(tray_id).is_some() {
        return Ok(());
    }

    // 获取默认窗口图标
    let icon = app.default_window_icon().ok_or("获取默认窗口图标失败")?.clone();

    // 创建托盘图标（不关联菜单）
    use std::sync::Arc;
    let app_shared = Arc::new(app.clone());
    TrayIconBuilder::with_id(tray_id)
        .icon(icon)
        .tooltip("智评会议")
        .on_tray_icon_event(move |_tray, event| {
            // 处理托盘图标点击事件
            if let tauri::tray::TrayIconEvent::Click {
                button_state: tauri::tray::MouseButtonState::Up,
                rect,
                ..
            } = event
            {
                let app_handle = Arc::clone(&app_shared);
                // 如果popup窗口不存在，则创建并显示弹出框窗口
                tauri::async_runtime::spawn(async move {
                    // 获取主显示器的缩放因子
                    let scale_factor = (*app_handle).primary_monitor().ok().flatten().map(|monitor| monitor.scale_factor()).unwrap_or(1.0);

                    let target = get_target_location(&rect, scale_factor);

                    // 直接调用后端函数创建弹出框窗口
                    let _ = create_popup_window_impl(&app_handle, &target, "auto").await;
                    play_prompt_tone_imp();
                });
            }
        })
        .build(app)
        .map_err(|e| format!("创建托盘图标失败: {}", e))?;

    // 托盘图标创建成功
    Ok(())
}

/**
 * 获取目标位置信息
 */
fn get_target_location(rect: &tauri::Rect, scale_factor: f64) -> TargetLocation {
    // 使用scale_factor将物理坐标转换为逻辑坐标
    // 在托盘图标的上下文中，默认使用1.0作为scale_factor
    // 这样可以确保返回的坐标始终是逻辑坐标

    let x = match rect.position {
        tauri::Position::Physical(physical_position) => (physical_position.x as f64 / scale_factor) as i32,
        tauri::Position::Logical(logical_position) => logical_position.x as i32,
    };

    let y = match rect.position {
        tauri::Position::Physical(physical_position) => (physical_position.y as f64 / scale_factor) as i32,
        tauri::Position::Logical(logical_position) => logical_position.y as i32,
    };

    let width = match rect.size {
        tauri::Size::Physical(physical_size) => (physical_size.width as f64 / scale_factor) as u32,
        tauri::Size::Logical(logical_size) => logical_size.width as u32,
    };

    let height = match rect.size {
        tauri::Size::Physical(physical_size) => (physical_size.height as f64 / scale_factor) as u32,
        tauri::Size::Logical(logical_size) => logical_size.height as u32,
    };

    TargetLocation { x, y, width, height }
}
