use std::sync::{Arc, Mutex};
use std::collections::VecDeque;
use std::time::{Duration, Instant};
use rusqlite::Connection;
use anyhow::{Result, anyhow};

/// 数据库连接池配置
#[derive(Debug, Clone)]
pub struct ConnectionPoolConfig {
    /// 最小连接数
    pub min_connections: usize,
    /// 最大连接数
    pub max_connections: usize,
    /// 连接超时时间（秒）
    pub connection_timeout: Duration,
    /// 连接空闲超时时间（秒）
    pub idle_timeout: Duration,
    /// 获取连接的最大等待时间
    pub acquire_timeout: Duration,
}

impl Default for ConnectionPoolConfig {
    fn default() -> Self {
        Self {
            min_connections: 1, // 减少最小连接数
            max_connections: 3, // 减少最大连接数，SQLite 不适合太多并发连接
            connection_timeout: Duration::from_secs(30),
            idle_timeout: Duration::from_secs(300), // 5分钟
            acquire_timeout: Duration::from_secs(5),
        }
    }
}

/// 连接包装器，包含连接和元数据
#[derive(Debug)]
struct PooledConnection {
    connection: Connection,
    created_at: Instant,
    last_used: Instant,
    is_busy: bool,
}

impl PooledConnection {
    fn new(connection: Connection) -> Self {
        let now = Instant::now();
        Self {
            connection,
            created_at: now,
            last_used: now,
            is_busy: false,
        }
    }

    fn is_expired(&self, idle_timeout: Duration) -> bool {
        self.last_used.elapsed() > idle_timeout
    }

    fn mark_used(&mut self) {
        self.last_used = Instant::now();
        self.is_busy = true;
    }

    fn mark_returned(&mut self) {
        self.last_used = Instant::now();
        self.is_busy = false;
    }
}

/// 数据库连接池
pub struct ConnectionPool {
    database_path: String,
    config: ConnectionPoolConfig,
    connections: Arc<Mutex<VecDeque<PooledConnection>>>,
    stats: Arc<Mutex<PoolStats>>,
}

/// 连接池统计信息
#[derive(Debug, Default)]
pub struct PoolStats {
    pub total_connections: usize,
    pub active_connections: usize,
    pub idle_connections: usize,
    pub total_acquired: u64,
    pub total_returned: u64,
    pub acquire_timeouts: u64,
    pub connection_errors: u64,
}

/// 连接池中的连接句柄
pub struct PooledConnectionHandle {
    connection: Option<Connection>,
    pool: Arc<ConnectionPool>,
}

impl PooledConnectionHandle {
    fn new(connection: Connection, pool: Arc<ConnectionPool>) -> Self {
        Self {
            connection: Some(connection),
            pool,
        }
    }

    /// 获取底层连接的引用
    pub fn as_ref(&self) -> &Connection {
        self.connection.as_ref().unwrap()
    }

    /// 获取底层连接的可变引用
    pub fn as_mut(&mut self) -> &mut Connection {
        self.connection.as_mut().unwrap()
    }
}

impl Drop for PooledConnectionHandle {
    fn drop(&mut self) {
        if let Some(connection) = self.connection.take() {
            self.pool.return_connection(connection);
        }
    }
}

impl std::ops::Deref for PooledConnectionHandle {
    type Target = Connection;

    fn deref(&self) -> &Self::Target {
        self.connection.as_ref().unwrap()
    }
}

impl std::ops::DerefMut for PooledConnectionHandle {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.connection.as_mut().unwrap()
    }
}

impl ConnectionPool {
    /// 创建新的连接池
    pub fn new(database_path: String, config: ConnectionPoolConfig) -> Result<Arc<Self>> {
        let pool = Arc::new(Self {
            database_path,
            config,
            connections: Arc::new(Mutex::new(VecDeque::new())),
            stats: Arc::new(Mutex::new(PoolStats::default())),
        });

        // 初始化最小连接数
        pool.initialize_connections()?;

        Ok(pool)
    }

    /// 初始化连接池
    fn initialize_connections(&self) -> Result<()> {
        let mut connections = self.connections.lock().map_err(|e| anyhow!("获取连接池锁失败: {}", e))?;
        
        for _ in 0..self.config.min_connections {
            let conn = self.create_connection()?;
            connections.push_back(PooledConnection::new(conn));
        }

        // 更新统计信息
        let mut stats = self.stats.lock().map_err(|e| anyhow!("获取统计锁失败: {}", e))?;
        stats.total_connections = connections.len();
        stats.idle_connections = connections.len();

        println!("连接池初始化完成，创建了 {} 个连接", connections.len());
        Ok(())
    }

