//! 会话服务

use crate::db::Database;
use crate::models::{SessionRow, HistoryRow, SessionResponse, HistoryResponse};
use anyhow::Result;
use chrono::Utc;
use uuid::Uuid;

/// 会话仓储
pub struct SessionRepository<'a> {
    db: &'a Database,
}

impl<'a> SessionRepository<'a> {
    pub fn new(db: &'a Database) -> Self {
        Self { db }
    }

    /// 创建会话
    pub async fn create(
        &self,
        controller_device_id: &str,
        controlled_device_id: &str,
        connection_type: &str,
    ) -> Result<SessionRow> {
        let id = Uuid::new_v4().to_string();
        let now = Utc::now().to_rfc3339();

        sqlx::query(
            r#"
            INSERT INTO sessions (id, controller_device_id, controlled_device_id, started_at, connection_type, status)
            VALUES (?, ?, ?, ?, ?, 'connecting')
            "#,
        )
        .bind(&id)
        .bind(controller_device_id)
        .bind(controlled_device_id)
        .bind(&now)
        .bind(connection_type)
        .execute(&self.db.pool)
        .await?;

        self.find_by_id(&id).await
    }

    /// 根据ID查找会话
    pub async fn find_by_id(&self, id: &str) -> Result<SessionRow> {
        let session = sqlx::query_as::<_, SessionRow>("SELECT * FROM sessions WHERE id = ?")
            .bind(id)
            .fetch_one(&self.db.pool)
            .await?;

        Ok(session)
    }

    /// 更新会话状态
    pub async fn update_status(&self, id: &str, status: &str) -> Result<()> {
        sqlx::query("UPDATE sessions SET status = ? WHERE id = ?")
            .bind(status)
            .bind(id)
            .execute(&self.db.pool)
            .await?;

        Ok(())
    }

    /// 结束会话
    pub async fn end_session(&self, id: &str) -> Result<()> {
        let now = Utc::now().to_rfc3339();
        sqlx::query("UPDATE sessions SET ended_at = ?, status = 'disconnected' WHERE id = ?")
            .bind(&now)
            .bind(id)
            .execute(&self.db.pool)
            .await?;

        Ok(())
    }

    /// 获取活跃会话
    pub async fn find_active(&self) -> Result<Vec<SessionRow>> {
        let sessions = sqlx::query_as::<_, SessionRow>(
            "SELECT * FROM sessions WHERE status IN ('connecting', 'connected') ORDER BY started_at DESC",
        )
        .fetch_all(&self.db.pool)
        .await?;

        Ok(sessions)
    }

    /// 获取设备相关的会话
    pub async fn find_by_device(&self, device_id: &str) -> Result<Vec<SessionRow>> {
        let sessions = sqlx::query_as::<_, SessionRow>(
            "SELECT * FROM sessions WHERE controller_device_id = ? OR controlled_device_id = ? ORDER BY started_at DESC",
        )
        .bind(device_id)
        .bind(device_id)
        .fetch_all(&self.db.pool)
        .await?;

        Ok(sessions)
    }

    /// 获取所有会话
    pub async fn find_all(&self, offset: u32, limit: u32) -> Result<(Vec<SessionRow>, i64)> {
        let sessions = sqlx::query_as::<_, SessionRow>(
            "SELECT * FROM sessions ORDER BY started_at DESC LIMIT ? OFFSET ?",
        )
        .bind(limit)
        .bind(offset)
        .fetch_all(&self.db.pool)
        .await?;

        let count: (i64,) = sqlx::query_as("SELECT COUNT(*) FROM sessions")
            .fetch_one(&self.db.pool)
            .await?;

        Ok((sessions, count.0))
    }

    /// 获取活跃会话数量
    pub async fn count_active(&self) -> Result<i64> {
        let count: (i64,) = sqlx::query_as(
            "SELECT COUNT(*) FROM sessions WHERE status IN ('connecting', 'connected')",
        )
        .fetch_one(&self.db.pool)
        .await?;

        Ok(count.0)
    }
}

/// 历史记录仓储
pub struct HistoryRepository<'a> {
    db: &'a Database,
}

impl<'a> HistoryRepository<'a> {
    pub fn new(db: &'a Database) -> Self {
        Self { db }
    }

