use crate::core::config::AppConfig;
use serde::{Deserialize, Serialize};

/// 消息信封：包含来源、目的地、消息体
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Envelope {
    pub from: String,
    pub to: Destination,
    pub message: Message,
}

/// 消息目的地
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Destination {
    /// 点对点发送给指定插件
    Plugin(String),
    /// 广播给所有插件
    Broadcast,
    /// 发给管理层自身
    Manager,
}

/// 所有插件间通信的类型安全消息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Message {
    // ── 播放控制 ──
    PlayerCommand(PlayerCommand),
    PlayerStatus(PlayerStatusData),
    Trigger {
        name: String,
        value: String,
    },
    StateChanged {
        old_state: String,
        new_state: String,
    },

    // ── 屏幕管理 ──
    ScreenLockRequest(bool),
    CursorVisibility(bool),

    // ── 网络 ──
    WifiCommand(WifiCommand),
    WifiResult(String),
    WifiProvisioned {
        ssid: String,
        ip: String,
    },

    // ── 配置 ──
    /// 配置重载广播需要经过 JSON/FFI 路径，因此这里保存可序列化的 AppConfig。
    ConfigReloaded(AppConfig),
    ConfigReloadRequest,

    // ── 系统 ──
    Shutdown,
    PluginReady(String),

    // ── 设备管理 ──
    DeviceCommand(DeviceCommand),
    DeviceResponse(DeviceResponse),
    DeviceEvent(DeviceEvent),

    // ── AI 语音对话 (M2.1) ──
    /// 语音/文字对话回合请求（HTTP → AI 插件）
    ChatRequest(ChatRequest),
    /// 对话回合响应（AI 插件 → HTTP/广播）
    ChatResponse(ChatResponse),
    /// AI 模型状态变更广播（加载/切换/下载进度）
    AiModelEvent(AiModelEvent),

    // ── 设备端字幕 (M2.1) ──
    /// 设备端 Live2D 字幕显示（AI 回复文字 Overlay）；HTTP 插件发出，live2d 插件消费
    Subtitle { text: String },

    // ── 扩展（未来插件用） ──
    Custom {
        kind: String,
        payload: String,
    },
}

/// 对话回合请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatRequest {
    /// 会话标识（同一会话保留上下文）
    pub session_id: String,
    /// 输入类型：文字或音频文件路径（设备临时文件）
    pub input: ChatInput,
    /// 当前角色人设 prompt
    pub persona_prompt: String,
    /// 最大回复 token 数（0 表示用默认）
    pub max_tokens: u16,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum ChatInput {
    /// 文字输入（Web 端主路径）
    Text { content: String },
    /// 音频文件路径（App 上传后的临时文件，16kHz mono wav）
    Audio { path: String },
}

/// 对话回合响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatResponse {
    pub session_id: String,
    /// ASR 转写文本（音频输入时，文字输入时为 None）
    pub transcription: Option<String>,
    /// LLM 回复文本
    pub reply_text: String,
    /// TTS 回复音频文件路径（设备临时文件，HTTP 返回后由客户端播放）
    pub reply_audio_path: Option<String>,
    /// 错误信息（非空表示失败）
    pub error: Option<String>,
}

/// AI 模型事件
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "event", rename_all = "snake_case")]
pub enum AiModelEvent {
    /// 模型加载中
    Loading { model_id: String },
    /// 模型已就绪
    Ready { model_id: String },
    /// 模型切换
    Switched { old: String, new: String },
    /// 下载进度
    DownloadProgress {
        model_id: String,
        downloaded: u64,
        total: u64,
    },
    /// 错误
    Error { model_id: String, message: String },
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum PlayerCommand {
    Play,
    Pause,
    Next,
    Previous,
    Goto(usize),
    ChangeScene(String),
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PlayerStatusData {
    pub running: bool,
    pub paused: bool,
    pub in_transition: bool,
    pub current_index: usize,
    pub playlist_length: usize,
    pub current_video: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum WifiCommand {
    Scan,
    Connect { ssid: String, password: String },
    Status,
    ApStart { ssid: String, password: String },
    ApStop,
}

// ── 设备管理 ──

/// 像素格式
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum PixelFormat {
    /// RGBA 8888 格式（每像素 4 字节）
    RGBA8888,
    /// RGB 888 格式（每像素 3 字节）
    RGB888,
    /// RGB 565 格式（每像素 2 字节）
    RGB565,
}

/// 传感器类型
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum SensorType {
    /// 温度传感器
    Temperature,
    /// 湿度传感器
    Humidity,
    /// 光线传感器
    Light,
    /// 接近传感器
    Proximity,
}

/// 触摸动作
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum TouchAction {
    /// 按下
    Down,
    /// 移动
    Move,
    /// 抬起
    Up,
}

/// 设备能力
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum DeviceCapability {
    /// 显示屏
    Display,
    /// 触摸屏
    Touch,
    /// 按钮
    Buttons,
    /// 音频
    Audio,
    /// 电池
    Battery,
    /// 背光
    Backlight,
    /// 传感器
    Sensors,
    /// 帧缓冲
    Framebuffer,
    /// GPIO
    GPIO,
    /// 光标控制能力
    Cursor,
}

/// 设备命令（业务插件 → DevicePlugin）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DeviceCommand {
    /// 获取显示信息
    GetDisplayInfo,
    /// 设置亮度（0-100）
    SetBrightness(u8),
    /// 设置背光开关
    SetBacklight(bool),
    /// 写入帧缓冲
    WriteFramebuffer { data: Vec<u8>, format: PixelFormat },
    /// 设置防息屏
    SetSleepInhibit(bool),
    /// 设置光标可见性
    /// - true: 显示光标
    /// - false: 隐藏光标（通过 unclutter 或平台特定方式）
    SetCursorVisible(bool),
    /// 获取电池电量
    GetBatteryLevel,
    /// 设置音量（0-100）
    SetVolume(u8),
    /// 播放音频
    PlayAudio { path: String },
    /// 获取触摸事件
    GetTouchEvents,
    /// 获取按钮状态
    GetButtonState,
    /// 获取传感器数据
    GetSensorData(SensorType),
    /// 自定义命令
    CustomCommand {
        subsystem: String,
        payload: serde_json::Value,
    },
}

/// 设备响应（DevicePlugin → 请求者）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DeviceResponse {
    /// 显示信息
    DisplayInfo {
        width: u32,
        height: u32,
        format: PixelFormat,
    },
    /// 传感器数据
    SensorData { sensor: SensorType, value: f64 },
    /// 电池电量（0-100）
    BatteryLevel(u8),
    /// 操作成功
    Ok,
    /// 操作失败
    Error(String),
    /// 自定义响应
    Custom(serde_json::Value),
}

/// 设备事件（DevicePlugin → 广播）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DeviceEvent {
    /// 触摸事件
    TouchEvent { x: i32, y: i32, action: TouchAction },
    /// 按钮事件
    ButtonEvent { button: u8, pressed: bool },
    /// 电池电量低
    BatteryLow(u8),
    /// 显示器已连接
    DisplayConnected,
    /// 显示器已断开
    DisplayDisconnected,
    /// 传感器警报
    SensorAlert { sensor: SensorType, value: f64 },
}
