/**
 * 模板匹配结果相关的 Tauri 命令
 * 遵循 Tauri 开发规范的 API 设计原则
 */

use tauri::{command, State};
use std::sync::Arc;

use crate::business::services::template_matching_result_service::{
    TemplateMatchingResultService, TemplateMatchingResultDetail, MatchingStatistics,
};
use crate::business::services::material_matching_service::MaterialMatchingResult as ServiceMatchingResult;
use crate::data::models::template_matching_result::{
    TemplateMatchingResult, CreateTemplateMatchingResultRequest,
    TemplateMatchingResultQueryOptions,
};
use crate::data::repositories::template_matching_result_repository::TemplateMatchingResultRepository;
use crate::data::repositories::material_repository::MaterialRepository;
use crate::infrastructure::database::Database;

/// 保存匹配结果到数据库
#[command]
pub async fn save_matching_result(
    service_result: ServiceMatchingResult,
    result_name: String,
    description: Option<String>,
    matching_duration_ms: u64,
    database: State<'_, Arc<Database>>,
) -> Result<TemplateMatchingResult, String> {
    println!("🚀 开始保存匹配结果");
    println!("📋 保存参数:");
    println!("  - result_name: {}", result_name);
    println!("  - description: {:?}", description);
    println!("  - matching_duration_ms: {}", matching_duration_ms);
    println!("  - project_id: {}", service_result.project_id);
    println!("  - template_id: {}", service_result.template_id);
    println!("  - binding_id: {}", service_result.binding_id);
    println!("  - matches 数量: {}", service_result.matches.len());
    println!("  - failed_segments 数量: {}", service_result.failed_segments.len());

    // 创建服务实例
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    // 保存匹配结果
    match service.save_matching_result(&service_result, result_name, description, matching_duration_ms).await {
        Ok(result) => {
            println!("✅ 匹配结果保存成功，ID: {}", result.id);
            Ok(result)
        }
        Err(e) => {
            println!("❌ 匹配结果保存失败: {}", e);
            Err(e.to_string())
        }
    }
}

/// 获取匹配结果详情
#[command]
pub async fn get_matching_result_detail(
    result_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Option<TemplateMatchingResultDetail>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.get_matching_result_detail(&result_id)
        .await
        .map_err(|e| e.to_string())
}

/// 获取项目的匹配结果列表
#[command]
pub async fn get_project_matching_results(
    project_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<TemplateMatchingResult>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.get_project_matching_results(&project_id)
        .await
        .map_err(|e| e.to_string())
}

/// 获取模板的匹配结果列表
#[command]
pub async fn get_template_matching_results(
    template_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<TemplateMatchingResult>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.get_template_matching_results(&template_id)
        .await
        .map_err(|e| e.to_string())
}

/// 获取绑定的匹配结果列表
#[command]
pub async fn get_binding_matching_results(
    binding_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<TemplateMatchingResult>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.get_binding_matching_results(&binding_id)
        .await
        .map_err(|e| e.to_string())
}

/// 查询匹配结果列表
#[command]
pub async fn list_matching_results(
    options: TemplateMatchingResultQueryOptions,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<TemplateMatchingResult>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.list_matching_results(options)
        .await
        .map_err(|e| e.to_string())
}

/// 删除匹配结果
#[command]
pub async fn delete_matching_result(
    result_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<bool, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.delete_matching_result(&result_id)
        .await
        .map_err(|e| e.to_string())
}

/// 软删除匹配结果
#[command]
pub async fn soft_delete_matching_result(
    result_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<bool, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.soft_delete_matching_result(&result_id)
        .await
        .map_err(|e| e.to_string())
}

/// 批量删除匹配结果
#[command]
pub async fn batch_delete_matching_results(
    result_ids: Vec<String>,
    database: State<'_, Arc<Database>>,
) -> Result<u32, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.batch_delete_matching_results(&result_ids)
        .await
        .map_err(|e| e.to_string())
}

/// 批量软删除匹配结果
#[command]
pub async fn batch_soft_delete_matching_results(
    result_ids: Vec<String>,
    database: State<'_, Arc<Database>>,
) -> Result<u32, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.batch_soft_delete_matching_results(&result_ids)
        .await
        .map_err(|e| e.to_string())
}

