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

/// 视频生成状态枚举
/// 遵循 Tauri 开发规范的数据模型设计原则
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum VideoGenerationStatus {
    Pending,    // 等待处理
    Processing, // 处理中
    Completed,  // 已完成
    Failed,     // 失败
}

impl VideoGenerationStatus {
    pub fn as_str(&self) -> &'static str {
        match self {
            VideoGenerationStatus::Pending => "Pending",
            VideoGenerationStatus::Processing => "Processing",
            VideoGenerationStatus::Completed => "Completed",
            VideoGenerationStatus::Failed => "Failed",
        }
    }

    pub fn from_str(s: &str) -> Result<Self, String> {
        match s {
            "Pending" => Ok(VideoGenerationStatus::Pending),
            "Processing" => Ok(VideoGenerationStatus::Processing),
            "Completed" => Ok(VideoGenerationStatus::Completed),
            "Failed" => Ok(VideoGenerationStatus::Failed),
            _ => Err(format!("未知的视频生成状态: {}", s)),
        }
    }
}

/// 视频生成记录实体模型
/// 遵循 Tauri 开发规范的数据模型设计原则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoGenerationRecord {
    pub id: String,
    pub project_id: Option<String>,
    pub name: String,
    pub description: Option<String>,
    
    // 输入文件信息
    pub image_path: Option<String>,
    pub image_url: Option<String>,
    pub audio_path: Option<String>,
    pub audio_url: Option<String>,
    
    // 生成参数
    pub prompt: Option<String>,
    pub negative_prompt: Option<String>,
    pub duration: i32, // 视频时长（秒）
    pub fps: i32, // 帧率
    pub resolution: String, // 分辨率
    pub style: Option<String>, // 风格参数
    pub motion_strength: f32, // 运动强度 0.0-1.0
    
    // 火山云API相关
    pub vol_task_id: Option<String>, // 火山云任务ID
    pub vol_request_id: Option<String>, // 火山云请求ID
    
    // 生成状态和结果
    pub status: VideoGenerationStatus,
    pub progress: i32, // 进度百分比 0-100
    pub result_video_path: Option<String>,
    pub result_video_url: Option<String>,
    pub result_thumbnail_path: Option<String>,
    pub result_thumbnail_url: Option<String>,
    
    // 错误信息
    pub error_message: Option<String>,
    pub error_code: Option<String>,
    
    // 时间戳
    pub started_at: Option<DateTime<Utc>>,
    pub completed_at: Option<DateTime<Utc>>,
    pub generation_time_ms: Option<i64>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

impl VideoGenerationRecord {
    /// 创建新的视频生成记录
    pub fn new(
        id: String,
        name: String,
        image_url: Option<String>,
        audio_url: Option<String>,
        prompt: Option<String>,
    ) -> Self {
        let now = Utc::now();
        
        Self {
            id,
            project_id: None,
            name,
            description: None,
            image_path: None,
            image_url,
            audio_path: None,
            audio_url,
            prompt,
            negative_prompt: None,
            duration: 5,
            fps: 24,
            resolution: "1080p".to_string(),
            style: None,
            motion_strength: 0.5,
            vol_task_id: None,
            vol_request_id: None,
            status: VideoGenerationStatus::Pending,
            progress: 0,
            result_video_path: None,
            result_video_url: None,
            result_thumbnail_path: None,
            result_thumbnail_url: None,
            error_message: None,
            error_code: None,
            started_at: None,
            completed_at: None,
            generation_time_ms: None,
            created_at: now,
            updated_at: now,
        }
    }

    /// 标记为开始处理
    pub fn mark_as_processing(&mut self, vol_task_id: Option<String>) {
        self.status = VideoGenerationStatus::Processing;
        self.vol_task_id = vol_task_id;
        self.started_at = Some(Utc::now());
        self.updated_at = Utc::now();
    }

    /// 标记为完成
    pub fn mark_as_completed(&mut self, result_video_url: String, result_thumbnail_url: Option<String>) {
        self.status = VideoGenerationStatus::Completed;
        self.result_video_url = Some(result_video_url);
        self.result_thumbnail_url = result_thumbnail_url;
        self.progress = 100;
        self.completed_at = Some(Utc::now());
        
        if let Some(started) = self.started_at {
            self.generation_time_ms = Some((Utc::now() - started).num_milliseconds());
        }
        
        self.updated_at = Utc::now();
    }

    /// 标记为失败
    pub fn mark_as_failed(&mut self, error_message: String, error_code: Option<String>) {
        self.status = VideoGenerationStatus::Failed;
        self.error_message = Some(error_message);
        self.error_code = error_code;
        self.completed_at = Some(Utc::now());
        
        if let Some(started) = self.started_at {
            self.generation_time_ms = Some((Utc::now() - started).num_milliseconds());
        }
        
        self.updated_at = Utc::now();
    }

    /// 更新进度
    pub fn update_progress(&mut self, progress: i32) {
        self.progress = progress.clamp(0, 100);
        self.updated_at = Utc::now();
    }

    /// 检查是否已完成（成功或失败）
    pub fn is_finished(&self) -> bool {
        matches!(self.status, VideoGenerationStatus::Completed | VideoGenerationStatus::Failed)
    }

    /// 检查是否成功完成
    pub fn is_successful(&self) -> bool {
        self.status == VideoGenerationStatus::Completed
    }

    /// 获取状态显示文本
    pub fn get_status_text(&self) -> &'static str {
        match self.status {
            VideoGenerationStatus::Pending => "等待处理",
            VideoGenerationStatus::Processing => "处理中",
            VideoGenerationStatus::Completed => "已完成",
            VideoGenerationStatus::Failed => "失败",
        }
    }

    /// 获取进度显示文本
    pub fn get_progress_text(&self) -> String {
        match self.status {
            VideoGenerationStatus::Pending => "等待开始".to_string(),
            VideoGenerationStatus::Processing => format!("{}%", self.progress),
            VideoGenerationStatus::Completed => "100%".to_string(),
            VideoGenerationStatus::Failed => "失败".to_string(),
        }
    }
}

/// 视频生成记录创建请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateVideoGenerationRequest {
    pub name: String,
    pub description: Option<String>,
    pub image_url: Option<String>,
    pub audio_url: Option<String>,
    pub prompt: Option<String>,
    pub negative_prompt: Option<String>,
    pub duration: Option<i32>,
    pub fps: Option<i32>,
    pub resolution: Option<String>,
    pub style: Option<String>,
    pub motion_strength: Option<f32>,
}

/// 视频生成记录查询参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoGenerationQuery {
    pub project_id: Option<String>,
    pub status: Option<VideoGenerationStatus>,
    pub limit: Option<i32>,
    pub offset: Option<i32>,
    pub order_by: Option<String>, // created_at, updated_at, name
    pub order_desc: Option<bool>,
}

impl Default for VideoGenerationQuery {
    fn default() -> Self {
        Self {
            project_id: None,
            status: None,
            limit: Some(50),
            offset: Some(0),
            order_by: Some("created_at".to_string()),
            order_desc: Some(true),
        }
    }
}