    /// 创建历史记录
    pub async fn create(
        &self,
        user_id: Option<&str>,
        controller_device_id: &str,
        controlled_device_id: &str,
        controlled_device_name: &str,
        connection_type: &str,
    ) -> Result<HistoryRow> {
        let id = Uuid::new_v4().to_string();
        let now = Utc::now().to_rfc3339();

        sqlx::query(
            r#"
            INSERT INTO control_history (id, user_id, controller_device_id, controlled_device_id, controlled_device_name, started_at, connection_type)
            VALUES (?, ?, ?, ?, ?, ?, ?)
            "#,
        )
        .bind(&id)
        .bind(user_id)
        .bind(controller_device_id)
        .bind(controlled_device_id)
        .bind(controlled_device_name)
        .bind(&now)
        .bind(connection_type)
        .execute(&self.db.pool)
        .await?;

        self.find_by_id(&id).await
    }

    /// 根据ID查找历史记录
    pub async fn find_by_id(&self, id: &str) -> Result<HistoryRow> {
        let history = sqlx::query_as::<_, HistoryRow>("SELECT * FROM control_history WHERE id = ?")
            .bind(id)
            .fetch_one(&self.db.pool)
            .await?;

        Ok(history)
    }

    /// 结束历史记录
    pub async fn end_record(&self, id: &str) -> Result<()> {
        let now = Utc::now();
        let now_str = now.to_rfc3339();

        // 计算持续时间
        let history = self.find_by_id(id).await?;
        let started_at = chrono::DateTime::parse_from_rfc3339(&history.started_at)
            .map(|dt| dt.with_timezone(&Utc))
            .unwrap_or(now);
        let duration = (now - started_at).num_seconds();

        sqlx::query(
            "UPDATE control_history SET ended_at = ?, duration_seconds = ? WHERE id = ?",
        )
        .bind(&now_str)
        .bind(duration)
        .bind(id)
        .execute(&self.db.pool)
        .await?;

        Ok(())
    }

    /// 获取用户的历史记录
    pub async fn find_by_user(&self, user_id: &str, offset: u32, limit: u32) -> Result<(Vec<HistoryRow>, i64)> {
        let history = sqlx::query_as::<_, HistoryRow>(
            "SELECT * FROM control_history WHERE user_id = ? ORDER BY started_at DESC LIMIT ? OFFSET ?",
        )
        .bind(user_id)
        .bind(limit)
        .bind(offset)
        .fetch_all(&self.db.pool)
        .await?;

        let count: (i64,) = sqlx::query_as("SELECT COUNT(*) FROM control_history WHERE user_id = ?")
            .bind(user_id)
            .fetch_one(&self.db.pool)
            .await?;

        Ok((history, count.0))
    }

    /// 获取设备的历史记录
    pub async fn find_by_device(&self, device_id: &str, offset: u32, limit: u32) -> Result<(Vec<HistoryRow>, i64)> {
        let history = sqlx::query_as::<_, HistoryRow>(
            "SELECT * FROM control_history WHERE controller_device_id = ? ORDER BY started_at DESC LIMIT ? OFFSET ?",
        )
        .bind(device_id)
        .bind(limit)
        .bind(offset)
        .fetch_all(&self.db.pool)
        .await?;

        let count: (i64,) = sqlx::query_as(
            "SELECT COUNT(*) FROM control_history WHERE controller_device_id = ?",
        )
        .bind(device_id)
        .fetch_one(&self.db.pool)
        .await?;

        Ok((history, count.0))
    }
}

impl From<SessionRow> for SessionResponse {
    fn from(session: SessionRow) -> Self {
        Self {
            id: session.id,
            controller_device_id: session.controller_device_id,
            controlled_device_id: session.controlled_device_id,
            started_at: session.started_at,
            ended_at: session.ended_at,
            connection_type: session.connection_type,
            status: session.status,
        }
    }
}

impl From<HistoryRow> for HistoryResponse {
    fn from(history: HistoryRow) -> Self {
        let duration = history.duration_seconds.map(|secs| {
            let hours = secs / 3600;
            let minutes = (secs % 3600) / 60;
            let seconds = secs % 60;
            if hours > 0 {
                format!("{:02}:{:02}:{:02}", hours, minutes, seconds)
            } else {
                format!("{:02}:{:02}", minutes, seconds)
            }
        });

        Self {
            id: history.id,
            controller_device_id: history.controller_device_id,
            controlled_device_id: history.controlled_device_id,
            controlled_device_name: history.controlled_device_name,
            started_at: history.started_at,
            ended_at: history.ended_at,
            duration,
            connection_type: history.connection_type,
        }
    }
}
