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

/// 语音生成记录状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum SpeechGenerationStatus {
    Pending,    // 等待中
    Processing, // 处理中
    Completed,  // 已完成
    Failed,     // 失败
    Cancelled,  // 已取消
}

impl SpeechGenerationStatus {
    pub fn as_str(&self) -> &'static str {
        match self {
            SpeechGenerationStatus::Pending => "pending",
            SpeechGenerationStatus::Processing => "processing",
            SpeechGenerationStatus::Completed => "completed",
            SpeechGenerationStatus::Failed => "failed",
            SpeechGenerationStatus::Cancelled => "cancelled",
        }
    }

    pub fn from_str(s: &str) -> Self {
        match s {
            "pending" => SpeechGenerationStatus::Pending,
            "processing" => SpeechGenerationStatus::Processing,
            "completed" => SpeechGenerationStatus::Completed,
            "failed" => SpeechGenerationStatus::Failed,
            "cancelled" => SpeechGenerationStatus::Cancelled,
            _ => SpeechGenerationStatus::Pending,
        }
    }
}

/// 语音生成记录
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpeechGenerationRecord {
    pub id: String,
    pub text: String,
    pub voice_id: String,
    pub voice_name: Option<String>,
    pub speed: f32,
    pub volume: f32,
    pub emotion: Option<String>,
    pub audio_url: Option<String>,
    pub local_file_path: Option<String>,
    pub status: SpeechGenerationStatus,
    pub error_message: Option<String>,
    pub created_at: DateTime<Utc>,
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
    pub duration_ms: Option<i64>,
}

/// 创建语音生成记录请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateSpeechGenerationRecordRequest {
    pub text: String,
    pub voice_id: String,
    pub voice_name: Option<String>,
    pub speed: f32,
    pub volume: f32,
    pub emotion: Option<String>,
    pub audio_url: Option<String>,
    pub local_file_path: Option<String>,
}

impl SpeechGenerationRecord {
    /// 创建新的语音生成记录
    pub fn new(request: CreateSpeechGenerationRecordRequest) -> Self {
        Self {
            id: Uuid::new_v4().to_string(),
            text: request.text,
            voice_id: request.voice_id,
            voice_name: request.voice_name,
            speed: request.speed,
            volume: request.volume,
            emotion: request.emotion,
            audio_url: request.audio_url,
            local_file_path: request.local_file_path,
            status: SpeechGenerationStatus::Pending,
            error_message: None,
            created_at: Utc::now(),
            started_at: None,
            completed_at: None,
            duration_ms: None,
        }
    }

    /// 开始生成
    pub fn start_generation(&mut self) {
        self.status = SpeechGenerationStatus::Processing;
        self.started_at = Some(Utc::now());
    }

    /// 完成生成
    pub fn complete_generation(&mut self, audio_url: Option<String>, local_file_path: Option<String>) {
        self.status = SpeechGenerationStatus::Completed;
        self.audio_url = audio_url;
        self.local_file_path = local_file_path;
        self.completed_at = Some(Utc::now());
        
        if let Some(started_at) = self.started_at {
            self.duration_ms = Some((Utc::now() - started_at).num_milliseconds());
        }
    }

    /// 标记为失败
    pub fn mark_failed(&mut self, error_message: String) {
        self.status = SpeechGenerationStatus::Failed;
        self.error_message = Some(error_message);
        self.completed_at = Some(Utc::now());
        
        if let Some(started_at) = self.started_at {
            self.duration_ms = Some((Utc::now() - started_at).num_milliseconds());
        }
    }

    /// 从数据库行创建记录
    pub fn from_row(row: &Row) -> SqliteResult<Self> {
        let created_at_str: String = row.get("created_at")?;
        let created_at = DateTime::parse_from_rfc3339(&created_at_str)
            .map_err(|_| rusqlite::Error::InvalidColumnType(0, "created_at".to_string(), rusqlite::types::Type::Text))?
            .with_timezone(&Utc);

        let started_at_str: Option<String> = row.get("started_at")?;
        let started_at = started_at_str
            .and_then(|s| DateTime::parse_from_rfc3339(&s).ok())
            .map(|dt| dt.with_timezone(&Utc));

        let completed_at_str: Option<String> = row.get("completed_at")?;
        let completed_at = completed_at_str
            .and_then(|s| DateTime::parse_from_rfc3339(&s).ok())
            .map(|dt| dt.with_timezone(&Utc));

        Ok(Self {
            id: row.get("id")?,
            text: row.get("text")?,
            voice_id: row.get("voice_id")?,
            voice_name: row.get("voice_name")?,
            speed: row.get("speed")?,
            volume: row.get("volume")?,
            emotion: row.get("emotion")?,
            audio_url: row.get("audio_url")?,
            local_file_path: row.get("local_file_path")?,
            status: SpeechGenerationStatus::from_str(&row.get::<_, String>("status")?),
            error_message: row.get("error_message")?,
            created_at,
            started_at,
            completed_at,
            duration_ms: row.get("duration_ms")?,
        })
    }

