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

/// 素材类型枚举
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum MaterialType {
    Video,
    Audio,
    Image,
    Document,
    Other,
}

impl MaterialType {
    pub fn from_extension(ext: &str) -> Self {
        match ext.to_lowercase().as_str() {
            "mp4" | "avi" | "mov" | "mkv" | "wmv" | "flv" | "webm" | "m4v" => MaterialType::Video,
            "mp3" | "wav" | "flac" | "aac" | "ogg" | "wma" | "m4a" => MaterialType::Audio,
            "jpg" | "jpeg" | "png" | "gif" | "bmp" | "tiff" | "webp" | "svg" => MaterialType::Image,
            "pdf" | "doc" | "docx" | "txt" | "md" | "rtf" => MaterialType::Document,
            _ => MaterialType::Other,
        }
    }
}

/// 素材处理状态枚举
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum ProcessingStatus {
    Pending,      // 待处理
    Processing,   // 处理中
    Completed,    // 处理完成
    Failed,       // 处理失败
    Skipped,      // 跳过（重复文件）
}

/// 视频元数据结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VideoMetadata {
    pub duration: f64,           // 时长（秒）
    pub width: u32,              // 宽度
    pub height: u32,             // 高度
    pub fps: f64,                // 帧率
    pub bitrate: u64,            // 比特率
    pub codec: String,           // 编码格式
    pub format: String,          // 容器格式
    pub has_audio: bool,         // 是否包含音频
    pub audio_codec: Option<String>, // 音频编码格式
    pub audio_bitrate: Option<u64>,  // 音频比特率
    pub audio_sample_rate: Option<u32>, // 音频采样率
}

/// 音频元数据结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AudioMetadata {
    pub duration: f64,           // 时长（秒）
    pub bitrate: u64,            // 比特率
    pub codec: String,           // 编码格式
    pub sample_rate: u32,        // 采样率
    pub channels: u32,           // 声道数
    pub format: String,          // 音频格式
}

/// 图片元数据结构
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImageMetadata {
    pub width: u32,              // 宽度
    pub height: u32,             // 高度
    pub format: String,          // 图片格式
    pub color_space: Option<String>, // 色彩空间
    pub has_alpha: bool,         // 是否有透明通道
    pub dpi: Option<u32>,        // DPI
}

/// 素材元数据联合体
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MaterialMetadata {
    Video(VideoMetadata),
    Audio(AudioMetadata),
    Image(ImageMetadata),
    None,
}

/// 场景检测结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SceneDetection {
    pub scenes: Vec<SceneSegment>,
    pub total_scenes: u32,
    pub detection_method: String,
    pub threshold: f64,
}

/// 场景片段
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SceneSegment {
    pub start_time: f64,         // 开始时间（秒）
    pub end_time: f64,           // 结束时间（秒）
    pub duration: f64,           // 片段时长（秒）
    pub scene_id: u32,           // 场景ID
    pub confidence: f64,         // 检测置信度
}

/// 素材实体模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Material {
    pub id: String,
    pub project_id: String,
    pub model_id: Option<String>, // 关联的模特ID
    pub name: String,
    pub original_path: String,
    pub file_size: u64,
    pub md5_hash: String,
    pub material_type: MaterialType,
    pub processing_status: ProcessingStatus,
    pub metadata: MaterialMetadata,
    pub scene_detection: Option<SceneDetection>,
    pub segments: Vec<MaterialSegment>,
    pub thumbnail_path: Option<String>, // 素材缩略图路径
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub processed_at: Option<DateTime<Utc>>,
    pub error_message: Option<String>,
}

/// 素材片段（切分后的片段）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MaterialSegment {
    pub id: String,
    pub material_id: String,
    pub segment_index: u32,
    pub start_time: f64,
    pub end_time: f64,
    pub duration: f64,
    pub file_path: String,
    pub file_size: u64,
    pub thumbnail_path: Option<String>, // 缩略图路径
    pub usage_count: u32,               // 使用次数
    pub is_used: bool,                  // 是否已使用
    pub last_used_at: Option<DateTime<Utc>>, // 最后使用时间
    pub created_at: DateTime<Utc>,
}

