#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

mod commands;
mod state;

use state::AppState;
use std::sync::Arc;
use tauri::{
    CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
    WindowEvent,
};
use tokio::sync::RwLock;

#[cfg(windows)]
mod single_instance {
    use windows::core::PCWSTR;
    use windows::Win32::Foundation::{CloseHandle, HANDLE, HWND, LPARAM, GetLastError, ERROR_ALREADY_EXISTS};
    use windows::Win32::System::Threading::CreateMutexW;
    use windows::Win32::UI::WindowsAndMessaging::{
        EnumWindows, GetWindowTextW, IsWindowVisible, SetForegroundWindow, ShowWindow, SW_RESTORE,
    };

    static MUTEX_NAME: &str = "Global\\EasyRemoteClientMutex";
    static WINDOW_TITLE: &str = "EasyRemote";

    pub struct SingleInstance {
        _handle: HANDLE,
    }

    impl SingleInstance {
        pub fn new() -> Option<Self> {
            unsafe {
                let mutex_name: Vec<u16> = MUTEX_NAME.encode_utf16().chain(std::iter::once(0)).collect();
                let handle = CreateMutexW(None, true, PCWSTR(mutex_name.as_ptr())).ok()?;

                if GetLastError() == ERROR_ALREADY_EXISTS {
                    // 已有实例在运行，尝试激活它
                    activate_existing_window();
                    let _ = CloseHandle(handle);
                    return None;
                }

                Some(Self { _handle: handle })
            }
        }
    }

    fn activate_existing_window() {
        unsafe {
            let _ = EnumWindows(Some(enum_window_callback), LPARAM(0));
        }
    }

    unsafe extern "system" fn enum_window_callback(hwnd: HWND, _: LPARAM) -> windows::Win32::Foundation::BOOL {
        if !IsWindowVisible(hwnd).as_bool() {
            return true.into();
        }

        let mut title = [0u16; 256];
        let len = GetWindowTextW(hwnd, &mut title);
        if len > 0 {
            let title_str = String::from_utf16_lossy(&title[..len as usize]);
            if title_str.contains(WINDOW_TITLE) {
                // 找到窗口，恢复并聚焦
                let _ = ShowWindow(hwnd, SW_RESTORE);
                let _ = SetForegroundWindow(hwnd);
                return false.into(); // 停止枚举
            }
        }
        true.into()
    }
}

#[cfg(not(windows))]
mod single_instance {
    use std::fs::File;
    use std::path::PathBuf;

    pub struct SingleInstance {
        _lock_file: File,
    }

    impl SingleInstance {
        pub fn new() -> Option<Self> {
            let lock_path = get_lock_path();
            
            // 尝试以独占方式打开锁文件
            match File::options()
                .write(true)
                .create(true)
                .truncate(true)
                .open(&lock_path)
            {
                Ok(file) => {
                    // 尝试获取文件锁
                    #[cfg(unix)]
                    {
                        use std::os::unix::io::AsRawFd;
                        let fd = file.as_raw_fd();
                        let result = unsafe {
                            libc::flock(fd, libc::LOCK_EX | libc::LOCK_NB)
                        };
                        if result != 0 {
                            eprintln!("EasyRemote 已在运行中");
                            return None;
                        }
                    }
                    Some(Self { _lock_file: file })
                }
                Err(_) => {
                    eprintln!("EasyRemote 已在运行中");
                    None
                }
            }
        }
    }

    fn get_lock_path() -> PathBuf {
        dirs::runtime_dir()
            .or_else(dirs::cache_dir)
            .unwrap_or_else(std::env::temp_dir)
            .join("easyremote.lock")
    }
}

fn main() {
    // 单例检查 - 确保只运行一个实例
    let _instance = match single_instance::SingleInstance::new() {
        Some(instance) => instance,
        None => {
            // 已有实例在运行，退出
            eprintln!("EasyRemote 客户端已在运行中，将激活现有窗口");
            return;
        }
    };

    // 初始化日志
    tracing_subscriber::fmt::init();

    // 创建应用状态
    let state = Arc::new(RwLock::new(AppState::new()));

    // 创建系统托盘菜单
    let tray_menu = SystemTrayMenu::new()
        .add_item(CustomMenuItem::new("show", "显示主窗口"))
        .add_native_item(SystemTrayMenuItem::Separator)
        .add_item(CustomMenuItem::new("quit", "退出"));

    let system_tray = SystemTray::new().with_menu(tray_menu);

    tauri::Builder::default()
        .system_tray(system_tray)
        .on_system_tray_event(|app, event| match event {
            SystemTrayEvent::LeftClick { .. } => {
                // 左键点击显示窗口
                if let Some(window) = app.get_window("main") {
                    let _ = window.show();
                    let _ = window.set_focus();
                }
            }
            SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
                "show" => {
                    if let Some(window) = app.get_window("main") {
                        let _ = window.show();
                        let _ = window.set_focus();
                    }
                }
                "quit" => {
                    std::process::exit(0);
                }
                _ => {}
            },
            _ => {}
        })
        .on_window_event(|event| {
            // 关闭窗口时的处理
            if let WindowEvent::CloseRequested { api, .. } = event.event() {
                let window = event.window();
                // 只有主窗口最小化到托盘，其他窗口（如远程控制窗口）直接关闭
                if window.label() == "main" {
                    window.hide().unwrap();
                    api.prevent_close();
                }
                // 远程控制窗口直接关闭（不阻止）
            }
        })
        .setup(|app| {
            // 设置窗口标题以便单例检测
            if let Some(window) = app.get_window("main") {
                let _ = window.set_title("EasyRemote");
                
                // 启动强制下线检测任务
                let window_clone = window.clone();
                std::thread::spawn(move || {
                    loop {
                        std::thread::sleep(std::time::Duration::from_millis(500));
                        
                        // 检查是否需要强制下线
                        if commands::check_force_offline() {
                            tracing::info!("执行强制下线，关闭应用");
                            // 关闭窗口并退出
                            let _ = window_clone.close();
                            break;
                        }
                    }
                });
            }
            Ok(())
        })
        .manage(state)
        .invoke_handler(tauri::generate_handler![
            // 初始化
            commands::initialize,
            // 设备信息
            commands::get_device_info,
            commands::refresh_verification_code,
            // 账号
            commands::login,
            commands::logout,
            commands::register,
            commands::get_current_user,
            // 设备管理
            commands::get_devices,
            commands::remove_device,
            // 连接
            commands::connect_to_device,
            commands::disconnect,
            commands::get_connection_state,
            commands::open_remote_window,
            // 历史记录
            commands::get_history,
            // 配置
            commands::get_config,
            commands::save_config,
            commands::reconnect_server,
            // 开机启动
            commands::get_autostart,
            commands::set_autostart,
            // 测试
            commands::test_local_input,
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
