use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Mutex;
use std::time::Duration;

use tauri::{AppHandle, Manager};

/// 钉子按钮在窗口内的热区（逻辑像素，相对窗口客户区左上角）
#[derive(Clone, Copy, Default)]
struct Hotzone {
    x: f64,
    y: f64,
    w: f64,
    h: f64,
    active: bool,
}

static HOTZONE: Mutex<Hotzone> = Mutex::new(Hotzone {
    x: 0.0,
    y: 0.0,
    w: 0.0,
    h: 0.0,
    active: false,
});
static POLLING: AtomicBool = AtomicBool::new(false);

/// 前端布局变化时更新钉子按钮热区坐标
pub fn set_hotzone(x: f64, y: f64, width: f64, height: f64, active: bool) {
    if let Ok(mut hz) = HOTZONE.lock() {
        *hz = Hotzone {
            x,
            y,
            w: width,
            h: height,
            active,
        };
    }
}

/// 开启/关闭钉子模式；开启时后台轮询鼠标位置，仅在热区内恢复窗口接收点击
pub fn set_pin_mode(app: &AppHandle, on: bool) -> Result<(), String> {
    if on {
        if let Some(win) = app.get_webview_window("main") {
            // 默认先穿透，等热区上报后再由轮询精确切换
            win.set_ignore_cursor_events(true)
                .map_err(|e| e.to_string())?;
        }
        start_polling(app.clone());
    } else {
        stop_polling();
        if let Ok(mut hz) = HOTZONE.lock() {
            hz.active = false;
        }
        if let Some(win) = app.get_webview_window("main") {
            win.set_ignore_cursor_events(false)
                .map_err(|e| e.to_string())?;
        }
    }
    Ok(())
}

fn start_polling(app: AppHandle) {
    if POLLING.swap(true, Ordering::SeqCst) {
        return;
    }
    std::thread::spawn(move || {
        while POLLING.load(Ordering::SeqCst) {
            poll_once(&app);
            std::thread::sleep(Duration::from_millis(32));
        }
    });
}

fn stop_polling() {
    POLLING.store(false, Ordering::SeqCst);
}

fn poll_once(app: &AppHandle) {
    let hz = match HOTZONE.lock() {
        Ok(h) => *h,
        Err(_) => return,
    };
    let Some(win) = app.get_webview_window("main") else {
        return;
    };

    if !hz.active || hz.w <= 0.0 || hz.h <= 0.0 {
        let _ = win.set_ignore_cursor_events(true);
        return;
    }

    let (cursor_x, cursor_y) = match cursor_screen_position() {
        Some(p) => p,
        None => return,
    };

    let Some(win_pos) = win.outer_position().ok() else {
        return;
    };

    // 热区为前端 getBoundingClientRect 的逻辑像素；光标与窗口位置为物理像素
    let scale = win.scale_factor().unwrap_or(1.0);
    let local_x = (cursor_x - win_pos.x as f64) / scale;
    let local_y = (cursor_y - win_pos.y as f64) / scale;

    let in_hotzone = local_x >= hz.x
        && local_x <= hz.x + hz.w
        && local_y >= hz.y
        && local_y <= hz.y + hz.h;

    let _ = win.set_ignore_cursor_events(!in_hotzone);
}

#[cfg(target_os = "windows")]
fn cursor_screen_position() -> Option<(f64, f64)> {
    use windows::Win32::Foundation::POINT;
    use windows::Win32::UI::WindowsAndMessaging::GetCursorPos;

    let mut pt = POINT::default();
    unsafe {
        GetCursorPos(&mut pt).ok()?;
    }
    Some((pt.x as f64, pt.y as f64))
}

#[cfg(not(target_os = "windows"))]
fn cursor_screen_position() -> Option<(f64, f64)> {
    None
}