    /// 保存到数据库
    pub fn save(&self, conn: &Connection) -> SqliteResult<()> {
        conn.execute(
            r#"
            INSERT OR REPLACE INTO speech_generation_records (
                id, text, voice_id, voice_name, speed, volume, emotion,
                audio_url, local_file_path, status, error_message,
                created_at, started_at, completed_at, duration_ms
            ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15)
            "#,
            params![
                self.id,
                self.text,
                self.voice_id,
                self.voice_name,
                self.speed,
                self.volume,
                self.emotion,
                self.audio_url,
                self.local_file_path,
                self.status.as_str(),
                self.error_message,
                self.created_at.to_rfc3339(),
                self.started_at.map(|dt| dt.to_rfc3339()),
                self.completed_at.map(|dt| dt.to_rfc3339()),
                self.duration_ms,
            ],
        )?;

        Ok(())
    }

    /// 根据ID获取记录
    pub fn get_by_id(conn: &Connection, id: &str) -> SqliteResult<Option<Self>> {
        let mut stmt = conn.prepare(
            "SELECT * FROM speech_generation_records WHERE id = ?1"
        )?;

        let mut rows = stmt.query_map([id], Self::from_row)?;

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

    /// 获取所有记录（按创建时间倒序）
    pub fn get_all(conn: &Connection, limit: Option<i32>) -> SqliteResult<Vec<Self>> {
        let sql = if let Some(limit) = limit {
            format!("SELECT * FROM speech_generation_records ORDER BY created_at DESC LIMIT {}", limit)
        } else {
            "SELECT * FROM speech_generation_records ORDER BY created_at DESC".to_string()
        };

        let mut stmt = conn.prepare(&sql)?;
        let rows = stmt.query_map([], Self::from_row)?;

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

        Ok(records)
    }

    /// 根据音色ID获取记录
    pub fn get_by_voice_id(conn: &Connection, voice_id: &str, limit: Option<i32>) -> SqliteResult<Vec<Self>> {
        let sql = if let Some(limit) = limit {
            format!("SELECT * FROM speech_generation_records WHERE voice_id = ?1 ORDER BY created_at DESC LIMIT {}", limit)
        } else {
            "SELECT * FROM speech_generation_records WHERE voice_id = ?1 ORDER BY created_at DESC".to_string()
        };

        let mut stmt = conn.prepare(&sql)?;
        let rows = stmt.query_map([voice_id], Self::from_row)?;

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

        Ok(records)
    }

    /// 删除记录
    pub fn delete(&self, conn: &Connection) -> SqliteResult<()> {
        conn.execute(
            "DELETE FROM speech_generation_records WHERE id = ?1",
            params![self.id],
        )?;
        Ok(())
    }
}

/// 创建语音生成记录表
pub fn create_table(conn: &Connection) -> SqliteResult<()> {
    conn.execute(
        r#"
        CREATE TABLE IF NOT EXISTS speech_generation_records (
            id TEXT PRIMARY KEY,
            text TEXT NOT NULL,
            voice_id TEXT NOT NULL,
            voice_name TEXT,
            speed REAL NOT NULL DEFAULT 1.0,
            volume REAL NOT NULL DEFAULT 1.0,
            emotion TEXT,
            audio_url TEXT,
            local_file_path TEXT,
            status TEXT NOT NULL DEFAULT 'pending',
            error_message TEXT,
            created_at TEXT NOT NULL,
            started_at TEXT,
            completed_at TEXT,
            duration_ms INTEGER
        )
        "#,
        [],
    )?;

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

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

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

    Ok(())
}
