use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use tauri::{command, State};
use tracing::{error, info};

use crate::data::models::system_voice::{SystemVoice, SystemVoiceType};
use crate::data::repositories::system_voice_repository::SystemVoiceRepository;
use crate::infrastructure::database::Database;

/// 系统音色查询请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemVoiceQuery {
    pub voice_type: Option<String>,
    pub gender: Option<String>,
    pub language: Option<String>,
    pub keyword: Option<String>,
    pub page: Option<i64>,
    pub page_size: Option<i64>,
}

/// 系统音色响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemVoiceResponse {
    pub voices: Vec<SystemVoice>,
    pub total: i64,
    pub page: i64,
    pub page_size: i64,
    pub total_pages: i64,
}

/// 获取所有活跃的系统音色
#[command]
pub async fn get_system_voices(
    database: State<'_, Arc<Database>>,
) -> Result<Vec<SystemVoice>, String> {

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    match repository.get_all_active() {
        Ok(voices) => {
            Ok(voices)
        }
        Err(e) => {
            error!("获取系统音色列表失败: {}", e);
            Err(format!("获取系统音色列表失败: {}", e))
        }
    }
}

/// 根据类型获取系统音色
#[command]
pub async fn get_system_voices_by_type(
    voice_type: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<SystemVoice>, String> {
    info!("根据类型获取系统音色: {}", voice_type);

    let repository = SystemVoiceRepository::new(database.inner().clone());
    let voice_type_enum = SystemVoiceType::from_str(&voice_type);
    
    match repository.get_by_type(voice_type_enum) {
        Ok(voices) => {
            Ok(voices)
        }
        Err(e) => {
            error!("根据类型获取系统音色失败: {}", e);
            Err(format!("根据类型获取系统音色失败: {}", e))
        }
    }
}

/// 根据性别获取系统音色
#[command]
pub async fn get_system_voices_by_gender(
    gender: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<SystemVoice>, String> {
    info!("根据性别获取系统音色: {}", gender);

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    match repository.get_by_gender(&gender) {
        Ok(voices) => {
            Ok(voices)
        }
        Err(e) => {
            error!("根据性别获取系统音色失败: {}", e);
            Err(format!("根据性别获取系统音色失败: {}", e))
        }
    }
}

/// 根据语言获取系统音色
#[command]
pub async fn get_system_voices_by_language(
    language: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<SystemVoice>, String> {
    info!("根据语言获取系统音色: {}", language);

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    match repository.get_by_language(&language) {
        Ok(voices) => {
            Ok(voices)
        }
        Err(e) => {
            error!("根据语言获取系统音色失败: {}", e);
            Err(format!("根据语言获取系统音色失败: {}", e))
        }
    }
}

/// 搜索系统音色
#[command]
pub async fn search_system_voices(
    keyword: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<SystemVoice>, String> {
    info!("搜索系统音色: {}", keyword);

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    match repository.search(&keyword) {
        Ok(voices) => {
            info!("搜索到 {} 个匹配的系统音色", voices.len());
            Ok(voices)
        }
        Err(e) => {
            error!("搜索系统音色失败: {}", e);
            Err(format!("搜索系统音色失败: {}", e))
        }
    }
}

/// 分页获取系统音色
#[command]
pub async fn get_system_voices_paginated(
    query: SystemVoiceQuery,
    database: State<'_, Arc<Database>>,
) -> Result<SystemVoiceResponse, String> {
    info!("分页获取系统音色: {:?}", query);

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    let page = query.page.unwrap_or(1);
    let page_size = query.page_size.unwrap_or(20);
    let offset = (page - 1) * page_size;

    // 根据查询条件获取音色列表
    let voices = if let Some(keyword) = &query.keyword {
        repository.search(keyword)
    } else if let Some(voice_type) = &query.voice_type {
        let voice_type_enum = SystemVoiceType::from_str(voice_type);
        repository.get_by_type(voice_type_enum)
    } else if let Some(gender) = &query.gender {
        repository.get_by_gender(gender)
    } else if let Some(language) = &query.language {
        repository.get_by_language(language)
    } else {
        repository.get_paginated(offset, page_size)
    };

    match voices {
        Ok(voices) => {
            // 获取总数
            let total = match repository.count_active() {
                Ok(count) => count,
                Err(e) => {
                    error!("获取系统音色总数失败: {}", e);
                    return Err(format!("获取系统音色总数失败: {}", e));
                }
            };

            let total_pages = (total + page_size - 1) / page_size;

            let response = SystemVoiceResponse {
                voices,
                total,
                page,
                page_size,
                total_pages,
            };

            Ok(response)
        }
        Err(e) => {
            error!("分页获取系统音色失败: {}", e);
            Err(format!("分页获取系统音色失败: {}", e))
        }
    }
}

/// 根据voice_id获取系统音色详情
#[command]
pub async fn get_system_voice_by_id(
    voice_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Option<SystemVoice>, String> {
    info!("根据voice_id获取系统音色详情: {}", voice_id);

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    match repository.get_by_voice_id(&voice_id) {
        Ok(voice) => {
            Ok(voice)
        }
        Err(e) => {
            error!("根据voice_id获取系统音色详情失败: {}", e);
            Err(format!("根据voice_id获取系统音色详情失败: {}", e))
        }
    }
}

/// 检查系统音色是否存在
#[command]
pub async fn check_system_voice_exists(
    voice_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<bool, String> {
    info!("检查系统音色是否存在: {}", voice_id);

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    match repository.exists_by_voice_id(&voice_id) {
        Ok(exists) => {
            info!("系统音色 {} 存在状态: {}", voice_id, exists);
            Ok(exists)
        }
        Err(e) => {
            error!("检查系统音色是否存在失败: {}", e);
            Err(format!("检查系统音色是否存在失败: {}", e))
        }
    }
}

/// 获取系统音色统计信息
#[command]
pub async fn get_system_voice_stats(
    database: State<'_, Arc<Database>>,
) -> Result<serde_json::Value, String> {
    info!("获取系统音色统计信息");

    let repository = SystemVoiceRepository::new(database.inner().clone());
    
    // 获取总数
    let total = match repository.count_active() {
        Ok(count) => count,
        Err(e) => {
            error!("获取系统音色总数失败: {}", e);
            return Err(format!("获取系统音色总数失败: {}", e));
        }
    };

    // 按类型统计
    let mut type_stats = serde_json::Map::new();
    for voice_type in ["system", "premium", "child", "character", "holiday", "english"] {
        let voice_type_enum = SystemVoiceType::from_str(voice_type);
        match repository.get_by_type(voice_type_enum) {
            Ok(voices) => {
                type_stats.insert(voice_type.to_string(), serde_json::Value::Number(voices.len().into()));
            }
            Err(e) => {
                error!("获取 {} 类型音色统计失败: {}", voice_type, e);
            }
        }
    }

    // 按性别统计
    let mut gender_stats = serde_json::Map::new();
    for gender in ["male", "female", "child", "other"] {
        match repository.get_by_gender(gender) {
            Ok(voices) => {
                gender_stats.insert(gender.to_string(), serde_json::Value::Number(voices.len().into()));
            }
            Err(e) => {
                error!("获取 {} 性别音色统计失败: {}", gender, e);
            }
        }
    }

    let stats = serde_json::json!({
        "total": total,
        "by_type": type_stats,
        "by_gender": gender_stats
    });

    Ok(stats)
}
