use anyhow::{anyhow, Result};
use std::sync::Arc;

use crate::data::models::hedra_lipsync_record::{HedraLipSyncRecord, HedraLipSyncStatus};
use crate::infrastructure::database::Database;

/// Hedra 口型合成记录仓储
/// 遵循 Tauri 开发规范的数据访问层设计
pub struct HedraLipSyncRepository {
    database: Arc<Database>,
}

impl HedraLipSyncRepository {
    /// 创建新的仓储实例
    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))?;

        crate::data::models::hedra_lipsync_record::create_table(&conn)
            .map_err(|e| anyhow!("创建 Hedra 口型合成记录表失败: {}", e))?;

        Ok(())
    }

    /// 保存记录
    pub fn save(&self, record: &HedraLipSyncRecord) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        record.save(&conn)
            .map_err(|e| anyhow!("保存 Hedra 口型合成记录失败: {}", e))?;
        
        Ok(())
    }

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

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        HedraLipSyncRecord::find_by_id(&conn, id)
            .map_err(|e| anyhow!("查找 Hedra 口型合成记录失败: {}", e))
    }

    /// 根据任务ID查找记录
    pub fn find_by_task_id(&self, task_id: &str) -> Result<Option<HedraLipSyncRecord>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        HedraLipSyncRecord::find_by_task_id(&conn, task_id)
            .map_err(|e| anyhow!("根据任务ID查找 Hedra 口型合成记录失败: {}", e))
    }

    /// 获取所有记录
    pub fn get_all(&self, limit: Option<i32>) -> Result<Vec<HedraLipSyncRecord>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        HedraLipSyncRecord::get_all(&conn, limit)
            .map_err(|e| anyhow!("获取所有 Hedra 口型合成记录失败: {}", e))
    }

    /// 根据状态获取记录
    pub fn get_by_status(&self, status: HedraLipSyncStatus) -> Result<Vec<HedraLipSyncRecord>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        HedraLipSyncRecord::get_by_status(&conn, status)
            .map_err(|e| anyhow!("根据状态获取 Hedra 口型合成记录失败: {}", e))
    }

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

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        record.delete(&conn)
            .map_err(|e| anyhow!("删除 Hedra 口型合成记录失败: {}", e))?;
        
        Ok(())
    }

    /// 根据ID删除记录
    pub fn delete_by_id(&self, id: &str) -> Result<()> {
        if let Some(record) = self.find_by_id(id)? {
            self.delete(&record)?;
        }
        Ok(())
    }

    /// 批量删除记录
    pub fn delete_batch(&self, ids: &[String]) -> Result<usize> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

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

        let mut deleted_count = 0;
        for id in ids {
            let result = conn.execute(
                "DELETE FROM hedra_lipsync_records WHERE id = ?1",
                rusqlite::params![id],
            );
            
            match result {
                Ok(changes) => deleted_count += changes,
                Err(e) => {
                    eprintln!("删除记录 {} 失败: {}", id, e);
                }
            }
        }

        Ok(deleted_count)
    }

    /// 更新记录状态
    pub fn update_status(&self, id: &str, status: HedraLipSyncStatus) -> Result<()> {
        if let Some(mut record) = self.find_by_id(id)? {
            match status {
                HedraLipSyncStatus::Processing => {
                    record.status = status;
                    if record.started_at.is_none() {
                        record.started_at = Some(chrono::Utc::now());
                    }
                }
                HedraLipSyncStatus::Completed | HedraLipSyncStatus::Failed | HedraLipSyncStatus::Cancelled => {
                    record.status = status;
                    if record.completed_at.is_none() {
                        record.completed_at = Some(chrono::Utc::now());
                        if let Some(started_at) = record.started_at {
                            record.duration_ms = Some((chrono::Utc::now() - started_at).num_milliseconds());
                        }
                    }
                }
                _ => {
                    record.status = status;
                }
            }
            self.save(&record)?;
        }
        Ok(())
    }

    /// 更新记录状态和错误信息
    pub fn update_status_and_error(&self, id: &str, status: HedraLipSyncStatus, error_message: Option<String>) -> Result<()> {
        if let Some(mut record) = self.find_by_id(id)? {
            record.status = status.clone();
            record.error_message = error_message;

            match status {
                HedraLipSyncStatus::Processing => {
                    if record.started_at.is_none() {
                        record.started_at = Some(chrono::Utc::now());
                    }
                }
                HedraLipSyncStatus::Completed | HedraLipSyncStatus::Failed | HedraLipSyncStatus::Cancelled => {
                    if record.completed_at.is_none() {
                        record.completed_at = Some(chrono::Utc::now());
                        if let Some(started_at) = record.started_at {
                            record.duration_ms = Some((chrono::Utc::now() - started_at).num_milliseconds());
                        }
                    }
                }
                _ => {}
            }

            self.save(&record)?;
        }
        Ok(())
    }

    /// 更新记录进度和结果
    pub fn update_progress_and_result(
        &self,
        id: &str,
        status: HedraLipSyncStatus,
        progress: i32,
        result_video_url: Option<String>,
        error_message: Option<String>
    ) -> Result<()> {
        if let Some(mut record) = self.find_by_id(id)? {
            record.status = status.clone();
            record.progress = progress as f32;
            record.result_video_url = result_video_url;
            record.error_message = error_message;

            match status {
                HedraLipSyncStatus::Processing => {
                    if record.started_at.is_none() {
                        record.started_at = Some(chrono::Utc::now());
                    }
                }
                HedraLipSyncStatus::Completed | HedraLipSyncStatus::Failed | HedraLipSyncStatus::Cancelled => {
                    if record.completed_at.is_none() {
                        record.completed_at = Some(chrono::Utc::now());
                        if let Some(started_at) = record.started_at {
                            record.duration_ms = Some((chrono::Utc::now() - started_at).num_milliseconds());
                        }
                    }
                }
                _ => {}
            }

            self.save(&record)?;
        }
        Ok(())
    }

    /// 获取统计信息
    pub fn get_statistics(&self) -> Result<HedraLipSyncStatistics> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

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

        let total: i64 = conn.query_row(
            "SELECT COUNT(*) FROM hedra_lipsync_records",
            [],
            |row| row.get(0),
        ).unwrap_or(0);

        let completed: i64 = conn.query_row(
            "SELECT COUNT(*) FROM hedra_lipsync_records WHERE status = 'completed'",
            [],
            |row| row.get(0),
        ).unwrap_or(0);

        let processing: i64 = conn.query_row(
            "SELECT COUNT(*) FROM hedra_lipsync_records WHERE status = 'processing'",
            [],
            |row| row.get(0),
        ).unwrap_or(0);

        let failed: i64 = conn.query_row(
            "SELECT COUNT(*) FROM hedra_lipsync_records WHERE status = 'failed'",
            [],
            |row| row.get(0),
        ).unwrap_or(0);

        Ok(HedraLipSyncStatistics {
            total: total as u32,
            completed: completed as u32,
            processing: processing as u32,
            failed: failed as u32,
        })
    }
}

/// Hedra 口型合成统计信息
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct HedraLipSyncStatistics {
    pub total: u32,
    pub completed: u32,
    pub processing: u32,
    pub failed: u32,
}
