#pragma once
#include "misc/delegates.h"
#include <Eigen/Eigen>

#include "misc/key_type/key_type.h"

class platform_window {
public:
	platform_window(int32_t in_width, int32_t in_height, const wchar_t* in_title);
    /**
     * @brief 显示窗口
     */
    void show();

    /**
     * @brief 隐藏窗口
     */
    void hide();

    /**
     * @brief 关闭窗口
     */
    void close();

    /**
     * @brief 最大化窗口
     */
    void maximize();

    /**
     * @brief 最小化窗口
     */
    void minimize();

	/**
	 * @brief 是否可见
	 */
	bool is_visible() const;

	//-------------- 窗口位置和大小 --------------

    /**
     * @brief 调整窗口大小
     * @param width 新宽度
     * @param height 新高度
     */
    void resize(int width, int height);

    /**
     * @brief 调整窗口大小
     * @param size 新大小向量
     */
    void resize(const Eigen::Vector2i& size) { resize(size.x(), size.y()); }

    /**
     * @brief 移动窗口
     * @param x 新的X坐标
     * @param y 新的Y坐标
     */
    void move(int x, int y);

    /**
     * @brief 移动窗口
     * @param pos 新位置向量
     */
    void move(const Eigen::Vector2i& pos) { move(pos.x(), pos.y()); }

    //-------------- 窗口属性获取 --------------

    /**
     * @brief 获取窗口大小
     * @return 窗口大小向量
     */
    [[nodiscard]] Eigen::Vector2i get_window_size() const;

    /**
     * @brief 获取窗口位置
     * @return 窗口位置向量
     */
    [[nodiscard]] Eigen::Vector2i get_window_position() const;

    /**
     * @brief 获取窗口框架大小
     * @return 窗口框架大小向量
     */
    [[nodiscard]] Eigen::Vector2i get_window_frame_size() const;

    /**
     * @brief 获取DPI缩放系数
     * @return DPI缩放系数
     */
    [[nodiscard]] float get_window_dpi_scale() const;

    /**
     * @brief 获取窗口句柄
     * @return 原生窗口句柄
     */
    [[nodiscard]] void* get_window_handle() const;

    //-------------- 窗口样式设置 --------------

    /**
     * @brief 设置窗口标题
     * @param title 新标题
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_title(const wchar_t* title);

    /**
     * @brief 设置是否有最小化按钮
     * @param has_minimize_button 是否有最小化按钮
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_has_minimize_button(bool has_minimize_button);

    /**
     * @brief 设置是否有最大化按钮
     * @param has_maximize_button 是否有最大化按钮
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_has_maximize_button(bool has_maximize_button);

    /**
     * @brief 设置是否有关闭按钮
     * @param has_close_button 是否有关闭按钮
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_has_close_button(bool has_close_button);

    /**
     * @brief 设置是否有边框
     * @param has_border 是否有边框
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_has_border(bool has_border);

    /**
     * @brief 设置是否有标题栏
     * @param has_caption 是否有标题栏
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_has_caption(bool has_caption);

    /**
     * @brief 设置是否有可调整大小的边框
     * @param has_resizable_border 是否有可调整大小的边框
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_has_resizable_border(bool has_resizable_border);

    /**
     * @brief 设置窗口是否总在最前
     * @param is_topmost 是否总在最前
     * @return 窗口对象引用，用于链式调用
     */
    platform_window& set_topmost(bool is_topmost);

    //-------------- 事件处理 --------------

    /**
     * @brief 处理鼠标移动事件
     * @param in_window_pos 窗口位置
     */
    void handle_mouse_move(const Eigen::Vector2f& in_window_pos);

    /**
     * @brief 处理鼠标按下事件
     * @param in_window_pos 窗口位置
     * @param in_button 按下的按钮
     */
    void handle_mouse_button_down(const Eigen::Vector2f& in_window_pos, mouse_button in_button);

    /**
     * @brief 处理鼠标释放事件
     * @param in_window_pos 窗口位置
     * @param in_button 释放的按钮
     */
    void handle_mouse_button_up(const Eigen::Vector2f& in_window_pos, mouse_button in_button);

	/**
	 * @brief 处理鼠标双击事件
	 * @param pos 窗口位置
	 * @param button 按下的按钮
	 */
	void handle_mouse_dbl_click(const Eigen::Vector2f& pos, mouse_button button);

	/**
	 * @brief 处理鼠标滚轮事件
	 * @param pos 窗口位置
	 * @param delta 滚轮事件
	 */
	void handle_mouse_wheel(const Eigen::Vector2f& pos, wheel_event delta);

	/**
	 * @brief 处理光标移出窗口事件
	 */
	void handle_mouse_leave();

	/**
     * @brief 轮询所有窗口的事件
     * @return 如果有活动窗口则返回true
     *
     * 静态方法，处理所有窗口的事件队列。
     */
    static bool poll_events();

    /**
     * @brief 获取所有窗口的列表
     * @return 窗口指针列表
     *
     * 静态方法，返回所有已创建窗口的列表。
     */
    static const std::vector<platform_window*>& get_windows();

    /**
     * @brief 处理窗口大小改变事件
     * @param width 新宽度
     * @param height 新高度
     */
    void on_resize(int width, int height);

    /**
     * @brief 处理窗口移动事件
     * @param x 新的X坐标
     * @param y 新的Y坐标
     */
    void on_move(int x, int y);

	multicast_delegate<const Eigen::Vector2i&> on_move_delegate;
	multicast_delegate<const Eigen::Vector2i&> on_resize_delegate;
	multicast_delegate<platform_window*> on_close_delegate;

	multicast_delegate<const Eigen::Vector2f&> on_mouse_move_delegate;
	multicast_delegate<const Eigen::Vector2f&, mouse_button> on_mouse_button_down_delegate;
	multicast_delegate<const Eigen::Vector2f&, mouse_button> on_mouse_button_up_delegate;
	multicast_delegate<const Eigen::Vector2f&, mouse_button> on_mouse_button_dbl_delegate;
	multicast_delegate<const Eigen::Vector2f&, wheel_event> on_mouse_wheel_delegate;
	multicast_delegate<> on_mouse_leave_delegate;
private:
    /** 原生窗口句柄 */
    void* window_handle_{};
};
