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

use crate::data::models::video_generation_record::{
    VideoGenerationRecord, VideoGenerationStatus, VideoGenerationQuery
};
use crate::infrastructure::database::Database;

/// 视频生成记录数据仓库
/// 遵循 Tauri 开发规范的数据访问层设计原则
pub struct VideoGenerationRecordRepository {
    database: Arc<Database>,
}

impl VideoGenerationRecordRepository {
    /// 创建新的视频生成记录仓库实例
    pub fn new(database: Arc<Database>) -> Self {
        Self { database }
    }

    /// 创建视频生成记录
    pub async fn create(&self, record: &VideoGenerationRecord) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

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

        pooled_conn.execute(
            "INSERT INTO video_generation_records (
                id, project_id, name, description,
                image_path, image_url, audio_path, audio_url,
                prompt, negative_prompt, duration, fps, resolution, style, motion_strength,
                vol_task_id, vol_request_id,
                status, progress, result_video_path, result_video_url,
                result_thumbnail_path, result_thumbnail_url,
                error_message, error_code,
                started_at, completed_at, generation_time_ms,
                created_at, updated_at
            ) VALUES (
                ?1, ?2, ?3, ?4,
                ?5, ?6, ?7, ?8,
                ?9, ?10, ?11, ?12, ?13, ?14, ?15,
                ?16, ?17,
                ?18, ?19, ?20, ?21,
                ?22, ?23,
                ?24, ?25,
                ?26, ?27, ?28,
                ?29, ?30
            )",
            params![
                record.id,
                record.project_id,
                record.name,
                record.description,
                record.image_path,
                record.image_url,
                record.audio_path,
                record.audio_url,
                record.prompt,
                record.negative_prompt,
                record.duration,
                record.fps,
                record.resolution,
                record.style,
                record.motion_strength,
                record.vol_task_id,
                record.vol_request_id,
                record.status.as_str(),
                record.progress,
                record.result_video_path,
                record.result_video_url,
                record.result_thumbnail_path,
                record.result_thumbnail_url,
                record.error_message,
                record.error_code,
                record.started_at.map(|dt| dt.timestamp()),
                record.completed_at.map(|dt| dt.timestamp()),
                record.generation_time_ms,
                record.created_at.timestamp(),
                record.updated_at.timestamp(),
            ],
        )?;

        Ok(())
    }

    /// 更新视频生成记录
    pub async fn update(&self, record: &VideoGenerationRecord) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

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

        pooled_conn.execute(
            "UPDATE video_generation_records SET
                project_id = ?2, name = ?3, description = ?4,
                image_path = ?5, image_url = ?6, audio_path = ?7, audio_url = ?8,
                prompt = ?9, negative_prompt = ?10, duration = ?11, fps = ?12,
                resolution = ?13, style = ?14, motion_strength = ?15,
                vol_task_id = ?16, vol_request_id = ?17,
                status = ?18, progress = ?19, result_video_path = ?20, result_video_url = ?21,
                result_thumbnail_path = ?22, result_thumbnail_url = ?23,
                error_message = ?24, error_code = ?25,
                started_at = ?26, completed_at = ?27, generation_time_ms = ?28,
                updated_at = ?29
            WHERE id = ?1",
            params![
                record.id,
                record.project_id,
                record.name,
                record.description,
                record.image_path,
                record.image_url,
                record.audio_path,
                record.audio_url,
                record.prompt,
                record.negative_prompt,
                record.duration,
                record.fps,
                record.resolution,
                record.style,
                record.motion_strength,
                record.vol_task_id,
                record.vol_request_id,
                record.status.as_str(),
                record.progress,
                record.result_video_path,
                record.result_video_url,
                record.result_thumbnail_path,
                record.result_thumbnail_url,
                record.error_message,
                record.error_code,
                record.started_at.map(|dt| dt.timestamp()),
                record.completed_at.map(|dt| dt.timestamp()),
                record.generation_time_ms,
                record.updated_at.timestamp(),
            ],
        )?;

        Ok(())
    }

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

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

        let result = pooled_conn.query_row(
            "SELECT id, project_id, name, description,
                    image_path, image_url, audio_path, audio_url,
                    prompt, negative_prompt, duration, fps, resolution, style, motion_strength,
                    vol_task_id, vol_request_id,
                    status, progress, result_video_path, result_video_url,
                    result_thumbnail_path, result_thumbnail_url,
                    error_message, error_code,
                    started_at, completed_at, generation_time_ms,
                    created_at, updated_at
             FROM video_generation_records WHERE id = ?1",
            params![id],
            |row| self.row_to_record(row),
        );

        match result {
            Ok(record) => Ok(Some(record)),
            Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
            Err(e) => Err(e.into()),
        }
    }

    /// 获取视频生成记录列表
    pub async fn get_list(&self, query: VideoGenerationQuery) -> Result<Vec<VideoGenerationRecord>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

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

        let mut sql = "SELECT id, project_id, name, description,
                              image_path, image_url, audio_path, audio_url,
                              prompt, negative_prompt, duration, fps, resolution, style, motion_strength,
                              vol_task_id, vol_request_id,
                              status, progress, result_video_path, result_video_url,
                              result_thumbnail_path, result_thumbnail_url,
                              error_message, error_code,
                              started_at, completed_at, generation_time_ms,
                              created_at, updated_at
                       FROM video_generation_records WHERE 1=1".to_string();

        let mut params: Vec<Box<dyn rusqlite::ToSql>> = Vec::new();

        // 添加查询条件
        if let Some(project_id) = &query.project_id {
            sql.push_str(" AND project_id = ?");
            params.push(Box::new(project_id.clone()));
        }

        if let Some(status) = &query.status {
            sql.push_str(" AND status = ?");
            params.push(Box::new(status.as_str()));
        }

        // 添加排序
        if let Some(order_by) = &query.order_by {
            sql.push_str(&format!(" ORDER BY {}", order_by));
            if query.order_desc.unwrap_or(false) {
                sql.push_str(" DESC");
            } else {
                sql.push_str(" ASC");
            }
        }

        // 添加分页
        if let Some(limit) = query.limit {
            sql.push_str(&format!(" LIMIT {}", limit));
        }

        if let Some(offset) = query.offset {
            sql.push_str(&format!(" OFFSET {}", offset));
        }

        let mut stmt = pooled_conn.prepare(&sql)?;
        let param_refs: Vec<&dyn rusqlite::ToSql> = params.iter().map(|p| p.as_ref()).collect();
        
        let rows = stmt.query_map(&param_refs[..], |row| self.row_to_record(row))?;

        let mut records = Vec::new();
        for row in rows {
            records.push(row?);
        }

        Ok(records)
    }

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

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

        pooled_conn.execute(
            "DELETE FROM video_generation_records WHERE id = ?1",
            params![id],
        )?;

        Ok(())
    }

    /// 将数据库行转换为VideoGenerationRecord
    fn row_to_record(&self, row: &Row) -> rusqlite::Result<VideoGenerationRecord> {
        let status_str: String = row.get("status")?;
        let status = VideoGenerationStatus::from_str(&status_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                row.as_ref().column_index("status").unwrap(),
                rusqlite::types::Type::Text,
                Box::new(std::io::Error::new(std::io::ErrorKind::InvalidData, e))
            ))?;

        let started_at: Option<i64> = row.get("started_at")?;
        let completed_at: Option<i64> = row.get("completed_at")?;
        let created_at: i64 = row.get("created_at")?;
        let updated_at: i64 = row.get("updated_at")?;

        Ok(VideoGenerationRecord {
            id: row.get("id")?,
            project_id: row.get("project_id")?,
            name: row.get("name")?,
            description: row.get("description")?,
            image_path: row.get("image_path")?,
            image_url: row.get("image_url")?,
            audio_path: row.get("audio_path")?,
            audio_url: row.get("audio_url")?,
            prompt: row.get("prompt")?,
            negative_prompt: row.get("negative_prompt")?,
            duration: row.get("duration")?,
            fps: row.get("fps")?,
            resolution: row.get("resolution")?,
            style: row.get("style")?,
            motion_strength: row.get("motion_strength")?,
            vol_task_id: row.get("vol_task_id")?,
            vol_request_id: row.get("vol_request_id")?,
            status,
            progress: row.get("progress")?,
            result_video_path: row.get("result_video_path")?,
            result_video_url: row.get("result_video_url")?,
            result_thumbnail_path: row.get("result_thumbnail_path")?,
            result_thumbnail_url: row.get("result_thumbnail_url")?,
            error_message: row.get("error_message")?,
            error_code: row.get("error_code")?,
            started_at: started_at.map(|ts| DateTime::from_timestamp(ts, 0).unwrap_or_default()),
            completed_at: completed_at.map(|ts| DateTime::from_timestamp(ts, 0).unwrap_or_default()),
            generation_time_ms: row.get("generation_time_ms")?,
            created_at: DateTime::from_timestamp(created_at, 0).unwrap_or_default(),
            updated_at: DateTime::from_timestamp(updated_at, 0).unwrap_or_default(),
        })
    }
}