    /// 创建新的数据库连接
    fn create_connection(&self) -> Result<Connection> {
        let conn = Connection::open(&self.database_path)
            .map_err(|e| anyhow!("创建数据库连接失败: {}", e))?;

        // 设置连接参数
        conn.execute_batch("
            PRAGMA foreign_keys = ON;
            PRAGMA journal_mode = WAL;
            PRAGMA synchronous = NORMAL;
            PRAGMA cache_size = 1000;
            PRAGMA temp_store = memory;
            PRAGMA busy_timeout = 5000;
        ").map_err(|e| anyhow!("设置数据库参数失败: {}", e))?;

        Ok(conn)
    }

    /// 获取连接（阻塞方式）
    pub fn acquire(self: &Arc<Self>) -> Result<PooledConnectionHandle> {
        let start_time = Instant::now();
        
        loop {
            // 尝试从池中获取连接
            if let Some(connection) = self.try_acquire_from_pool()? {
                let mut stats = self.stats.lock().map_err(|e| anyhow!("获取统计锁失败: {}", e))?;
                stats.total_acquired += 1;
                stats.active_connections += 1;
                stats.idle_connections = stats.idle_connections.saturating_sub(1);
                
                return Ok(PooledConnectionHandle::new(connection, Arc::clone(self)));
            }

            // 检查是否超时
            if start_time.elapsed() >= self.config.acquire_timeout {
                let mut stats = self.stats.lock().map_err(|e| anyhow!("获取统计锁失败: {}", e))?;
                stats.acquire_timeouts += 1;
                return Err(anyhow!("获取数据库连接超时"));
            }

            // 等待一小段时间后重试
            std::thread::sleep(Duration::from_millis(10));
        }
    }

    /// 尝试非阻塞获取连接
    pub fn try_acquire(self: &Arc<Self>) -> Result<Option<PooledConnectionHandle>> {
        match self.try_acquire_from_pool()? {
            Some(connection) => {
                let mut stats = self.stats.lock().map_err(|e| anyhow!("获取统计锁失败: {}", e))?;
                stats.total_acquired += 1;
                stats.active_connections += 1;
                stats.idle_connections = stats.idle_connections.saturating_sub(1);
                
                Ok(Some(PooledConnectionHandle::new(connection, Arc::clone(self))))
            },
            None => Ok(None),
        }
    }

    /// 从池中尝试获取连接
    fn try_acquire_from_pool(&self) -> Result<Option<Connection>> {
        let mut connections = self.connections.lock().map_err(|e| anyhow!("获取连接池锁失败: {}", e))?;

        // 清理过期连接
        connections.retain(|conn| !conn.is_expired(self.config.idle_timeout));

        // 查找可用的连接并移除它
        let mut found_index = None;
        for (i, pooled_conn) in connections.iter().enumerate() {
            if !pooled_conn.is_busy && !pooled_conn.is_expired(self.config.idle_timeout) {
                found_index = Some(i);
                break;
            }
        }

        if let Some(index) = found_index {
            let pooled_conn = connections.remove(index).unwrap();
            return Ok(Some(pooled_conn.connection));
        }

        // 如果没有可用连接且未达到最大连接数，创建新连接
        if connections.len() < self.config.max_connections {
            match self.create_connection() {
                Ok(new_conn) => {
                    println!("创建新的数据库连接，当前连接数: {}", connections.len() + 1);
                    return Ok(Some(new_conn));
                },
                Err(e) => {
                    let mut stats = self.stats.lock().map_err(|e| anyhow!("获取统计锁失败: {}", e))?;
                    stats.connection_errors += 1;
                    return Err(e);
                }
            }
        }

        println!("连接池已满且无可用连接，当前连接数: {}", connections.len());
        Ok(None)
    }

    /// 归还连接到池中
    fn return_connection(&self, connection: Connection) {
        let mut connections = self.connections.lock().unwrap();
        connections.push_back(PooledConnection::new(connection));

        let mut stats = self.stats.lock().unwrap();
        stats.total_returned += 1;
        stats.active_connections = stats.active_connections.saturating_sub(1);
        stats.idle_connections += 1;
    }

    /// 获取连接池统计信息
    pub fn get_stats(&self) -> PoolStats {
        let stats = self.stats.lock().unwrap();
        PoolStats {
            total_connections: {
                let connections = self.connections.lock().unwrap();
                connections.len()
            },
            active_connections: stats.active_connections,
            idle_connections: stats.idle_connections,
            total_acquired: stats.total_acquired,
            total_returned: stats.total_returned,
            acquire_timeouts: stats.acquire_timeouts,
            connection_errors: stats.connection_errors,
        }
    }

    /// 关闭连接池
    pub fn close(&self) -> Result<()> {
        let mut connections = self.connections.lock().map_err(|e| anyhow!("获取连接池锁失败: {}", e))?;
        connections.clear();
        println!("连接池已关闭");
        Ok(())
    }
}
