use std::collections::HashSet;
use winit::event::MouseButton;
use winit::keyboard::KeyCode;
use crate::math::Vec2;

/// 입력 상태 - 순수 데이터 구조체 (읽기 전용)
#[derive(Debug, Clone)]
pub struct InputState {
    // 키보드 상태
    pub(crate) keys_down: HashSet<KeyCode>,
    pub(crate) keys_pressed_this_frame: HashSet<KeyCode>,
    pub(crate) keys_released_this_frame: HashSet<KeyCode>,
    
    // 마우스 상태
    pub(crate) mouse_position: Vec2,
    pub(crate) mouse_delta: Vec2,
    pub(crate) mouse_buttons_down: HashSet<MouseButton>,
    pub(crate) mouse_buttons_pressed_this_frame: HashSet<MouseButton>,
    pub(crate) mouse_buttons_released_this_frame: HashSet<MouseButton>,
    pub(crate) mouse_wheel_delta: f32,
}

impl InputState {
    pub(crate) fn new() -> Self {
        Self {
            keys_down: HashSet::new(),
            keys_pressed_this_frame: HashSet::new(),
            keys_released_this_frame: HashSet::new(),
            mouse_position: Vec2::zero(),
            mouse_delta: Vec2::zero(),
            mouse_buttons_down: HashSet::new(),
            mouse_buttons_pressed_this_frame: HashSet::new(),
            mouse_buttons_released_this_frame: HashSet::new(),
            mouse_wheel_delta: 0.0,
        }
    }
    
    // ========== Polling API - 키보드 ==========
    
    /// 현재 프레임에 키가 눌려있는지 확인 (연속 입력)
    pub fn is_key_down(&self, key: KeyCode) -> bool {
        self.keys_down.contains(&key)
    }
    
    /// 이번 프레임에 키가 새로 눌렸는지 확인 (단일 입력)
    pub fn is_key_just_pressed(&self, key: KeyCode) -> bool {
        self.keys_pressed_this_frame.contains(&key)
    }
    
    /// 이번 프레임에 키가 떼졌는지 확인
    pub fn is_key_just_released(&self, key: KeyCode) -> bool {
        self.keys_released_this_frame.contains(&key)
    }
    
    // ========== Polling API - 마우스 ==========
    
    /// 현재 마우스 위치 (픽셀 좌표)
    pub fn mouse_position(&self) -> Vec2 {
        self.mouse_position
    }
    
    /// 이번 프레임의 마우스 이동량
    pub fn mouse_delta(&self) -> Vec2 {
        self.mouse_delta
    }
    
    /// 마우스 버튼이 눌려있는지 확인
    pub fn is_mouse_button_down(&self, button: MouseButton) -> bool {
        self.mouse_buttons_down.contains(&button)
    }
    
    /// 이번 프레임에 마우스 버튼이 새로 눌렸는지 확인
    pub fn is_mouse_button_just_pressed(&self, button: MouseButton) -> bool {
        self.mouse_buttons_pressed_this_frame.contains(&button)
    }
    
    /// 이번 프레임에 마우스 버튼이 떼졌는지 확인
    pub fn is_mouse_button_just_released(&self, button: MouseButton) -> bool {
        self.mouse_buttons_released_this_frame.contains(&button)
    }
    
    /// 마우스 휠 스크롤량 (양수: 위, 음수: 아래)
    pub fn mouse_wheel_delta(&self) -> f32 {
        self.mouse_wheel_delta
    }
    
    // ========== 내부 상태 관리 ==========
    
    pub(crate) fn begin_frame(&mut self) {
        // 이전 프레임의 "just pressed/released" 초기화
        self.keys_pressed_this_frame.clear();
        self.keys_released_this_frame.clear();
        self.mouse_buttons_pressed_this_frame.clear();
        self.mouse_buttons_released_this_frame.clear();
    }
    
    pub(crate) fn end_frame(&mut self) {
        // 프레임 단위 값 초기화
        self.mouse_delta = Vec2::zero();
        self.mouse_wheel_delta = 0.0;
    }
}

impl Default for InputState {
    fn default() -> Self {
        Self::new()
    }
}