/// 批量删除匹配结果并重置资源使用状态
#[command]
pub async fn batch_delete_matching_results_with_usage_reset(
    result_ids: Vec<String>,
    database: State<'_, Arc<Database>>,
) -> Result<(u32, u32), String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let material_usage_repo = Arc::new(crate::data::repositories::material_usage_repository::MaterialUsageRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.batch_delete_matching_results_with_usage_reset(&result_ids, material_usage_repo)
        .await
        .map_err(|e| e.to_string())
}

/// 批量软删除匹配结果并重置资源使用状态
#[command]
pub async fn batch_soft_delete_matching_results_with_usage_reset(
    result_ids: Vec<String>,
    database: State<'_, Arc<Database>>,
) -> Result<(u32, u32), String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let material_usage_repo = Arc::new(crate::data::repositories::material_usage_repository::MaterialUsageRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.batch_soft_delete_matching_results_with_usage_reset(&result_ids, material_usage_repo)
        .await
        .map_err(|e| e.to_string())
}

/// 重置匹配结果的导出状态
#[command]
pub async fn reset_matching_result_export_status(
    result_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<bool, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));

    repository.reset_export_status(&result_id)
        .map(|_| true)
        .map_err(|e| e.to_string())
}

/// 更新匹配结果信息
#[command]
pub async fn update_matching_result_info(
    result_id: String,
    result_name: Option<String>,
    description: Option<String>,
    database: State<'_, Arc<Database>>,
) -> Result<Option<TemplateMatchingResult>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.update_matching_result_info(&result_id, result_name, description)
        .await
        .map_err(|e| e.to_string())
}

/// 设置匹配结果质量评分
#[command]
pub async fn set_matching_result_quality_score(
    result_id: String,
    quality_score: f64,
    database: State<'_, Arc<Database>>,
) -> Result<Option<TemplateMatchingResult>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.set_quality_score(&result_id, quality_score)
        .await
        .map_err(|e| e.to_string())
}

/// 获取匹配结果统计信息
#[command]
pub async fn get_matching_statistics(
    project_id: Option<String>,
    database: State<'_, Arc<Database>>,
) -> Result<MatchingStatistics, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let service = TemplateMatchingResultService::new(repository);

    service.get_matching_statistics(project_id.as_deref())
        .await
        .map_err(|e| e.to_string())
}

/// 创建匹配结果（手动创建，不通过匹配服务）
#[command]
pub async fn create_matching_result(
    request: CreateTemplateMatchingResultRequest,
    database: State<'_, Arc<Database>>,
) -> Result<TemplateMatchingResult, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));

    repository.create(request)
        .map_err(|e| e.to_string())
}

/// 根据ID获取匹配结果
#[command]
pub async fn get_matching_result_by_id(
    result_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Option<TemplateMatchingResult>, String> {
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));

    repository.get_by_id(&result_id)
        .map_err(|e| e.to_string())
}

/// 获取匹配结果状态选项（用于前端下拉选择）
#[command]
pub async fn get_matching_result_status_options() -> Result<Vec<(String, String)>, String> {
    Ok(vec![
        ("Success".to_string(), "匹配成功".to_string()),
        ("PartialSuccess".to_string(), "部分成功".to_string()),
        ("Failed".to_string(), "匹配失败".to_string()),
        ("Cancelled".to_string(), "已取消".to_string()),
    ])
}