/// 创建素材请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateMaterialRequest {
    pub project_id: String,
    pub file_paths: Vec<String>,
    pub auto_process: bool,
    pub max_segment_duration: Option<f64>, // 最大片段时长（秒）
    pub model_id: Option<String>, // 可选的模特绑定ID
    pub skip_start_ms: Option<u32>, // 跳过视频开头的毫秒数（用于AI生成视频避免相同首帧）
}

/// 视频切分模式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum VideoSplitMode {
    Fast,      // 快速模式（流复制，可能有画面问题）
    Accurate,  // 精确模式（重新编码，确保画面完整）
    Smart,     // 智能模式（关键帧对齐 + 快速切分）
}

impl Default for VideoSplitMode {
    fn default() -> Self {
        VideoSplitMode::Accurate
    }
}

/// 素材处理配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MaterialProcessingConfig {
    pub max_segment_duration: f64,      // 最大片段时长（秒）
    pub scene_detection_threshold: f64, // 场景检测阈值
    pub enable_scene_detection: bool,   // 是否启用场景检测
    pub video_quality: String,          // 视频质量设置
    pub audio_quality: String,          // 音频质量设置
    pub output_format: String,          // 输出格式
    pub auto_process: Option<bool>,     // 是否自动处理
    pub split_mode: VideoSplitMode,     // 视频切分模式
    pub skip_start_ms: Option<u32>,     // 跳过视频开头的毫秒数（用于AI生成视频避免相同首帧）
}

impl Default for MaterialProcessingConfig {
    fn default() -> Self {
        Self {
            max_segment_duration: 300.0, // 5分钟
            scene_detection_threshold: 0.3,
            enable_scene_detection: true,
            video_quality: "medium".to_string(),
            audio_quality: "medium".to_string(),
            output_format: "mp4".to_string(),
            auto_process: Some(true),
            split_mode: VideoSplitMode::Accurate, // 默认使用精确模式
            skip_start_ms: None, // 默认不跳过开头
        }
    }
}

/// 素材导入结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MaterialImportResult {
    pub total_files: u32,
    pub processed_files: u32,
    pub skipped_files: u32,
    pub failed_files: u32,
    pub created_materials: Vec<Material>,
    pub errors: Vec<String>,
    pub processing_time: f64, // 处理时间（秒）
}

/// 素材统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MaterialStats {
    pub total_materials: u32,
    pub video_count: u32,
    pub audio_count: u32,
    pub image_count: u32,
    pub other_count: u32,
    pub total_size: u64,
    pub total_duration: f64, // 总时长（秒）
    pub processing_status_counts: std::collections::HashMap<String, u32>,
}

