use tauri::{command, State};
use crate::app_state::AppState;
use crate::business::services::video_generation_service::{VideoGenerationService, VideoGenerationStatistics};
use crate::data::models::video_generation::{
    VideoGenerationTask, VideoGenerationQueryParams, CreateVideoGenerationRequest
};

/// 创建视频生成任务命令
/// 遵循 Tauri 开发规范的命令设计模式
#[command]
pub async fn create_video_generation_task(
    state: State<'_, AppState>,
    request: CreateVideoGenerationRequest,
) -> Result<VideoGenerationTask, String> {
    // 克隆仓库引用以避免跨await边界的Send问题
    let (video_gen_repo, model_repo) = {
        let video_gen_repository_guard = state.get_video_generation_repository()
            .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;

        let video_gen_repository = video_gen_repository_guard.as_ref()
            .ok_or("视频生成仓库未初始化")?;

        let model_repository_guard = state.get_model_repository()
            .map_err(|e| format!("获取模特仓库失败: {}", e))?;

        let model_repository = model_repository_guard.as_ref()
            .ok_or("模特仓库未初始化")?;

        // 这里我们需要克隆仓库，但由于仓库包含Arc，这应该是轻量级的
        (video_gen_repository.clone(), model_repository.clone())
    };

    VideoGenerationService::create_task(&video_gen_repo, &model_repo, request)
        .await
        .map_err(|e| e.to_string())
}

/// 执行视频生成任务命令
#[command]
pub async fn execute_video_generation_task(
    state: State<'_, AppState>,
    task_id: String,
) -> Result<VideoGenerationTask, String> {
    let (video_gen_repo, model_repo) = {
        let video_gen_repository_guard = state.get_video_generation_repository()
            .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;

        let video_gen_repository = video_gen_repository_guard.as_ref()
            .ok_or("视频生成仓库未初始化")?;

        let model_repository_guard = state.get_model_repository()
            .map_err(|e| format!("获取模特仓库失败: {}", e))?;

        let model_repository = model_repository_guard.as_ref()
            .ok_or("模特仓库未初始化")?;

        (video_gen_repository.clone(), model_repository.clone())
    };

    VideoGenerationService::execute_task(&video_gen_repo, &model_repo, &task_id)
        .await
        .map_err(|e| e.to_string())
}

/// 获取视频生成任务命令
#[command]
pub async fn get_video_generation_task(
    state: State<'_, AppState>,
    task_id: String,
) -> Result<Option<VideoGenerationTask>, String> {
    let repository_guard = state.get_video_generation_repository()
        .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
    
    let repository = repository_guard.as_ref()
        .ok_or("视频生成仓库未初始化")?;

    VideoGenerationService::get_task(repository, &task_id)
        .map_err(|e| e.to_string())
}

/// 获取视频生成任务列表命令
#[command]
pub async fn get_video_generation_tasks(
    state: State<'_, AppState>,
    params: VideoGenerationQueryParams,
) -> Result<Vec<VideoGenerationTask>, String> {
    let repository_guard = state.get_video_generation_repository()
        .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
    
    let repository = repository_guard.as_ref()
        .ok_or("视频生成仓库未初始化")?;

    VideoGenerationService::get_tasks(repository, &params)
        .map_err(|e| e.to_string())
}

/// 取消视频生成任务命令
#[command]
pub async fn cancel_video_generation_task(
    state: State<'_, AppState>,
    task_id: String,
) -> Result<VideoGenerationTask, String> {
    let repository_guard = state.get_video_generation_repository()
        .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
    
    let repository = repository_guard.as_ref()
        .ok_or("视频生成仓库未初始化")?;

    VideoGenerationService::cancel_task(repository, &task_id)
        .map_err(|e| e.to_string())
}

/// 删除视频生成任务命令
#[command]
pub async fn delete_video_generation_task(
    state: State<'_, AppState>,
    task_id: String,
) -> Result<(), String> {
    let repository_guard = state.get_video_generation_repository()
        .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
    
    let repository = repository_guard.as_ref()
        .ok_or("视频生成仓库未初始化")?;

    VideoGenerationService::delete_task(repository, &task_id)
        .map_err(|e| e.to_string())
}

/// 重试视频生成任务命令
#[command]
pub async fn retry_video_generation_task(
    state: State<'_, AppState>,
    task_id: String,
) -> Result<VideoGenerationTask, String> {
    let (video_gen_repo, model_repo) = {
        let video_gen_repository_guard = state.get_video_generation_repository()
            .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;

        let video_gen_repository = video_gen_repository_guard.as_ref()
            .ok_or("视频生成仓库未初始化")?;

        let model_repository_guard = state.get_model_repository()
            .map_err(|e| format!("获取模特仓库失败: {}", e))?;

        let model_repository = model_repository_guard.as_ref()
            .ok_or("模特仓库未初始化")?;

        (video_gen_repository.clone(), model_repository.clone())
    };

    VideoGenerationService::retry_task(&video_gen_repo, &model_repo, &task_id)
        .await
        .map_err(|e| e.to_string())
}

/// 获取模特视频生成统计命令
#[command]
pub async fn get_model_video_generation_statistics(
    state: State<'_, AppState>,
    model_id: String,
) -> Result<VideoGenerationStatistics, String> {
    let repository_guard = state.get_video_generation_repository()
        .map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
    
    let repository = repository_guard.as_ref()
        .ok_or("视频生成仓库未初始化")?;

    VideoGenerationService::get_model_statistics(repository, &model_id)
        .map_err(|e| e.to_string())
}

/// 获取模特详情（包含照片）命令
#[command]
pub async fn get_model_detail_with_photos(
    state: State<'_, AppState>,
    model_id: String,
) -> Result<Option<crate::data::models::model::Model>, String> {
    let repository_guard = state.get_model_repository()
        .map_err(|e| format!("获取模特仓库失败: {}", e))?;
    
    let repository = repository_guard.as_ref()
        .ok_or("模特仓库未初始化")?;

    // 使用完整的get_by_id方法获取包含照片的模特信息
    repository.get_by_id(&model_id)
        .map_err(|e| e.to_string())
}

/// 批量上传模特照片命令（上传到云端）
#[command]
pub async fn batch_upload_model_photos(
    state: State<'_, AppState>,
    model_id: String,
    file_paths: Vec<String>,
    photo_type: crate::data::models::model::PhotoType,
    description: Option<String>,
    tags: Option<Vec<String>>,
) -> Result<Vec<crate::data::models::model::ModelPhoto>, String> {
    // 克隆仓库引用以避免跨await边界的Send问题
    let repository = {
        let repository_guard = state.get_model_repository()
            .map_err(|e| format!("获取模特仓库失败: {}", e))?;

        let repository = repository_guard.as_ref()
            .ok_or("模特仓库未初始化")?;

        repository.clone()
    };

    let mut uploaded_photos = Vec::new();

    for file_path in file_paths {
        match crate::business::services::model_service::ModelService::add_model_photo_with_cloud_upload(
            &repository,
            &model_id,
            file_path,
            photo_type.clone(),
            description.clone(),
            tags.clone(),
        ).await {
            Ok(photo) => uploaded_photos.push(photo),
            Err(e) => {
                println!("⚠️ 上传照片失败: {}", e);
                // 继续上传其他照片，不中断整个过程
            }
        }
    }

    if uploaded_photos.is_empty() {
        return Err("没有成功上传任何照片".to_string());
    }

    Ok(uploaded_photos)
}
