use std::sync::Arc;
use anyhow::{Result, anyhow};
use rusqlite::{params, Row};
use serde_json;

use crate::infrastructure::database::Database;
use crate::data::models::model_dynamic::{
    ModelDynamic, GeneratedVideo, CreateModelDynamicRequest, UpdateModelDynamicRequest,
    ModelDynamicStats, DynamicStatus, VideoGenerationStatus
};

/// 模特动态数据仓库
/// 遵循 Tauri 开发规范的数据访问层设计原则
#[derive(Clone)]
pub struct ModelDynamicRepository {
    database: Arc<Database>,
}

impl ModelDynamicRepository {
    /// 创建新的模特动态仓库实例
    pub fn new(database: Arc<Database>) -> Self {
        Self { database }
    }

    /// 初始化数据库表
    pub fn init_tables(&self) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        // 创建模特动态表
        conn.execute(
            "CREATE TABLE IF NOT EXISTS model_dynamics (
                id TEXT PRIMARY KEY,
                model_id TEXT NOT NULL,
                title TEXT,
                description TEXT NOT NULL,
                prompt TEXT NOT NULL,
                source_image_path TEXT NOT NULL,
                ai_model TEXT NOT NULL,
                video_count INTEGER NOT NULL,
                status TEXT NOT NULL DEFAULT 'Draft',
                created_at TEXT NOT NULL,
                updated_at TEXT NOT NULL,
                FOREIGN KEY (model_id) REFERENCES models (id)
            )",
            [],
        )?;

        // 创建生成视频表
        conn.execute(
            "CREATE TABLE IF NOT EXISTS generated_videos (
                id TEXT PRIMARY KEY,
                dynamic_id TEXT NOT NULL,
                video_path TEXT NOT NULL,
                thumbnail_path TEXT,
                file_size INTEGER NOT NULL DEFAULT 0,
                duration INTEGER NOT NULL DEFAULT 0,
                status TEXT NOT NULL DEFAULT 'Pending',
                generation_progress INTEGER,
                error_message TEXT,
                created_at TEXT NOT NULL,
                FOREIGN KEY (dynamic_id) REFERENCES model_dynamics (id) ON DELETE CASCADE
            )",
            [],
        )?;

        // 创建索引
        conn.execute(
            "CREATE INDEX IF NOT EXISTS idx_model_dynamics_model_id ON model_dynamics (model_id)",
            [],
        )?;

        conn.execute(
            "CREATE INDEX IF NOT EXISTS idx_model_dynamics_status ON model_dynamics (status)",
            [],
        )?;

        conn.execute(
            "CREATE INDEX IF NOT EXISTS idx_generated_videos_dynamic_id ON generated_videos (dynamic_id)",
            [],
        )?;

        Ok(())
    }

    /// 创建模特动态
    pub fn create(&self, request: CreateModelDynamicRequest) -> Result<ModelDynamic> {
        let mut dynamic = ModelDynamic::new(
            request.model_id,
            request.description,
            request.prompt,
            request.source_image_path,
            request.ai_model,
            request.video_count,
        );

        if let Some(title) = request.title {
            dynamic.title = Some(title);
        }

        dynamic.validate().map_err(|e| anyhow::anyhow!(e))?;

        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        conn.execute(
            "INSERT INTO model_dynamics (
                id, model_id, title, description, prompt, source_image_path,
                ai_model, video_count, status, created_at, updated_at
            ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)",
            params![
                dynamic.id,
                dynamic.model_id,
                dynamic.title,
                dynamic.description,
                dynamic.prompt,
                dynamic.source_image_path,
                dynamic.ai_model,
                dynamic.video_count,
                serde_json::to_string(&dynamic.status)?,
                dynamic.created_at.to_rfc3339(),
                dynamic.updated_at.to_rfc3339(),
            ],
        )?;

        Ok(dynamic)
    }

    /// 根据ID获取动态
    pub fn get_by_id(&self, id: &str) -> Result<Option<ModelDynamic>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        let mut stmt = conn.prepare(
            "SELECT id, model_id, title, description, prompt, source_image_path,
                    ai_model, video_count, status, created_at, updated_at
             FROM model_dynamics WHERE id = ?1"
        )?;

        let dynamic_iter = stmt.query_map([id], |row| {
            self.row_to_dynamic(row)
        })?;

        for dynamic in dynamic_iter {
            let mut dynamic = dynamic?;
            // 加载生成的视频
            dynamic.generated_videos = self.get_videos_by_dynamic_id(&dynamic.id)?;
            return Ok(Some(dynamic));
        }

        Ok(None)
    }

    /// 根据模特ID获取动态列表
    pub fn get_by_model_id(&self, model_id: &str) -> Result<Vec<ModelDynamic>> {
       if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        let mut stmt = conn.prepare(
            "SELECT id, model_id, title, description, prompt, source_image_path,
                    ai_model, video_count, status, created_at, updated_at
             FROM model_dynamics WHERE model_id = ?1 ORDER BY created_at DESC"
        )?;

        let dynamic_iter = stmt.query_map([model_id], |row| {
            self.row_to_dynamic(row)
        })?;

        let mut dynamics = Vec::new();
        for dynamic in dynamic_iter {
            let mut dynamic = dynamic?;
            // 加载生成的视频
            dynamic.generated_videos = self.get_videos_by_dynamic_id(&dynamic.id)?;
            dynamics.push(dynamic);
        }

        Ok(dynamics)
    }

    /// 更新动态
    pub fn update(&self, id: &str, request: UpdateModelDynamicRequest) -> Result<ModelDynamic> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        // 构建更新语句
        let mut updates = Vec::new();
        let mut params: Vec<Box<dyn rusqlite::ToSql>> = Vec::new();

        if let Some(title) = &request.title {
            updates.push("title = ?");
            params.push(Box::new(title.clone()));
        }

        if let Some(description) = &request.description {
            updates.push("description = ?");
            params.push(Box::new(description.clone()));
        }

        if let Some(prompt) = &request.prompt {
            updates.push("prompt = ?");
            params.push(Box::new(prompt.clone()));
        }

        if let Some(status) = &request.status {
            updates.push("status = ?");
            params.push(Box::new(serde_json::to_string(status)?));
        }

        if updates.is_empty() {
            return Err(anyhow::anyhow!("没有要更新的字段"));
        }

        updates.push("updated_at = ?");
        params.push(Box::new(chrono::Utc::now().to_rfc3339()));
        params.push(Box::new(id.to_string()));

        let sql = format!(
            "UPDATE model_dynamics SET {} WHERE id = ?",
            updates.join(", ")
        );

        let params_refs: Vec<&dyn rusqlite::ToSql> = params.iter().map(|p| p.as_ref()).collect();
        conn.execute(&sql, &params_refs[..])?;

        // 返回更新后的动态
        self.get_by_id(id)?.ok_or_else(|| anyhow::anyhow!("动态不存在"))
    }

    /// 删除动态
    pub fn delete(&self, id: &str) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        // 删除动态（级联删除视频）
        conn.execute("DELETE FROM model_dynamics WHERE id = ?1", [id])?;

        Ok(())
    }

    /// 获取模特动态统计
    pub fn get_stats_by_model_id(&self, model_id: &str) -> Result<ModelDynamicStats> {
       if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        // 获取动态统计
        let mut stmt = conn.prepare(
            "SELECT 
                COUNT(*) as total_dynamics,
                SUM(CASE WHEN status = '\"Published\"' THEN 1 ELSE 0 END) as published_dynamics
             FROM model_dynamics WHERE model_id = ?1"
        )?;

        let (total_dynamics, published_dynamics) = stmt.query_row([model_id], |row| {
            Ok((row.get::<_, u32>(0)?, row.get::<_, u32>(1)?))
        })?;

        // 获取视频统计
        let mut stmt = conn.prepare(
            "SELECT 
                COUNT(*) as total_videos,
                SUM(CASE WHEN status = '\"Completed\"' THEN 1 ELSE 0 END) as completed_videos,
                SUM(CASE WHEN status = '\"Generating\"' THEN 1 ELSE 0 END) as generating_videos,
                SUM(CASE WHEN status = '\"Failed\"' THEN 1 ELSE 0 END) as failed_videos
             FROM generated_videos 
             WHERE dynamic_id IN (SELECT id FROM model_dynamics WHERE model_id = ?1)"
        )?;

        let (total_videos, completed_videos, generating_videos, failed_videos) = 
            stmt.query_row([model_id], |row| {
                Ok((
                    row.get::<_, u32>(0)?,
                    row.get::<_, u32>(1)?,
                    row.get::<_, u32>(2)?,
                    row.get::<_, u32>(3)?
                ))
            })?;

        Ok(ModelDynamicStats {
            total_dynamics,
            published_dynamics,
            total_videos,
            completed_videos,
            generating_videos,
            failed_videos,
        })
    }

    /// 获取动态的生成视频列表
    fn get_videos_by_dynamic_id(&self, dynamic_id: &str) -> Result<Vec<GeneratedVideo>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        let mut stmt = conn.prepare(
            "SELECT id, dynamic_id, video_path, thumbnail_path, file_size, duration,
                    status, generation_progress, error_message, created_at
             FROM generated_videos WHERE dynamic_id = ?1 ORDER BY created_at ASC"
        )?;

        let video_iter = stmt.query_map([dynamic_id], |row| {
            self.row_to_video(row)
        })?;

        let mut videos = Vec::new();
        for video in video_iter {
            videos.push(video?);
        }

        Ok(videos)
    }

    /// 将数据库行转换为动态对象
    fn row_to_dynamic(&self, row: &Row) -> rusqlite::Result<ModelDynamic> {
        let status_str: String = row.get("status")?;
        let status: DynamicStatus = serde_json::from_str(&status_str)
            .map_err(|e| rusqlite::Error::InvalidColumnType(
                row.as_ref().column_index("status").unwrap(),
                format!("Invalid status: {}", e).into(),
                rusqlite::types::Type::Text
            ))?;

        Ok(ModelDynamic {
            id: row.get("id")?,
            model_id: row.get("model_id")?,
            title: row.get("title")?,
            description: row.get("description")?,
            prompt: row.get("prompt")?,
            source_image_path: row.get("source_image_path")?,
            ai_model: row.get("ai_model")?,
            video_count: row.get("video_count")?,
            generated_videos: Vec::new(), // 将在外部加载
            status,
            created_at: chrono::DateTime::parse_from_rfc3339(&row.get::<_, String>("created_at")?)
                .map_err(|e| rusqlite::Error::InvalidColumnType(
                    row.as_ref().column_index("created_at").unwrap(),
                    format!("Invalid datetime: {}", e).into(),
                    rusqlite::types::Type::Text
                ))?
                .with_timezone(&chrono::Utc),
            updated_at: chrono::DateTime::parse_from_rfc3339(&row.get::<_, String>("updated_at")?)
                .map_err(|e| rusqlite::Error::InvalidColumnType(
                    row.as_ref().column_index("updated_at").unwrap(),
                    format!("Invalid datetime: {}", e).into(),
                    rusqlite::types::Type::Text
                ))?
                .with_timezone(&chrono::Utc),
        })
    }

    /// 将数据库行转换为视频对象
    fn row_to_video(&self, row: &Row) -> rusqlite::Result<GeneratedVideo> {
        let status_str: String = row.get("status")?;
        let status: VideoGenerationStatus = serde_json::from_str(&status_str)
            .map_err(|e| rusqlite::Error::InvalidColumnType(
                row.as_ref().column_index("status").unwrap(),
                format!("Invalid status: {}", e).into(),
                rusqlite::types::Type::Text
            ))?;

        Ok(GeneratedVideo {
            id: row.get("id")?,
            dynamic_id: row.get("dynamic_id")?,
            video_path: row.get("video_path")?,
            thumbnail_path: row.get("thumbnail_path")?,
            file_size: row.get("file_size")?,
            duration: row.get("duration")?,
            status,
            generation_progress: row.get("generation_progress")?,
            error_message: row.get("error_message")?,
            created_at: chrono::DateTime::parse_from_rfc3339(&row.get::<_, String>("created_at")?)
                .map_err(|e| rusqlite::Error::InvalidColumnType(
                    row.as_ref().column_index("created_at").unwrap(),
                    format!("Invalid datetime: {}", e).into(),
                    rusqlite::types::Type::Text
                ))?
                .with_timezone(&chrono::Utc),
        })
    }
}
