//! 数据库操作封装

use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use rusqlite::{params, Connection, OptionalExtension};
use std::path::PathBuf;

use crate::models::{ChatMessage, Conversation, FileTransfer, MessageStatus, MessageType, TransferStatus, DeviceInfo};
use crate::utils::AppError;
use super::init_database;

/// 全局数据库连接
static DB_CONNECTION: OnceCell<Mutex<Connection>> = OnceCell::new();

/// 数据库仓库
pub struct Database;

impl Database {
    /// 初始化数据库连接
    pub fn init(app_data_dir: PathBuf) -> Result<(), AppError> {
        // 确保目录存在
        std::fs::create_dir_all(&app_data_dir)?;

        let db_path = app_data_dir.join("flash_send.db");
        let conn = Connection::open(&db_path)?;

        // 启用外键约束
        conn.execute("PRAGMA foreign_keys = ON", [])?;

        // 初始化表结构
        init_database(&conn)?;

        DB_CONNECTION
            .set(Mutex::new(conn))
            .map_err(|_| AppError::Database(rusqlite::Error::InvalidPath(db_path)))?;

        log::info!("Database initialized at {:?}", app_data_dir);
        Ok(())
    }

    /// 获取数据库连接
    fn conn() -> &'static Mutex<Connection> {
        DB_CONNECTION.get().expect("Database not initialized")
    }

    // ==================== 聊天消息操作 ====================

    /// 保存聊天消息
    pub fn save_message(message: &ChatMessage) -> Result<(), AppError> {
        let conn = Self::conn().lock();
        conn.execute(
            r#"
            INSERT INTO chat_messages (id, message_type, content, from_device, to_device, timestamp, status)
            VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)
            ON CONFLICT(id) DO UPDATE SET status = ?7
            "#,
            params![
                message.id,
                serde_json::to_string(&message.message_type)?,
                message.content,
                message.from,
                message.to,
                message.timestamp,
                serde_json::to_string(&message.status)?,
            ],
        )?;
        Ok(())
    }

    /// 更新消息状态
    pub fn update_message_status(message_id: &str, status: MessageStatus) -> Result<(), AppError> {
        let conn = Self::conn().lock();
        conn.execute(
            "UPDATE chat_messages SET status = ?1 WHERE id = ?2",
            params![serde_json::to_string(&status)?, message_id],
        )?;
        Ok(())
    }

    /// 获取与指定设备的聊天历史
    pub fn get_chat_history(
        device_id: &str,
        local_device_id: &str,
        limit: usize,
        offset: usize,
    ) -> Result<Vec<ChatMessage>, AppError> {
        let conn = Self::conn().lock();
        let mut stmt = conn.prepare(
            r#"
            SELECT id, message_type, content, from_device, to_device, timestamp, status
            FROM chat_messages
            WHERE (from_device = ?1 AND to_device = ?2) OR (from_device = ?2 AND to_device = ?1)
            ORDER BY timestamp DESC
            LIMIT ?3 OFFSET ?4
            "#,
        )?;

        let messages = stmt
            .query_map(params![device_id, local_device_id, limit, offset], |row| {
                let message_type_str: String = row.get(1)?;
                let status_str: String = row.get(6)?;
                
                Ok(ChatMessage {
                    id: row.get(0)?,
                    message_type: serde_json::from_str(&message_type_str).unwrap_or(MessageType::Text),
                    content: row.get(2)?,
                    from: row.get(3)?,
                    to: row.get(4)?,
                    timestamp: row.get(5)?,
                    status: serde_json::from_str(&status_str).unwrap_or(MessageStatus::Pending),
                })
            })?
            .collect::<Result<Vec<_>, _>>()?;

        Ok(messages)
    }

    /// 删除与指定设备的所有聊天记录
    pub fn delete_chat_history(device_id: &str, local_device_id: &str) -> Result<usize, AppError> {
        let conn = Self::conn().lock();
        let count = conn.execute(
            r#"
            DELETE FROM chat_messages
            WHERE (from_device = ?1 AND to_device = ?2) OR (from_device = ?2 AND to_device = ?1)
            "#,
            params![device_id, local_device_id],
        )?;
        Ok(count)
    }

    /// 获取会话列表（所有有聊天记录的设备，按最后消息时间排序）
    pub fn get_conversations(local_device_id: &str) -> Result<Vec<Conversation>, AppError> {
        let conn = Self::conn().lock();
        
        // 查询所有聊天过的设备及其最后一条消息
        let mut stmt = conn.prepare(
            r#"
            WITH conversation_devices AS (
                SELECT DISTINCT 
                    CASE 
                        WHEN from_device = ?1 THEN to_device 
                        ELSE from_device 
                    END as peer_device
                FROM chat_messages
                WHERE from_device = ?1 OR to_device = ?1
            ),
            last_messages AS (
                SELECT 
                    cd.peer_device,
                    m.content as last_content,
                    m.message_type as last_type,
                    m.timestamp as last_time
                FROM conversation_devices cd
                LEFT JOIN chat_messages m ON (
                    (m.from_device = ?1 AND m.to_device = cd.peer_device) OR
                    (m.from_device = cd.peer_device AND m.to_device = ?1)
                )
                WHERE m.timestamp = (
                    SELECT MAX(m2.timestamp)
                    FROM chat_messages m2
                    WHERE (m2.from_device = ?1 AND m2.to_device = cd.peer_device)
                       OR (m2.from_device = cd.peer_device AND m2.to_device = ?1)
                )
            )
            SELECT 
                lm.peer_device,
                COALESCE(kd.device_name, lm.peer_device) as device_name,
                COALESCE(kd.ip, '') as ip,
                lm.last_content,
                lm.last_type,
                lm.last_time
            FROM last_messages lm
            LEFT JOIN known_devices kd ON kd.device_id = lm.peer_device
            ORDER BY lm.last_time DESC
            "#,
        )?;

        let conversations = stmt
            .query_map(params![local_device_id], |row| {
                let last_type_str: Option<String> = row.get(4)?;
                Ok(Conversation {
                    device_id: row.get(0)?,
                    device_name: row.get(1)?,
                    ip: row.get(2)?,
                    online: false, // 将在命令层更新
                    last_message: row.get(3)?,
                    last_message_type: last_type_str.and_then(|s| serde_json::from_str(&s).ok()),
                    last_message_time: row.get(5)?,
                    unread_count: 0, // TODO: 实现未读计数
                })
            })?
            .collect::<Result<Vec<_>, _>>()?;

        Ok(conversations)
    }

    // ==================== 文件传输操作 ====================

    /// 保存文件传输记录
    pub fn save_file_transfer(transfer: &FileTransfer) -> Result<(), AppError> {
        let conn = Self::conn().lock();
        conn.execute(
            r#"
            INSERT INTO file_transfers 
            (file_id, name, size, progress, status, mime_type, from_device, to_device, local_path, created_at, completed_at, transferred_bytes)
            VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
            ON CONFLICT(file_id) DO UPDATE SET 
                progress = ?4, status = ?5, local_path = ?9, completed_at = ?11, transferred_bytes = ?12
            "#,
            params![
                transfer.file_id,
                transfer.name,
                transfer.size as i64,
                transfer.progress,
                serde_json::to_string(&transfer.status)?,
                transfer.mime_type,
                transfer.from_device,
                transfer.to_device,
                transfer.local_path,
                transfer.created_at,
                transfer.completed_at,
                transfer.transferred_bytes as i64,
            ],
        )?;
        Ok(())
    }

    /// 更新文件传输状态
    pub fn update_transfer_status(file_id: &str, status: &str) -> Result<(), AppError> {
        let conn = Self::conn().lock();
        let completed_at = chrono::Utc::now().timestamp();

        conn.execute(
            "UPDATE file_transfers SET status = ?1, completed_at = ?2 WHERE file_id = ?3",
            params![format!("\"{}\"", status), completed_at, file_id],
        )?;
        Ok(())
    }

    /// 更新文件传输进度和状态
    pub fn update_transfer_progress(file_id: &str, progress: f64, transferred_bytes: u64, status: &str) -> Result<(), AppError> {
        let conn = Self::conn().lock();
        let completed_at = if status == "completed" || status == "failed" {
            Some(chrono::Utc::now().timestamp())
        } else {
            None
        };

        conn.execute(
            "UPDATE file_transfers SET progress = ?1, transferred_bytes = ?2, status = ?3, completed_at = ?4 WHERE file_id = ?5",
            params![progress, transferred_bytes as i64, format!("\"{}\"", status), completed_at, file_id],
        )?;
        Ok(())
    }

    /// 获取文件传输记录
    pub fn get_file_transfer(file_id: &str) -> Result<Option<FileTransfer>, AppError> {
        let conn = Self::conn().lock();
        let mut stmt = conn.prepare(
            r#"
            SELECT file_id, name, size, progress, status, mime_type, 
                   from_device, to_device, local_path, created_at, completed_at, transferred_bytes
            FROM file_transfers WHERE file_id = ?1
            "#,
        )?;

        let transfer = stmt
            .query_row(params![file_id], |row| {
                let status_str: String = row.get(4)?;
                Ok(FileTransfer {
                    file_id: row.get(0)?,
                    name: row.get(1)?,
                    size: row.get::<_, i64>(2)? as u64,
                    progress: row.get(3)?,
                    status: serde_json::from_str(&status_str).unwrap_or(TransferStatus::Pending),
                    mime_type: row.get(5)?,
                    from_device: row.get(6)?,
                    to_device: row.get(7)?,
                    local_path: row.get(8)?,
                    created_at: row.get(9)?,
                    completed_at: row.get(10)?,
                    transferred_bytes: row.get::<_, i64>(11).unwrap_or(0) as u64,
                })
            })
            .optional()?;

        Ok(transfer)
    }

    /// 获取与指定设备的文件传输历史
    pub fn get_transfer_history(
        device_id: &str,
        local_device_id: &str,
        limit: usize,
    ) -> Result<Vec<FileTransfer>, AppError> {
        let conn = Self::conn().lock();
        let mut stmt = conn.prepare(
            r#"
            SELECT file_id, name, size, progress, status, mime_type, 
                   from_device, to_device, local_path, created_at, completed_at, transferred_bytes
            FROM file_transfers
            WHERE (from_device = ?1 AND to_device = ?2) OR (from_device = ?2 AND to_device = ?1)
            ORDER BY created_at DESC
            LIMIT ?3
            "#,
        )?;

        let transfers = stmt
            .query_map(params![device_id, local_device_id, limit], |row| {
                let status_str: String = row.get(4)?;
                Ok(FileTransfer {
                    file_id: row.get(0)?,
                    name: row.get(1)?,
                    size: row.get::<_, i64>(2)? as u64,
                    progress: row.get(3)?,
                    status: serde_json::from_str(&status_str).unwrap_or(TransferStatus::Pending),
                    mime_type: row.get(5)?,
                    from_device: row.get(6)?,
                    to_device: row.get(7)?,
                    local_path: row.get(8)?,
                    created_at: row.get(9)?,
                    completed_at: row.get(10)?,
                    transferred_bytes: row.get::<_, i64>(11).unwrap_or(0) as u64,
                })
            })?
            .collect::<Result<Vec<_>, _>>()?;

        Ok(transfers)
    }

    // ==================== 设备信息操作 ====================

    /// 保存已知设备
    pub fn save_known_device(device: &DeviceInfo) -> Result<(), AppError> {
        let conn = Self::conn().lock();
        conn.execute(
            r#"
            INSERT INTO known_devices (device_id, device_name, ip, ws_port, http_port, last_seen)
            VALUES (?1, ?2, ?3, ?4, ?5, ?6)
            ON CONFLICT(device_id) DO UPDATE SET 
                device_name = ?2, ip = ?3, ws_port = ?4, http_port = ?5, last_seen = ?6
            "#,
            params![
                device.device_id,
                device.device_name,
                device.ip,
                device.ws_port,
                device.http_port,
                device.last_seen,
            ],
        )?;
        Ok(())
    }

    /// 获取所有已知设备
    pub fn get_known_devices() -> Result<Vec<DeviceInfo>, AppError> {
        let conn = Self::conn().lock();
        let mut stmt = conn.prepare(
            "SELECT device_id, device_name, ip, ws_port, http_port, last_seen FROM known_devices",
        )?;

        let devices = stmt
            .query_map([], |row| {
                Ok(DeviceInfo {
                    device_id: row.get(0)?,
                    device_name: row.get(1)?,
                    ip: row.get(2)?,
                    ws_port: row.get(3)?,
                    http_port: row.get(4)?,
                    online: false,
                    capabilities: vec![],
                    last_seen: row.get(5)?,
                })
            })?
            .collect::<Result<Vec<_>, _>>()?;

        Ok(devices)
    }

    // ==================== 配置操作 ====================

    /// 保存配置项
    pub fn save_config(key: &str, value: &str) -> Result<(), AppError> {
        let conn = Self::conn().lock();
        conn.execute(
            "INSERT INTO app_config (key, value) VALUES (?1, ?2) ON CONFLICT(key) DO UPDATE SET value = ?2",
            params![key, value],
        )?;
        Ok(())
    }

    /// 获取配置项
    pub fn get_config(key: &str) -> Result<Option<String>, AppError> {
        let conn = Self::conn().lock();
        let value: Option<String> = conn
            .query_row(
                "SELECT value FROM app_config WHERE key = ?1",
                params![key],
                |row| row.get(0),
            )
            .optional()?;
        Ok(value)
    }
}
