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

/// AI视频分类记录数据模型
/// 遵循 Tauri 开发规范的数据模型设计原则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoClassificationRecord {
    /// 分类记录唯一标识符
    pub id: String,
    /// 素材片段ID
    pub segment_id: String,
    /// 素材ID
    pub material_id: String,
    /// 项目ID
    pub project_id: String,
    /// 分类结果
    pub category: String,
    /// 置信度 (0.0 - 1.0)
    pub confidence: f64,
    /// 分类理由
    pub reasoning: String,
    /// 关键特征
    pub features: Vec<String>,
    /// 商品匹配度
    pub product_match: bool,
    /// 质量评分 (0.0 - 1.0)
    pub quality_score: f64,
    /// Gemini文件URI
    pub gemini_file_uri: Option<String>,
    /// 原始AI响应
    pub raw_response: Option<String>,
    /// 分类状态
    pub status: ClassificationStatus,
    /// 错误信息
    pub error_message: Option<String>,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 更新时间
    pub updated_at: DateTime<Utc>,
}

/// AI视频分类任务数据模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoClassificationTask {
    /// 任务唯一标识符
    pub id: String,
    /// 素材片段ID
    pub segment_id: String,
    /// 素材ID
    pub material_id: String,
    /// 项目ID
    pub project_id: String,
    /// 视频文件路径
    pub video_file_path: String,
    /// 任务状态
    pub status: TaskStatus,
    /// 任务优先级
    pub priority: i32,
    /// 重试次数
    pub retry_count: i32,
    /// 最大重试次数
    pub max_retries: i32,
    /// Gemini文件URI（上传后获得）
    pub gemini_file_uri: Option<String>,
    /// 使用的提示词
    pub prompt_text: Option<String>,
    /// 错误信息
    pub error_message: Option<String>,
    /// 开始处理时间
    pub started_at: Option<DateTime<Utc>>,
    /// 完成时间
    pub completed_at: Option<DateTime<Utc>>,
    /// 创建时间
    pub created_at: DateTime<Utc>,
    /// 更新时间
    pub updated_at: DateTime<Utc>,
}

/// 分类状态枚举
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum ClassificationStatus {
    /// 已分类
    Classified,
    /// 分类失败
    Failed,
    /// 需要人工审核
    NeedsReview,
}

/// 任务状态枚举
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TaskStatus {
    /// 等待处理
    Pending,
    /// 上传中
    Uploading,
    /// 分析中
    Analyzing,
    /// 已完成
    Completed,
    /// 失败
    Failed,
    /// 已取消
    Cancelled,
}

/// 批量分类请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchClassificationRequest {
    /// 素材ID
    pub material_id: String,
    /// 项目ID
    pub project_id: String,
    /// 是否覆盖已有分类
    pub overwrite_existing: bool,
    /// 任务优先级
    pub priority: Option<i32>,
}

/// 项目一键分类请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProjectBatchClassificationRequest {
    /// 项目ID
    pub project_id: String,
    /// 是否覆盖已有分类
    pub overwrite_existing: Option<bool>,
    /// 要处理的素材类型（可选，默认只处理视频）
    pub material_types: Option<Vec<crate::data::models::material::MaterialType>>,
    /// 任务优先级
    pub priority: Option<i32>,
}

/// 项目一键分类响应
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProjectBatchClassificationResponse {
    /// 项目中总素材数
    pub total_materials: u32,
    /// 符合条件的素材数
    pub eligible_materials: u32,
    /// 创建的任务数
    pub created_tasks: u32,
    /// 创建的任务ID列表
    pub task_ids: Vec<String>,
    /// 跳过的素材ID列表（已有分类）
    pub skipped_materials: Vec<String>,
}

/// 分类任务查询参数
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ClassificationTaskQuery {
    /// 项目ID过滤
    pub project_id: Option<String>,
    /// 素材ID过滤
    pub material_id: Option<String>,
    /// 状态过滤
    pub status: Option<TaskStatus>,
    /// 分页大小
    pub limit: Option<i32>,
    /// 分页偏移
    pub offset: Option<i32>,
}

