//! 通信协议定义

use crate::types::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// 消息类型标识
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
#[repr(u8)]
pub enum MessageType {
    // 认证相关 (0x00 - 0x0F)
    AuthRequest = 0x00,
    AuthResponse = 0x01,
    AuthChallenge = 0x02,
    AuthVerify = 0x03,

    // 信令相关 (0x10 - 0x1F)
    SignalOffer = 0x10,
    SignalAnswer = 0x11,
    SignalCandidate = 0x12,
    SignalReady = 0x13,

    // 连接相关 (0x20 - 0x2F)
    ConnectRequest = 0x20,
    ConnectAccept = 0x21,
    ConnectReject = 0x22,
    Disconnect = 0x23,
    Heartbeat = 0x24,
    HeartbeatAck = 0x25,

    // 数据传输 (0x30 - 0x3F)
    FrameData = 0x30,
    FrameAck = 0x31,
    InputEvent = 0x32,
    AudioData = 0x33,
    ClipboardData = 0x34,
    FileTransfer = 0x35,

    // 控制相关 (0x40 - 0x4F)
    QualityRequest = 0x40,
    QualityResponse = 0x41,
    ScreenInfo = 0x42,
    SessionControl = 0x43,

    // 错误 (0xF0 - 0xFF)
    Error = 0xF0,
}

/// 协议消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProtocolMessage {
    /// 消息ID
    pub id: u64,
    /// 消息类型
    pub msg_type: MessageType,
    /// 消息负载
    pub payload: Vec<u8>,
    /// 时间戳
    pub timestamp: i64,
}

impl ProtocolMessage {
    pub fn new(msg_type: MessageType, payload: Vec<u8>) -> Self {
        use chrono::Utc;
        Self {
            id: rand::random(),
            msg_type,
            payload,
            timestamp: Utc::now().timestamp_millis(),
        }
    }

    pub fn encode(&self) -> crate::Result<Vec<u8>> {
        bincode::serialize(self).map_err(Into::into)
    }

    pub fn decode(data: &[u8]) -> crate::Result<Self> {
        bincode::deserialize(data).map_err(Into::into)
    }
}

// ==================== 认证消息 ====================

/// 认证请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthRequest {
    pub device_id: DeviceId,
    pub verification_code: String,
}

/// 认证响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthResponse {
    pub success: bool,
    pub session_token: Option<String>,
    pub error: Option<String>,
}

// ==================== 信令消息 ====================

/// SDP Offer
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SignalOffer {
    pub session_id: Uuid,
    pub from_device: DeviceId,
    pub to_device: DeviceId,
    pub sdp: String,
}

/// SDP Answer
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SignalAnswer {
    pub session_id: Uuid,
    pub from_device: DeviceId,
    pub to_device: DeviceId,
    pub sdp: String,
}

/// ICE Candidate
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SignalCandidate {
    pub session_id: Uuid,
    pub from_device: DeviceId,
    pub to_device: DeviceId,
    pub candidate: String,
    pub sdp_mid: Option<String>,
    pub sdp_mline_index: Option<u32>,
}

// ==================== 连接消息 ====================

/// 连接请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectRequest {
    pub session_id: Uuid,
    pub from_device: DeviceId,
    pub to_device: DeviceId,
    pub verification_code: String,
    pub quality_settings: QualitySettings,
}

/// 连接接受
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectAccept {
    pub session_id: Uuid,
    pub screen_width: u32,
    pub screen_height: u32,
    pub connection_type: ConnectionType,
}

/// 连接拒绝
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectReject {
    pub session_id: Uuid,
    pub reason: String,
}

// ==================== 数据传输消息 ====================

/// 视频帧数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FrameData {
    /// 帧序号
    pub frame_id: u64,
    /// 是否为关键帧
    pub is_keyframe: bool,
    /// 帧宽度
    pub width: u32,
    /// 帧高度
    pub height: u32,
    /// 编码格式
    pub format: FrameFormat,
    /// 帧数据
    pub data: Vec<u8>,
    /// 时间戳
    pub timestamp: i64,
}

/// 帧编码格式
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum FrameFormat {
    /// JPEG
    Jpeg,
    /// VP8
    Vp8,
    /// VP9
    Vp9,
    /// H264
    H264,
    /// H265
    H265,
    /// Raw RGBA
    RawRgba,
}

/// 输入事件
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum InputEvent {
    /// 鼠标移动
    MouseMove { x: i32, y: i32 },
    /// 鼠标按下
    MouseDown { button: MouseButton, x: i32, y: i32 },
    /// 鼠标释放
    MouseUp { button: MouseButton, x: i32, y: i32 },
    /// 鼠标滚轮
    MouseScroll { delta_x: i32, delta_y: i32 },
    /// 键盘按下
    KeyDown { key: String, modifiers: Modifiers },
    /// 键盘释放
    KeyUp { key: String, modifiers: Modifiers },
    /// 文本输入
    TextInput { text: String },
}

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

/// 修饰键状态
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
pub struct Modifiers {
    pub ctrl: bool,
    pub alt: bool,
    pub shift: bool,
    pub meta: bool,
}

/// 剪贴板数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClipboardData {
    pub format: ClipboardFormat,
    pub data: Vec<u8>,
}

/// 剪贴板格式
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum ClipboardFormat {
    Text,
    Html,
    Image,
    Files,
}

// ==================== 控制消息 ====================

/// 质量调整请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct QualityRequest {
    pub settings: QualitySettings,
}

/// 屏幕信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScreenInfo {
    pub monitors: Vec<MonitorInfo>,
    pub primary_index: usize,
}

/// 显示器信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MonitorInfo {
    pub index: usize,
    pub name: String,
    pub width: u32,
    pub height: u32,
    pub x: i32,
    pub y: i32,
    pub is_primary: bool,
    pub scale_factor: f32,
}

/// 会话控制命令
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SessionControl {
    /// 请求控制权
    RequestControl,
    /// 释放控制权
    ReleaseControl,
    /// 切换显示器
    SwitchMonitor { index: usize },
    /// 锁定屏幕
    LockScreen,
    /// 重启
    Restart,
    /// 关机
    Shutdown,
}

// ==================== 错误消息 ====================

/// 错误消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ErrorMessage {
    pub code: u32,
    pub message: String,
}