impl Material {
    /// 创建新的素材实例
    pub fn new(
        project_id: String,
        name: String,
        original_path: String,
        file_size: u64,
        md5_hash: String,
        material_type: MaterialType,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            project_id,
            model_id: None,
            name,
            original_path,
            file_size,
            md5_hash,
            material_type,
            processing_status: ProcessingStatus::Pending,
            metadata: MaterialMetadata::None,
            scene_detection: None,
            segments: Vec::new(),
            thumbnail_path: None,
            created_at: now,
            updated_at: now,
            processed_at: None,
            error_message: None,
        }
    }

    /// 创建新的素材实例（带模特绑定）
    pub fn new_with_model(
        project_id: String,
        name: String,
        original_path: String,
        file_size: u64,
        md5_hash: String,
        material_type: MaterialType,
        model_id: Option<String>,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            project_id,
            model_id,
            name,
            original_path,
            file_size,
            md5_hash,
            material_type,
            processing_status: ProcessingStatus::Pending,
            metadata: MaterialMetadata::None,
            scene_detection: None,
            segments: Vec::new(),
            thumbnail_path: None,
            created_at: now,
            updated_at: now,
            processed_at: None,
            error_message: None,
        }
    }

    /// 更新处理状态
    pub fn update_status(&mut self, status: ProcessingStatus, error_message: Option<String>) {
        self.processing_status = status;
        self.error_message = error_message;
        self.updated_at = Utc::now();
        
        if matches!(status, ProcessingStatus::Completed | ProcessingStatus::Failed) {
            self.processed_at = Some(Utc::now());
        }
    }

    /// 设置元数据
    pub fn set_metadata(&mut self, metadata: MaterialMetadata) {
        self.metadata = metadata;
        self.updated_at = Utc::now();
    }

    /// 添加场景检测结果
    pub fn set_scene_detection(&mut self, scene_detection: SceneDetection) {
        self.scene_detection = Some(scene_detection);
        self.updated_at = Utc::now();
    }

    /// 添加片段
    pub fn add_segment(&mut self, segment: MaterialSegment) {
        self.segments.push(segment);
        self.updated_at = Utc::now();
    }

    /// 获取总时长
    pub fn get_duration(&self) -> Option<f64> {
        match &self.metadata {
            MaterialMetadata::Video(video) => Some(video.duration),
            MaterialMetadata::Audio(audio) => Some(audio.duration),
            _ => None,
        }
    }

    /// 检查是否需要切分
    pub fn needs_segmentation(&self, max_duration: f64) -> bool {
        if let Some(duration) = self.get_duration() {
            duration > max_duration
        } else {
            false
        }
    }

    /// 关联模特
    pub fn associate_model(&mut self, model_id: String) {
        self.model_id = Some(model_id);
        self.updated_at = Utc::now();
    }

    /// 取消关联模特
    pub fn disassociate_model(&mut self) {
        self.model_id = None;
        self.updated_at = Utc::now();
    }

    /// 检查是否关联了模特
    pub fn has_associated_model(&self) -> bool {
        self.model_id.is_some()
    }

    /// 获取关联的模特ID
    pub fn get_associated_model_id(&self) -> Option<&String> {
        self.model_id.as_ref()
    }
}

impl MaterialSegment {
    /// 创建新的素材片段
    pub fn new(
        material_id: String,
        segment_index: u32,
        start_time: f64,
        end_time: f64,
        file_path: String,
        file_size: u64,
    ) -> Self {
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            material_id,
            segment_index,
            start_time,
            end_time,
            duration: end_time - start_time,
            file_path,
            file_size,
            thumbnail_path: None,
            usage_count: 0,
            is_used: false,
            last_used_at: None,
            created_at: Utc::now(),
        }
    }

    /// 检查片段是否满足最小时长要求
    pub fn meets_duration_requirement(&self, required_duration: f64) -> bool {
        self.duration >= required_duration
    }

    /// 计算与目标时长的匹配度（越接近越好，返回0.0-1.0）
    pub fn duration_match_score(&self, target_duration: f64) -> f64 {
        if self.duration < target_duration {
            return 0.0; // 时长不足，不匹配
        }

        // 计算匹配度：时长越接近目标时长，分数越高
        let excess_ratio = (self.duration - target_duration) / target_duration;
        let score = if excess_ratio <= 0.1 {
            1.0 // 超出10%以内，完美匹配
        } else if excess_ratio <= 0.5 {
            0.8 - (excess_ratio - 0.1) * 2.0 // 超出10%-50%，线性递减
        } else {
            0.3 // 超出50%以上，低匹配度
        };
        score
    }
}

/// 批量删除失败项
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchDeleteFailedItem {
    pub id: String,
    pub error_message: String,
}

/// 批量删除结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchDeleteResult {
    pub total_count: usize,
    pub success_count: usize,
    pub failed_count: usize,
    pub successful_ids: Vec<String>,
    pub failed_items: Vec<BatchDeleteFailedItem>,
}
