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

use crate::data::models::hedra_lipsync_record::{HedraLipSyncRecord, HedraLipSyncStatus};
use crate::data::repositories::hedra_lipsync_repository::{HedraLipSyncRepository, HedraLipSyncStatistics};
use crate::infrastructure::database::Database;

/// Hedra 口型合成记录创建请求
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateHedraLipSyncRecordRequest {
    pub image_path: String,
    pub audio_path: String,
    pub prompt: Option<String>,
}

/// Hedra 口型合成记录更新请求
#[derive(Debug, Serialize, Deserialize)]
pub struct UpdateHedraLipSyncRecordRequest {
    pub id: String,
    pub task_id: Option<String>,
    pub image_url: Option<String>,
    pub audio_url: Option<String>,
    pub status: Option<String>,
    pub progress: Option<f32>,
    pub result_video_url: Option<String>,
    pub result_video_path: Option<String>,
    pub error_message: Option<String>,
    pub file_size_bytes: Option<i64>,
    pub video_duration_seconds: Option<f32>,
}

/// 批量删除请求
#[derive(Debug, Serialize, Deserialize)]
pub struct BatchDeleteRequest {
    pub ids: Vec<String>,
}

/// 调试记录信息
#[derive(Debug, Serialize, Deserialize)]
pub struct DebugRecordInfo {
    pub id: String,
    pub status: String,
    pub result_video_url: Option<String>,
    pub result_video_path: Option<String>,
    pub progress: f32,
    pub completed_at: Option<String>,
}

/// 创建 Hedra 口型合成记录
#[command]
pub async fn create_hedra_lipsync_record(
    request: CreateHedraLipSyncRecordRequest,
    database: State<'_, Arc<Database>>,
) -> Result<HedraLipSyncRecord, String> {
    info!("创建 Hedra 口型合成记录: {:?}", request);

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    let record = HedraLipSyncRecord::new(
        request.image_path,
        request.audio_path,
        request.prompt,
    );

    repository
        .save(&record)
        .map_err(|e| {
            error!("保存 Hedra 口型合成记录失败: {}", e);
            format!("保存记录失败: {}", e)
        })?;

    info!("Hedra 口型合成记录创建成功: {}", record.id);
    Ok(record)
}

/// 更新 Hedra 口型合成记录
#[command]
pub async fn update_hedra_lipsync_record(
    request: UpdateHedraLipSyncRecordRequest,
    database: State<'_, Arc<Database>>,
) -> Result<HedraLipSyncRecord, String> {
    info!("更新 Hedra 口型合成记录: {:?}", request);

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    let mut record = repository
        .find_by_id(&request.id)
        .map_err(|e| {
            error!("查找 Hedra 口型合成记录失败: {}", e);
            format!("查找记录失败: {}", e)
        })?
        .ok_or_else(|| format!("未找到ID为 {} 的记录", request.id))?;

    // 更新字段
    if let Some(task_id) = request.task_id {
        record.task_id = Some(task_id);
    }
    if let Some(image_url) = request.image_url {
        record.image_url = Some(image_url);
    }
    if let Some(audio_url) = request.audio_url {
        record.audio_url = Some(audio_url);
    }
    if let Some(status_str) = request.status {
        record.status = HedraLipSyncStatus::from_str(&status_str);
    }
    if let Some(progress) = request.progress {
        record.progress = progress;
    }
    if let Some(result_video_url) = request.result_video_url {
        record.result_video_url = Some(result_video_url);
    }
    if let Some(result_video_path) = request.result_video_path {
        record.result_video_path = Some(result_video_path);
    }
    if let Some(error_message) = request.error_message {
        record.error_message = Some(error_message);
    }
    if let Some(file_size_bytes) = request.file_size_bytes {
        record.file_size_bytes = Some(file_size_bytes);
    }
    if let Some(video_duration_seconds) = request.video_duration_seconds {
        record.video_duration_seconds = Some(video_duration_seconds);
    }

    repository
        .save(&record)
        .map_err(|e| {
            error!("更新 Hedra 口型合成记录失败: {}", e);
            format!("更新记录失败: {}", e)
        })?;

    info!("Hedra 口型合成记录更新成功: {}", record.id);
    Ok(record)
}

