use rusqlite::{Connection, Result as SqliteResult, Row};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// 声音克隆记录实体模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VoiceCloneRecord {
    pub id: String,
    pub voice_id: String,
    pub voice_name: Option<String>,
    pub clone_text: String,
    pub audio_url: String,
    pub file_id: Option<u64>,
    pub model: Option<String>,
    pub need_noise_reduction: bool,
    pub prefix: Option<String>,
    pub audio_file_path: Option<String>,
    pub status: String,
    pub created_at: String,
    pub updated_at: String,
}

/// 创建声音克隆记录请求
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateVoiceCloneRecordRequest {
    pub voice_id: String,
    pub voice_name: Option<String>,
    pub clone_text: String,
    pub audio_url: String,
    pub file_id: Option<u64>,
    pub model: Option<String>,
    pub need_noise_reduction: bool,
    pub prefix: Option<String>,
    pub audio_file_path: Option<String>,
}

impl VoiceCloneRecord {
    /// 从数据库行创建实例
    pub fn from_row(row: &Row) -> SqliteResult<Self> {
        Ok(VoiceCloneRecord {
            id: row.get("id")?,
            voice_id: row.get("voice_id")?,
            voice_name: row.get("voice_name")?,
            clone_text: row.get("clone_text")?,
            audio_url: row.get("audio_url")?,
            file_id: row.get("file_id")?,
            model: row.get("model")?,
            need_noise_reduction: row.get("need_noise_reduction")?,
            prefix: row.get("prefix")?,
            audio_file_path: row.get("audio_file_path")?,
            status: row.get("status")?,
            created_at: row.get("created_at")?,
            updated_at: row.get("updated_at")?,
        })
    }

    /// 创建新的声音克隆记录
    pub fn create(conn: &Connection, request: CreateVoiceCloneRecordRequest) -> SqliteResult<VoiceCloneRecord> {
        let id = Uuid::new_v4().to_string();
        let now = chrono::Utc::now().to_rfc3339();

        conn.execute(
            r#"
            INSERT INTO voice_clone_records (
                id, voice_id, voice_name, clone_text, audio_url, file_id,
                model, need_noise_reduction, prefix, audio_file_path,
                status, created_at, updated_at
            ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
            "#,
            (
                &id,
                &request.voice_id,
                &request.voice_name,
                &request.clone_text,
                &request.audio_url,
                &request.file_id,
                &request.model,
                &request.need_noise_reduction,
                &request.prefix,
                &request.audio_file_path,
                "active",
                &now,
                &now,
            ),
        )?;

        Ok(VoiceCloneRecord {
            id,
            voice_id: request.voice_id,
            voice_name: request.voice_name,
            clone_text: request.clone_text,
            audio_url: request.audio_url,
            file_id: request.file_id,
            model: request.model,
            need_noise_reduction: request.need_noise_reduction,
            prefix: request.prefix,
            audio_file_path: request.audio_file_path,
            status: "active".to_string(),
            created_at: now.clone(),
            updated_at: now,
        })
    }

    /// 获取所有活跃的声音克隆记录
    pub fn get_all_active(conn: &Connection) -> SqliteResult<Vec<VoiceCloneRecord>> {
        let mut stmt = conn.prepare(
            r#"
            SELECT id, voice_id, voice_name, clone_text, audio_url, file_id,
                   model, need_noise_reduction, prefix, audio_file_path,
                   status, created_at, updated_at
            FROM voice_clone_records
            WHERE status = 'active'
            ORDER BY created_at DESC
            "#,
        )?;

        let records = stmt
            .query_map([], |row| VoiceCloneRecord::from_row(row))?
            .collect::<Result<Vec<_>, _>>()?;

        Ok(records)
    }

    /// 根据voice_id获取记录
    pub fn get_by_voice_id(conn: &Connection, voice_id: &str) -> SqliteResult<Option<VoiceCloneRecord>> {
        let mut stmt = conn.prepare(
            r#"
            SELECT id, voice_id, voice_name, clone_text, audio_url, file_id,
                   model, need_noise_reduction, prefix, audio_file_path,
                   status, created_at, updated_at
            FROM voice_clone_records
            WHERE voice_id = ?1 AND status = 'active'
            "#,
        )?;

        let mut rows = stmt.query_map([voice_id], |row| VoiceCloneRecord::from_row(row))?;

        match rows.next() {
            Some(row) => Ok(Some(row?)),
            None => Ok(None),
        }
    }

    /// 删除声音克隆记录（软删除）
    pub fn delete(conn: &Connection, voice_id: &str) -> SqliteResult<()> {
        let now = chrono::Utc::now().to_rfc3339();
        
        conn.execute(
            "UPDATE voice_clone_records SET status = 'deleted', updated_at = ?1 WHERE voice_id = ?2",
            (&now, voice_id),
        )?;

        Ok(())
    }

    /// 更新声音克隆记录
    pub fn update_voice_name(conn: &Connection, voice_id: &str, voice_name: Option<String>) -> SqliteResult<()> {
        let now = chrono::Utc::now().to_rfc3339();
        
        conn.execute(
            "UPDATE voice_clone_records SET voice_name = ?1, updated_at = ?2 WHERE voice_id = ?3",
            (&voice_name, &now, voice_id),
        )?;

        Ok(())
    }
}

/// 创建声音克隆记录表
pub fn create_table(conn: &Connection) -> SqliteResult<()> {
    conn.execute(
        r#"
        CREATE TABLE IF NOT EXISTS voice_clone_records (
            id TEXT PRIMARY KEY,
            voice_id TEXT NOT NULL UNIQUE,
            voice_name TEXT,
            clone_text TEXT NOT NULL,
            audio_url TEXT NOT NULL,
            file_id INTEGER,
            model TEXT,
            need_noise_reduction BOOLEAN DEFAULT 1,
            prefix TEXT,
            audio_file_path TEXT,
            status TEXT NOT NULL DEFAULT 'active',
            created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
            updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
        )
        "#,
        [],
    )?;

    // 创建索引
    conn.execute(
        "CREATE INDEX IF NOT EXISTS idx_voice_clone_records_voice_id ON voice_clone_records(voice_id)",
        [],
    )?;

    conn.execute(
        "CREATE INDEX IF NOT EXISTS idx_voice_clone_records_created_at ON voice_clone_records(created_at)",
        [],
    )?;

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

    Ok(())
}
