//! 输入控制模块

use anyhow::Result;
use enigo::{Enigo, Key, Keyboard, Mouse, Direction, Settings, Coordinate};
use easyremote_common::protocol::{InputEvent, MouseButton as ProtoMouseButton, Modifiers};

/// 鼠标按钮
#[derive(Debug, Clone, Copy)]
pub enum MouseButton {
    Left,
    Right,
    Middle,
}

/// 输入控制器
pub struct InputController {
    enigo: Enigo,
    screen_width: i32,
    screen_height: i32,
}

impl InputController {
    /// 创建新的输入控制器（带屏幕尺寸）
    pub fn with_screen_size(screen_width: u32, screen_height: u32) -> Self {
        Self {
            enigo: Enigo::new(&Settings::default()).unwrap(),
            screen_width: screen_width as i32,
            screen_height: screen_height as i32,
        }
    }
    
    /// 创建新的输入控制器（默认屏幕尺寸）
    pub fn new() -> Result<Self> {
        Ok(Self {
            enigo: Enigo::new(&Settings::default())?,
            screen_width: 1920,
            screen_height: 1080,
        })
    }
    
    /// 移动鼠标
    pub fn move_mouse(&mut self, x: i32, y: i32) -> Result<()> {
        self.enigo.move_mouse(x, y, Coordinate::Abs)?;
        Ok(())
    }
    
    /// 点击鼠标
    pub fn click(&mut self, button: MouseButton) -> Result<()> {
        self.enigo.button(convert_simple_mouse_button(button), Direction::Click)?;
        Ok(())
    }
    
    /// 鼠标按下
    pub fn mouse_down(&mut self, button: MouseButton) -> Result<()> {
        self.enigo.button(convert_simple_mouse_button(button), Direction::Press)?;
        Ok(())
    }
    
    /// 鼠标释放
    pub fn mouse_up(&mut self, button: MouseButton) -> Result<()> {
        self.enigo.button(convert_simple_mouse_button(button), Direction::Release)?;
        Ok(())
    }
    
    /// 滚动
    pub fn scroll(&mut self, delta_x: i32, delta_y: i32) -> Result<()> {
        if delta_y != 0 {
            self.enigo.scroll(delta_y, enigo::Axis::Vertical)?;
        }
        if delta_x != 0 {
            self.enigo.scroll(delta_x, enigo::Axis::Horizontal)?;
        }
        Ok(())
    }
    
    /// 按键按下
    pub fn key_down(&mut self, key: &str) -> Result<()> {
        if let Some(k) = parse_key(key) {
            self.enigo.key(k, Direction::Press)?;
        }
        Ok(())
    }
    
    /// 按键释放
    pub fn key_up(&mut self, key: &str) -> Result<()> {
        if let Some(k) = parse_key(key) {
            self.enigo.key(k, Direction::Release)?;
        }
        Ok(())
    }

    /// 处理输入事件
    pub fn handle_event(&mut self, event: InputEvent) -> Result<()> {
        match event {
            InputEvent::MouseMove { x, y } => {
                let _ = self.enigo.move_mouse(x, y, Coordinate::Abs);
            }
            InputEvent::MouseDown { button, x, y } => {
                let _ = self.enigo.move_mouse(x, y, Coordinate::Abs);
                let _ = self.enigo.button(convert_mouse_button(button), Direction::Press);
            }
            InputEvent::MouseUp { button, x, y } => {
                let _ = self.enigo.move_mouse(x, y, Coordinate::Abs);
                let _ = self.enigo.button(convert_mouse_button(button), Direction::Release);
            }
            InputEvent::MouseScroll { delta_x, delta_y } => {
                if delta_y != 0 {
                    let _ = self.enigo.scroll(delta_y, enigo::Axis::Vertical);
                }
                if delta_x != 0 {
                    let _ = self.enigo.scroll(delta_x, enigo::Axis::Horizontal);
                }
            }
            InputEvent::KeyDown { key, modifiers } => {
                self.handle_modifiers_down(&modifiers);
                if let Some(k) = parse_key(&key) {
                    let _ = self.enigo.key(k, Direction::Press);
                }
            }
            InputEvent::KeyUp { key, modifiers } => {
                if let Some(k) = parse_key(&key) {
                    let _ = self.enigo.key(k, Direction::Release);
                }
                self.handle_modifiers_up(&modifiers);
            }
            InputEvent::TextInput { text } => {
                let _ = self.enigo.text(&text);
            }
        }
        Ok(())
    }

    fn handle_modifiers_down(&mut self, modifiers: &Modifiers) {
        if modifiers.ctrl {
            let _ = self.enigo.key(Key::Control, Direction::Press);
        }
        if modifiers.alt {
            let _ = self.enigo.key(Key::Alt, Direction::Press);
        }
        if modifiers.shift {
            let _ = self.enigo.key(Key::Shift, Direction::Press);
        }
        if modifiers.meta {
            let _ = self.enigo.key(Key::Meta, Direction::Press);
        }
    }

