use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};
use std::path::PathBuf;

/// 批量处理任务状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum BatchTaskStatus {
    /// 待处理
    Pending,
    /// 处理中
    Processing,
    /// 已完成
    Completed,
    /// 失败
    Failed,
    /// 已取消
    Cancelled,
}

/// 批量处理任务
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchProcessingTask {
    pub id: String,
    pub name: String,
    pub workflow_template_id: i64,
    pub input_folder: PathBuf,
    pub output_folder: PathBuf,
    pub status: BatchTaskStatus,
    pub total_files: u32,
    pub processed_files: u32,
    pub failed_files: u32,
    pub created_at: DateTime<Utc>,
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
    pub error_message: Option<String>,
}

/// 批量处理文件项
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchFileItem {
    pub id: String,
    pub batch_task_id: String,
    pub input_file_path: PathBuf,
    pub output_file_path: Option<PathBuf>,
    pub status: BatchTaskStatus,
    pub execution_id: Option<i64>,
    pub error_message: Option<String>,
    pub processed_at: Option<DateTime<Utc>>,
}

/// 创建批量处理任务请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateBatchTaskRequest {
    pub name: String,
    pub workflow_template_id: i64,
    pub input_folder: String,
    pub output_folder: String,
    pub file_extensions: Vec<String>, // 支持的文件扩展名，如 ["jpg", "png", "jpeg"]
    pub recursive: bool, // 是否递归扫描子文件夹
}

/// 批量处理进度信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchProcessingProgress {
    pub task_id: String,
    pub status: BatchTaskStatus,
    pub total_files: u32,
    pub processed_files: u32,
    pub failed_files: u32,
    pub current_file: Option<String>,
    pub progress_percentage: f32,
    pub estimated_remaining_time: Option<u64>, // 秒
}

/// 批量处理统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchProcessingStats {
    pub total_tasks: u32,
    pub active_tasks: u32,
    pub completed_tasks: u32,
    pub failed_tasks: u32,
    pub total_files_processed: u32,
    pub average_processing_time_per_file: f32, // 秒
}

impl BatchProcessingTask {
    /// 创建新的批量处理任务
    pub fn new(request: CreateBatchTaskRequest) -> Self {
        let now = Utc::now();
        Self {
            id: format!("batch_{}", now.timestamp_millis()),
            name: request.name,
            workflow_template_id: request.workflow_template_id,
            input_folder: PathBuf::from(request.input_folder),
            output_folder: PathBuf::from(request.output_folder),
            status: BatchTaskStatus::Pending,
            total_files: 0,
            processed_files: 0,
            failed_files: 0,
            created_at: now,
            started_at: None,
            completed_at: None,
            error_message: None,
        }
    }

    /// 开始处理
    pub fn start_processing(&mut self, total_files: u32) {
        self.status = BatchTaskStatus::Processing;
        self.started_at = Some(Utc::now());
        self.total_files = total_files;
        self.processed_files = 0;
        self.failed_files = 0;
    }

    /// 更新进度
    pub fn update_progress(&mut self, processed: u32, failed: u32) {
        self.processed_files = processed;
        self.failed_files = failed;
    }

    /// 完成处理
    pub fn complete_processing(&mut self) {
        self.status = BatchTaskStatus::Completed;
        self.completed_at = Some(Utc::now());
    }

    /// 标记失败
    pub fn mark_failed(&mut self, error_message: String) {
        self.status = BatchTaskStatus::Failed;
        self.completed_at = Some(Utc::now());
        self.error_message = Some(error_message);
    }

    /// 取消处理
    pub fn cancel(&mut self) {
        self.status = BatchTaskStatus::Cancelled;
        self.completed_at = Some(Utc::now());
    }

    /// 获取进度百分比
    pub fn get_progress_percentage(&self) -> f32 {
        if self.total_files == 0 {
            return 0.0;
        }
        (self.processed_files as f32 / self.total_files as f32) * 100.0
    }

    /// 获取处理时长（秒）
    pub fn get_duration_seconds(&self) -> Option<i64> {
        if let Some(started_at) = self.started_at {
            let end_time = self.completed_at.unwrap_or_else(Utc::now);
            Some((end_time - started_at).num_seconds())
        } else {
            None
        }
    }
}

impl BatchFileItem {
    /// 创建新的文件项
    pub fn new(batch_task_id: String, input_file_path: PathBuf) -> Self {
        Self {
            id: format!("file_{}_{}", batch_task_id, input_file_path.file_name().unwrap_or_default().to_string_lossy()),
            batch_task_id,
            input_file_path,
            output_file_path: None,
            status: BatchTaskStatus::Pending,
            execution_id: None,
            error_message: None,
            processed_at: None,
        }
    }

    /// 开始处理
    pub fn start_processing(&mut self, execution_id: i64) {
        self.status = BatchTaskStatus::Processing;
        self.execution_id = Some(execution_id);
    }

    /// 完成处理
    pub fn complete_processing(&mut self, output_file_path: PathBuf) {
        self.status = BatchTaskStatus::Completed;
        self.output_file_path = Some(output_file_path);
        self.processed_at = Some(Utc::now());
    }

    /// 标记失败
    pub fn mark_failed(&mut self, error_message: String) {
        self.status = BatchTaskStatus::Failed;
        self.error_message = Some(error_message);
        self.processed_at = Some(Utc::now());
    }
}