/// 获取 Hedra 口型合成记录
#[command]
pub async fn get_hedra_lipsync_record(
    id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Option<HedraLipSyncRecord>, String> {
    info!("获取 Hedra 口型合成记录: {}", id);

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    repository
        .find_by_id(&id)
        .map_err(|e| {
            error!("查找 Hedra 口型合成记录失败: {}", e);
            format!("查找记录失败: {}", e)
        })
}

/// 根据任务ID获取 Hedra 口型合成记录
#[command]
pub async fn get_hedra_lipsync_record_by_task_id(
    task_id: String,
    database: State<'_, Arc<Database>>,
) -> Result<Option<HedraLipSyncRecord>, String> {
    info!("根据任务ID获取 Hedra 口型合成记录: {}", task_id);

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    repository
        .find_by_task_id(&task_id)
        .map_err(|e| {
            error!("根据任务ID查找 Hedra 口型合成记录失败: {}", e);
            format!("查找记录失败: {}", e)
        })
}

/// 获取所有 Hedra 口型合成记录
#[command]
pub async fn get_all_hedra_lipsync_records(
    limit: Option<i32>,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<HedraLipSyncRecord>, String> {
    info!("获取所有 Hedra 口型合成记录，限制: {:?}", limit);

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    repository
        .get_all(limit)
        .map_err(|e| {
            error!("获取所有 Hedra 口型合成记录失败: {}", e);
            format!("获取记录失败: {}", e)
        })
}

/// 根据状态获取 Hedra 口型合成记录
#[command]
pub async fn get_hedra_lipsync_records_by_status(
    status: String,
    database: State<'_, Arc<Database>>,
) -> Result<Vec<HedraLipSyncRecord>, String> {
    info!("根据状态获取 Hedra 口型合成记录: {}", status);

    let repository = HedraLipSyncRepository::new(database.inner().clone());
    let status_enum = HedraLipSyncStatus::from_str(&status);

    repository
        .get_by_status(status_enum)
        .map_err(|e| {
            error!("根据状态获取 Hedra 口型合成记录失败: {}", e);
            format!("获取记录失败: {}", e)
        })
}

/// 删除 Hedra 口型合成记录
#[command]
pub async fn delete_hedra_lipsync_record(
    id: String,
    database: State<'_, Arc<Database>>,
) -> Result<(), String> {
    info!("删除 Hedra 口型合成记录: {}", id);

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    repository
        .delete_by_id(&id)
        .map_err(|e| {
            error!("删除 Hedra 口型合成记录失败: {}", e);
            format!("删除记录失败: {}", e)
        })?;

    info!("Hedra 口型合成记录删除成功: {}", id);
    Ok(())
}

/// 批量删除 Hedra 口型合成记录
#[command]
pub async fn batch_delete_hedra_lipsync_records(
    request: BatchDeleteRequest,
    database: State<'_, Arc<Database>>,
) -> Result<usize, String> {
    info!("批量删除 Hedra 口型合成记录: {:?}", request.ids);

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    let deleted_count = repository
        .delete_batch(&request.ids)
        .map_err(|e| {
            error!("批量删除 Hedra 口型合成记录失败: {}", e);
            format!("批量删除记录失败: {}", e)
        })?;

    info!("批量删除 Hedra 口型合成记录成功，删除数量: {}", deleted_count);
    Ok(deleted_count)
}

/// 获取 Hedra 口型合成统计信息
#[command]
pub async fn get_hedra_lipsync_statistics(
    database: State<'_, Arc<Database>>,
) -> Result<HedraLipSyncStatistics, String> {
    info!("获取 Hedra 口型合成统计信息");

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    repository
        .get_statistics()
        .map_err(|e| {
            error!("获取 Hedra 口型合成统计信息失败: {}", e);
            format!("获取统计信息失败: {}", e)
        })
}

/// 调试：获取所有记录的状态信息
#[command]
pub async fn debug_hedra_lipsync_records(
    database: State<'_, Arc<Database>>,
) -> Result<Vec<DebugRecordInfo>, String> {
    info!("调试：获取所有 Hedra 口型合成记录状态");

    let repository = HedraLipSyncRepository::new(database.inner().clone());

    let records = repository
        .get_all(Some(100))
        .map_err(|e| {
            error!("获取 Hedra 口型合成记录失败: {}", e);
            format!("获取记录失败: {}", e)
        })?;

    let debug_info: Vec<DebugRecordInfo> = records
        .into_iter()
        .map(|record| DebugRecordInfo {
            id: record.id,
            status: record.status.as_str().to_string(),
            result_video_url: record.result_video_url,
            result_video_path: record.result_video_path,
            progress: record.progress,
            completed_at: record.completed_at.map(|dt| dt.to_rfc3339()),
        })
        .collect();

    info!("调试信息获取成功，共 {} 条记录", debug_info.len());
    Ok(debug_info)
}