/// 导出匹配结果到剪映格式 (V1版本)
#[command]
pub async fn export_matching_result_to_jianying(
    result_id: String,
    output_path: String,
    database: State<'_, Arc<Database>>,
) -> Result<String, String> {
    use std::time::Instant;
    use crate::data::repositories::export_record_repository::ExportRecordRepository;
    use crate::business::services::export_record_service::ExportRecordService;
    use crate::data::models::export_record::{ExportType, ExportFormat};

    println!("🎬 开始导出匹配结果到剪映格式 (V1)");
    println!("📋 导出参数:");
    println!("  - 匹配结果ID: {}", result_id);
    println!("  - 输出路径: {}", output_path);

    let start_time = Instant::now();

    // 创建服务实例
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let material_repository = Arc::new(MaterialRepository::new(database.inner().clone())
        .map_err(|e| format!("创建MaterialRepository失败: {}", e))?);
    let export_record_repository = Arc::new(ExportRecordRepository::new(database.inner().clone()));
    let export_record_service = ExportRecordService::new(export_record_repository, repository.clone());
    let service = TemplateMatchingResultService::new(repository);

    // 创建导出记录
    let export_record = match export_record_service.create_export_record(
        result_id.clone(),
        ExportType::JianYingV1,
        ExportFormat::Json,
        output_path.clone(),
        None,
    ).await {
        Ok(record) => record,
        Err(e) => {
            println!("❌ 创建导出记录失败: {}", e);
            return Err(format!("创建导出记录失败: {}", e));
        }
    };

    // 执行导出
    match service.export_to_jianying(&result_id, &output_path, material_repository).await {
        Ok(file_path) => {
            let duration_ms = start_time.elapsed().as_millis() as u64;

            // 标记导出成功
            if let Err(e) = export_record_service.mark_export_success(
                export_record.id,
                file_path.clone(),
                duration_ms,
            ).await {
                println!("⚠️ 更新导出记录失败: {}", e);
            }

            println!("✅ 导出成功: {}", file_path);
            Ok(file_path)
        }
        Err(e) => {
            let duration_ms = start_time.elapsed().as_millis() as u64;

            // 标记导出失败
            if let Err(err) = export_record_service.mark_export_failed(
                export_record.id,
                e.to_string(),
                duration_ms,
            ).await {
                println!("⚠️ 更新导出记录失败: {}", err);
            }

            println!("❌ 导出失败: {}", e);
            Err(e.to_string())
        }
    }
}

/// 导出匹配结果到剪映格式 (V2版本)
/// 基于原始模板的 draft_content.json 文件进行替换
#[command]
pub async fn export_matching_result_to_jianying_v2(
    result_id: String,
    output_path: String,
    database: State<'_, Arc<Database>>,
) -> Result<String, String> {
    use std::time::Instant;
    use crate::data::repositories::export_record_repository::ExportRecordRepository;
    use crate::business::services::export_record_service::ExportRecordService;
    use crate::data::models::export_record::{ExportType, ExportFormat};

    println!("🎬 开始导出匹配结果到剪映格式");
    println!("📋 导出参数:");
    println!("  - 匹配结果ID: {}", result_id);
    println!("  - 输出路径: {}", output_path);

    let start_time = Instant::now();

    // 创建服务实例
    let repository = Arc::new(TemplateMatchingResultRepository::new(database.inner().clone()));
    let material_repository = Arc::new(MaterialRepository::new(database.inner().clone())
        .map_err(|e| format!("创建MaterialRepository失败: {}", e))?);
    let template_service = Arc::new(crate::business::services::template_service::TemplateService::new(database.inner().clone()));
    let export_record_repository = Arc::new(ExportRecordRepository::new(database.inner().clone()));
    let export_record_service = ExportRecordService::new(export_record_repository, repository.clone());
    let service = TemplateMatchingResultService::new(repository);

    // 创建导出记录
    let export_record = match export_record_service.create_export_record(
        result_id.clone(),
        ExportType::JianYingV2,
        ExportFormat::Json,
        output_path.clone(),
        None,
    ).await {
        Ok(record) => record,
        Err(e) => {
            println!("❌ 创建导出记录失败: {}", e);
            return Err(format!("创建导出记录失败: {}", e));
        }
    };

    // 执行导出
    match service.export_to_jianying_v2(&result_id, &output_path, material_repository, template_service).await {
        Ok(file_path) => {
            let duration_ms = start_time.elapsed().as_millis() as u64;

            // 标记导出成功
            if let Err(e) = export_record_service.mark_export_success(
                export_record.id,
                file_path.clone(),
                duration_ms,
            ).await {
                println!("⚠️ 更新导出记录失败: {}", e);
            }

            println!("✅ 导出成功: {}", file_path);
            Ok(file_path)
        }
        Err(e) => {
            let duration_ms = start_time.elapsed().as_millis() as u64;

            // 标记导出失败
            if let Err(err) = export_record_service.mark_export_failed(
                export_record.id,
                e.to_string(),
                duration_ms,
            ).await {
                println!("⚠️ 更新导出记录失败: {}", err);
            }

            eprintln!("❌ 导出失败: {}", e);
            Err(format!("导出失败: {}", e))
        }
    }
}