    fn handle_modifiers_up(&mut self, modifiers: &Modifiers) {
        if modifiers.meta {
            let _ = self.enigo.key(Key::Meta, Direction::Release);
        }
        if modifiers.shift {
            let _ = self.enigo.key(Key::Shift, Direction::Release);
        }
        if modifiers.alt {
            let _ = self.enigo.key(Key::Alt, Direction::Release);
        }
        if modifiers.ctrl {
            let _ = self.enigo.key(Key::Control, Direction::Release);
        }
    }

    /// 更新屏幕尺寸
    pub fn set_screen_size(&mut self, width: u32, height: u32) {
        self.screen_width = width as i32;
        self.screen_height = height as i32;
    }
}

fn convert_mouse_button(button: ProtoMouseButton) -> enigo::Button {
    match button {
        ProtoMouseButton::Left => enigo::Button::Left,
        ProtoMouseButton::Right => enigo::Button::Right,
        ProtoMouseButton::Middle => enigo::Button::Middle,
        ProtoMouseButton::Back => enigo::Button::Back,
        ProtoMouseButton::Forward => enigo::Button::Forward,
    }
}

fn convert_simple_mouse_button(button: MouseButton) -> enigo::Button {
    match button {
        MouseButton::Left => enigo::Button::Left,
        MouseButton::Right => enigo::Button::Right,
        MouseButton::Middle => enigo::Button::Middle,
    }
}

fn parse_key(key: &str) -> Option<Key> {
    // 处理常见的键名
    match key.to_lowercase().as_str() {
        // 功能键
        "escape" | "esc" => Some(Key::Escape),
        "f1" => Some(Key::F1),
        "f2" => Some(Key::F2),
        "f3" => Some(Key::F3),
        "f4" => Some(Key::F4),
        "f5" => Some(Key::F5),
        "f6" => Some(Key::F6),
        "f7" => Some(Key::F7),
        "f8" => Some(Key::F8),
        "f9" => Some(Key::F9),
        "f10" => Some(Key::F10),
        "f11" => Some(Key::F11),
        "f12" => Some(Key::F12),
        
        // 控制键
        "tab" => Some(Key::Tab),
        "capslock" => Some(Key::CapsLock),
        "shift" => Some(Key::Shift),
        "control" | "ctrl" => Some(Key::Control),
        "alt" => Some(Key::Alt),
        "meta" | "win" | "cmd" | "command" => Some(Key::Meta),
        "space" | " " => Some(Key::Space),
        "enter" | "return" => Some(Key::Return),
        "backspace" => Some(Key::Backspace),
        "delete" | "del" => Some(Key::Delete),
        "home" => Some(Key::Home),
        "end" => Some(Key::End),
        "pageup" | "pgup" => Some(Key::PageUp),
        "pagedown" | "pgdn" => Some(Key::PageDown),
        
        // 方向键
        "arrowup" | "up" => Some(Key::UpArrow),
        "arrowdown" | "down" => Some(Key::DownArrow),
        "arrowleft" | "left" => Some(Key::LeftArrow),
        "arrowright" | "right" => Some(Key::RightArrow),
        
        // 单字符 - 使用 Unicode
        s if s.len() == 1 => {
            let c = s.chars().next().unwrap();
            Some(Key::Unicode(c))
        }
        
        _ => None,
    }
}

/// 生成输入事件
pub struct InputEventGenerator;

impl InputEventGenerator {
    /// 生成鼠标移动事件
    pub fn mouse_move(x: i32, y: i32) -> InputEvent {
        InputEvent::MouseMove { x, y }
    }

    /// 生成鼠标按下事件
    pub fn mouse_down(button: ProtoMouseButton, x: i32, y: i32) -> InputEvent {
        InputEvent::MouseDown { button, x, y }
    }

    /// 生成鼠标释放事件
    pub fn mouse_up(button: ProtoMouseButton, x: i32, y: i32) -> InputEvent {
        InputEvent::MouseUp { button, x, y }
    }

    /// 生成鼠标点击事件（按下+释放）
    pub fn mouse_click(button: ProtoMouseButton, x: i32, y: i32) -> Vec<InputEvent> {
        vec![
            InputEvent::MouseDown { button, x, y },
            InputEvent::MouseUp { button, x, y },
        ]
    }

    /// 生成鼠标滚轮事件
    pub fn mouse_scroll(delta_x: i32, delta_y: i32) -> InputEvent {
        InputEvent::MouseScroll { delta_x, delta_y }
    }

    /// 生成键盘按下事件
    pub fn key_down(key: String, modifiers: Modifiers) -> InputEvent {
        InputEvent::KeyDown { key, modifiers }
    }

    /// 生成键盘释放事件
    pub fn key_up(key: String, modifiers: Modifiers) -> InputEvent {
        InputEvent::KeyUp { key, modifiers }
    }

    /// 生成文本输入事件
    pub fn text_input(text: String) -> InputEvent {
        InputEvent::TextInput { text }
    }
}