/// 分类统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClassificationStats {
    /// 总任务数
    pub total_tasks: i32,
    /// 等待中任务数
    pub pending_tasks: i32,
    /// 处理中任务数
    pub processing_tasks: i32,
    /// 已完成任务数
    pub completed_tasks: i32,
    /// 失败任务数
    pub failed_tasks: i32,
    /// 总分类记录数
    pub total_classifications: i32,
    /// 成功分类记录数
    pub successful_classifications: i32,
    /// 失败分类记录数
    pub failed_classifications: i32,
    /// 需要审核记录数
    pub needs_review_classifications: i32,
    /// 平均置信度
    pub average_confidence: f64,
    /// 平均质量评分
    pub average_quality_score: f64,
}

/// Gemini API响应结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GeminiClassificationResponse {
    /// 分类结果
    pub category: String,
    /// 置信度
    pub confidence: f64,
    /// 分类理由
    pub reasoning: String,
    /// 关键特征
    pub features: Vec<String>,
    /// 商品匹配度
    pub product_match: bool,
    /// 质量评分
    pub quality_score: f64,
}

impl VideoClassificationRecord {
    /// 创建新的分类记录
    pub fn new(
        segment_id: String,
        material_id: String,
        project_id: String,
        gemini_response: GeminiClassificationResponse,
        gemini_file_uri: Option<String>,
        raw_response: Option<String>,
    ) -> Self {
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            segment_id,
            material_id,
            project_id,
            category: gemini_response.category,
            confidence: gemini_response.confidence,
            reasoning: gemini_response.reasoning,
            features: gemini_response.features,
            product_match: gemini_response.product_match,
            quality_score: gemini_response.quality_score,
            gemini_file_uri,
            raw_response,
            status: ClassificationStatus::Classified,
            error_message: None,
            created_at: Utc::now(),
            updated_at: Utc::now(),
        }
    }

    /// 标记为失败
    pub fn mark_as_failed(&mut self, error_message: String) {
        self.status = ClassificationStatus::Failed;
        self.error_message = Some(error_message);
        self.updated_at = Utc::now();
    }

    /// 标记为需要审核
    pub fn mark_as_needs_review(&mut self, reason: String) {
        self.status = ClassificationStatus::NeedsReview;
        self.error_message = Some(reason);
        self.updated_at = Utc::now();
    }

    /// 是否需要人工审核（低置信度或低质量）
    pub fn needs_review(&self) -> bool {
        self.confidence < 0.7 || self.quality_score < 0.6
    }
}

impl VideoClassificationTask {
    /// 创建新的分类任务
    pub fn new(
        segment_id: String,
        material_id: String,
        project_id: String,
        video_file_path: String,
        priority: Option<i32>,
    ) -> Self {
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            segment_id,
            material_id,
            project_id,
            video_file_path,
            status: TaskStatus::Pending,
            priority: priority.unwrap_or(0),
            retry_count: 0,
            max_retries: 3,
            gemini_file_uri: None,
            prompt_text: None,
            error_message: None,
            started_at: None,
            completed_at: None,
            created_at: Utc::now(),
            updated_at: Utc::now(),
        }
    }

    /// 开始处理任务
    pub fn start_processing(&mut self) {
        self.status = TaskStatus::Uploading;
        self.started_at = Some(Utc::now());
        self.updated_at = Utc::now();
    }

    /// 设置为分析状态
    pub fn set_analyzing(&mut self, gemini_file_uri: String, prompt_text: String) {
        self.status = TaskStatus::Analyzing;
        self.gemini_file_uri = Some(gemini_file_uri);
        self.prompt_text = Some(prompt_text);
        self.updated_at = Utc::now();
    }

    /// 完成任务
    pub fn complete(&mut self) {
        self.status = TaskStatus::Completed;
        self.completed_at = Some(Utc::now());
        self.updated_at = Utc::now();
    }

    /// 任务失败
    pub fn fail(&mut self, error_message: String) {
        self.status = TaskStatus::Failed;
        self.error_message = Some(error_message);
        self.retry_count += 1;
        self.updated_at = Utc::now();
    }

    /// 是否可以重试
    pub fn can_retry(&self) -> bool {
        self.retry_count < self.max_retries && self.status == TaskStatus::Failed
    }

    /// 重置为等待状态（用于重试）
    pub fn reset_for_retry(&mut self) {
        self.status = TaskStatus::Pending;
        self.error_message = None;
        self.started_at = None;
        self.completed_at = None;
        self.updated_at = Utc::now();
    }
}

impl Default for ClassificationStatus {
    fn default() -> Self {
        ClassificationStatus::Classified
    }
}

impl Default for TaskStatus {
    fn default() -> Self {
        TaskStatus::Pending
    }
}
