use anyhow::Result;
use std::sync::Arc;
use crate::data::models::system_voice::{SystemVoice, SystemVoiceType, CreateSystemVoiceRequest};
use crate::infrastructure::database::Database;

/// 系统音色仓库
pub struct SystemVoiceRepository {
    database: Arc<Database>,
}

impl SystemVoiceRepository {
    /// 创建新的系统音色仓库实例
    pub fn new(database: Arc<Database>) -> Self {
        Self { database }
    }

    /// 获取所有活跃的系统音色
    pub fn get_all_active(&self) -> Result<Vec<SystemVoice>> {
        self.database.with_connection(|conn| {
            SystemVoice::get_all_active(conn)
        })
        .map_err(|e| anyhow::anyhow!("获取系统音色列表失败: {}", e))
    }

    /// 根据类型获取系统音色
    pub fn get_by_type(&self, voice_type: SystemVoiceType) -> Result<Vec<SystemVoice>> {
        self.database.with_connection(|conn| {
            SystemVoice::get_by_type(conn, voice_type)
        })
        .map_err(|e| anyhow::anyhow!("根据类型获取系统音色失败: {}", e))
    }

    /// 根据voice_id获取系统音色
    pub fn get_by_voice_id(&self, voice_id: &str) -> Result<Option<SystemVoice>> {
        self.database.with_connection(|conn| {
            SystemVoice::get_by_voice_id(conn, voice_id)
        })
        .map_err(|e| anyhow::anyhow!("根据voice_id获取系统音色失败: {}", e))
    }

    /// 创建系统音色
    pub fn create(&self, request: CreateSystemVoiceRequest) -> Result<SystemVoice> {
        self.database.with_connection(|conn| {
            SystemVoice::create(conn, request)
        })
        .map_err(|e| anyhow::anyhow!("创建系统音色失败: {}", e))
    }

    /// 批量插入系统音色
    pub fn batch_insert(&self, voices: Vec<CreateSystemVoiceRequest>) -> Result<()> {
        self.database.with_connection(|conn| {
            SystemVoice::batch_insert(conn, voices)
        })
        .map_err(|e| anyhow::anyhow!("批量插入系统音色失败: {}", e))
    }

    /// 检查系统音色是否存在
    pub fn exists_by_voice_id(&self, voice_id: &str) -> Result<bool> {
        match self.get_by_voice_id(voice_id)? {
            Some(_) => Ok(true),
            None => Ok(false),
        }
    }

    /// 获取系统音色总数
    pub fn count_active(&self) -> Result<i64> {
        self.database.with_connection(|conn| {
            let mut stmt = conn.prepare("SELECT COUNT(*) FROM system_voices WHERE is_active = 1")?;
            let count: i64 = stmt.query_row([], |row| row.get(0))?;
            Ok(count)
        })
        .map_err(|e| anyhow::anyhow!("获取系统音色总数失败: {}", e))
    }

    /// 根据性别获取系统音色
    pub fn get_by_gender(&self, gender: &str) -> Result<Vec<SystemVoice>> {
        self.database.with_connection(|conn| {
            let mut stmt = conn.prepare(
                r#"
                SELECT id, voice_id, voice_name, voice_name_en, description,
                       voice_type, gender, language, is_active, sort_order,
                       created_at, updated_at
                FROM system_voices
                WHERE gender = ?1 AND is_active = 1
                ORDER BY sort_order ASC, voice_name ASC
                "#,
            )?;

            let voice_iter = stmt.query_map([gender], |row| SystemVoice::from_row(row))?;
            let mut voices = Vec::new();

            for voice in voice_iter {
                voices.push(voice?);
            }

            Ok(voices)
        })
        .map_err(|e| anyhow::anyhow!("根据性别获取系统音色失败: {}", e))
    }

    /// 根据语言获取系统音色
    pub fn get_by_language(&self, language: &str) -> Result<Vec<SystemVoice>> {
        self.database.with_connection(|conn| {
            let mut stmt = conn.prepare(
                r#"
                SELECT id, voice_id, voice_name, voice_name_en, description,
                       voice_type, gender, language, is_active, sort_order,
                       created_at, updated_at
                FROM system_voices
                WHERE language = ?1 AND is_active = 1
                ORDER BY sort_order ASC, voice_name ASC
                "#,
            )?;

            let voice_iter = stmt.query_map([language], |row| SystemVoice::from_row(row))?;
            let mut voices = Vec::new();

            for voice in voice_iter {
                voices.push(voice?);
            }

            Ok(voices)
        })
        .map_err(|e| anyhow::anyhow!("根据语言获取系统音色失败: {}", e))
    }

    /// 搜索系统音色
    pub fn search(&self, keyword: &str) -> Result<Vec<SystemVoice>> {
        self.database.with_connection(|conn| {
            let search_pattern = format!("%{}%", keyword);
            let mut stmt = conn.prepare(
                r#"
                SELECT id, voice_id, voice_name, voice_name_en, description,
                       voice_type, gender, language, is_active, sort_order,
                       created_at, updated_at
                FROM system_voices
                WHERE (voice_name LIKE ?1 OR voice_name_en LIKE ?1 OR description LIKE ?1)
                  AND is_active = 1
                ORDER BY sort_order ASC, voice_name ASC
                "#,
            )?;

            let voice_iter = stmt.query_map([&search_pattern], |row| SystemVoice::from_row(row))?;
            let mut voices = Vec::new();

            for voice in voice_iter {
                voices.push(voice?);
            }

            Ok(voices)
        })
        .map_err(|e| anyhow::anyhow!("搜索系统音色失败: {}", e))
    }

    /// 获取分页的系统音色列表
    pub fn get_paginated(&self, offset: i64, limit: i64) -> Result<Vec<SystemVoice>> {
        self.database.with_connection(|conn| {
            let mut stmt = conn.prepare(
                r#"
                SELECT id, voice_id, voice_name, voice_name_en, description,
                       voice_type, gender, language, is_active, sort_order,
                       created_at, updated_at
                FROM system_voices
                WHERE is_active = 1
                ORDER BY sort_order ASC, voice_name ASC
                LIMIT ?1 OFFSET ?2
                "#,
            )?;

            let voice_iter = stmt.query_map([limit, offset], |row| SystemVoice::from_row(row))?;
            let mut voices = Vec::new();

            for voice in voice_iter {
                voices.push(voice?);
            }

            Ok(voices)
        })
        .map_err(|e| anyhow::anyhow!("获取分页系统音色列表失败: {}", e))
    }
}
