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

/// 模板实体模型
/// 遵循 Tauri 开发规范的数据模型设计原则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Template {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub canvas_config: CanvasConfig,
    pub duration: u64, // 模板总时长（微秒）
    pub fps: f64,
    pub materials: Vec<TemplateMaterial>,
    pub tracks: Vec<Track>,
    pub import_status: ImportStatus,
    pub source_file_path: Option<String>, // 原始draft_content.json文件路径
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub is_active: bool,
}

/// 画布配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CanvasConfig {
    pub width: u32,
    pub height: u32,
    pub ratio: String, // "original", "16:9", "9:16", etc.
}

/// 模板素材
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateMaterial {
    pub id: String,
    pub template_id: String,
    pub original_id: String, // 原始剪映素材ID
    pub name: String,
    pub material_type: TemplateMaterialType,
    pub original_path: String, // 原始本地路径
    pub remote_url: Option<String>, // 上传后的远程URL
    pub file_size: Option<u64>,
    pub duration: Option<u64>, // 素材时长（微秒）
    pub width: Option<u32>,
    pub height: Option<u32>,
    pub upload_status: UploadStatus,
    pub file_exists: bool,        // 本地文件是否存在
    pub upload_success: bool,     // 是否上传成功
    pub metadata: Option<String>, // JSON格式的额外元数据
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// 轨道
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Track {
    pub id: String,
    pub template_id: String,
    pub name: String,
    pub track_type: TrackType,
    pub track_index: u32, // 轨道索引
    pub segments: Vec<TrackSegment>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// 片段匹配规则类型
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum SegmentMatchingRule {
    /// 固定素材（默认）- 不替换
    FixedMaterial,
    /// AI分类素材 - 使用指定AI分类的素材
    AiClassification { category_id: String, category_name: String },
    /// 随机匹配 - 从项目中随机选择合适的素材
    RandomMatch,
    /// 文件名序号匹配 - 根据文件名中的序号进行匹配
    FilenameSequence { target_sequence: String },
    /// 按顺序匹配 - 按照AI分类权重顺序依次匹配
    PriorityOrder { category_ids: Vec<String> },
}

impl Default for SegmentMatchingRule {
    fn default() -> Self {
        Self::FixedMaterial
    }
}

impl SegmentMatchingRule {
    /// 获取规则的显示名称
    pub fn display_name(&self) -> String {
        match self {
            Self::FixedMaterial => "固定素材".to_string(),
            Self::AiClassification { category_name, .. } => format!("AI分类: {}", category_name),
            Self::RandomMatch => "随机匹配".to_string(),
            Self::FilenameSequence { target_sequence } => format!("文件名序号: {}", target_sequence),
            Self::PriorityOrder { category_ids } => format!("按顺序匹配: {} 个分类", category_ids.len()),
        }
    }

    /// 检查是否为固定素材
    pub fn is_fixed_material(&self) -> bool {
        matches!(self, Self::FixedMaterial)
    }

    /// 检查是否为AI分类
    pub fn is_ai_classification(&self) -> bool {
        matches!(self, Self::AiClassification { .. })
    }

    /// 检查是否为随机匹配
    pub fn is_random_match(&self) -> bool {
        matches!(self, Self::RandomMatch)
    }

    /// 检查是否为文件名序号匹配
    pub fn is_filename_sequence(&self) -> bool {
        matches!(self, Self::FilenameSequence { .. })
    }

    /// 检查是否为按顺序匹配
    pub fn is_priority_order(&self) -> bool {
        matches!(self, Self::PriorityOrder { .. })
    }

    /// 获取目标序号（如果是文件名序号匹配）
    pub fn get_target_sequence(&self) -> Option<&String> {
        match self {
            Self::FilenameSequence { target_sequence } => Some(target_sequence),
            _ => None,
        }
    }

    /// 获取分类ID列表（如果是按顺序匹配）
    pub fn get_category_ids(&self) -> Option<&Vec<String>> {
        match self {
            Self::PriorityOrder { category_ids } => Some(category_ids),
            _ => None,
        }
    }
}

/// 轨道片段
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TrackSegment {
    pub id: String,
    pub track_id: String,
    pub template_material_id: Option<String>, // 关联的模板素材ID
    pub name: String,
    pub start_time: u64, // 开始时间（微秒）
    pub end_time: u64,   // 结束时间（微秒）
    pub duration: u64,   // 片段时长（微秒）
    pub segment_index: u32, // 片段在轨道中的索引
    pub properties: Option<String>, // JSON格式的片段属性（如变换、效果等）
    pub matching_rule: SegmentMatchingRule, // 片段匹配规则
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// 模板片段权重配置
/// 用于存储每个模板片段对不同AI分类的权重配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemplateSegmentWeight {
    pub id: String,
    pub template_id: String,
    pub track_segment_id: String,
    pub ai_classification_id: String,
    pub weight: i32, // 权重值，数值越大优先级越高
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// 创建模板片段权重配置请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateTemplateSegmentWeightRequest {
    pub template_id: String,
    pub track_segment_id: String,
    pub ai_classification_id: String,
    pub weight: i32,
}

/// 更新模板片段权重配置请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateTemplateSegmentWeightRequest {
    pub weight: i32,
}

/// 批量更新模板片段权重配置请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchUpdateTemplateSegmentWeightRequest {
    pub template_id: String,
    pub track_segment_id: String,
    pub weights: Vec<SegmentWeightConfig>,
}

/// 片段权重配置项
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SegmentWeightConfig {
    pub ai_classification_id: String,
    pub weight: i32,
}

/// 模板素材类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TemplateMaterialType {
    Video,
    Audio,
    Image,
    Text,
    Effect,
    Sticker,
    Canvas,
    Other(String),
}

/// 轨道类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TrackType {
    Video,
    Audio,
    Text,
    Sticker,
    Effect,
    Other(String),
}

/// 导入状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum ImportStatus {
    Pending,     // 等待导入
    Parsing,     // 解析中
    Uploading,   // 上传中
    Processing,  // 处理中
    Completed,   // 完成
    Failed,      // 失败
}

/// 上传状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UploadStatus {
    Pending,     // 等待上传
    Uploading,   // 上传中
    Completed,   // 上传完成
    Failed,      // 上传失败
    Skipped,     // 跳过（文件不存在等）
}

/// 创建模板请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateTemplateRequest {
    pub name: String,
    pub description: Option<String>,
    pub project_id: Option<String>,
    pub source_file_path: String, // draft_content.json文件路径
}

/// 模板导入请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImportTemplateRequest {
    pub file_path: String, // draft_content.json文件路径
    pub template_name: Option<String>, // 自定义模板名称
    pub project_id: Option<String>,
    pub auto_upload: bool, // 是否自动上传素材到云端
}

/// 批量导入请求
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchImportRequest {
    pub folder_path: String, // 包含多个draft_content.json的文件夹路径
    pub project_id: Option<String>,
    pub auto_upload: bool,
    pub max_concurrent: Option<u32>, // 最大并发数
}

/// 导入进度信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImportProgress {
    pub template_id: String,
    pub template_name: String,
    pub status: ImportStatus,
    pub total_materials: u32,
    pub uploaded_materials: u32,
    pub failed_materials: u32,
    pub current_operation: String,
    pub error_message: Option<String>,
    pub progress_percentage: f64, // 0.0 - 100.0
}

impl Template {
    /// 创建新的模板实例
    pub fn new(
        name: String,
        canvas_config: CanvasConfig,
        duration: u64,
        fps: f64,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            name,
            description: None,
            canvas_config,
            duration,
            fps,
            materials: Vec::new(),
            tracks: Vec::new(),
            import_status: ImportStatus::Pending,
            source_file_path: None,
            created_at: now,
            updated_at: now,
            is_active: true,
        }
    }

    /// 添加素材
    pub fn add_material(&mut self, material: TemplateMaterial) {
        self.materials.push(material);
        self.updated_at = Utc::now();
    }

    /// 添加轨道
    pub fn add_track(&mut self, track: Track) {
        self.tracks.push(track);
        self.updated_at = Utc::now();
    }

    /// 更新导入状态
    pub fn update_import_status(&mut self, status: ImportStatus) {
        self.import_status = status;
        self.updated_at = Utc::now();
    }

    /// 获取所有需要上传的素材
    pub fn get_pending_upload_materials(&self) -> Vec<&TemplateMaterial> {
        self.materials
            .iter()
            .filter(|m| matches!(m.upload_status, UploadStatus::Pending))
            .collect()
    }

    /// 获取上传进度
    pub fn get_upload_progress(&self) -> f64 {
        if self.materials.is_empty() {
            return 100.0;
        }
        
        let completed = self.materials
            .iter()
            .filter(|m| matches!(m.upload_status, UploadStatus::Completed | UploadStatus::Skipped))
            .count();
        
        (completed as f64 / self.materials.len() as f64) * 100.0
    }
}

impl TemplateMaterial {
    /// 创建新的模板素材实例
    pub fn new(
        id: String,           // 素材的真实ID（来自剪映草稿）
        template_id: String,
        original_id: String,  // local_material_id
        name: String,
        material_type: TemplateMaterialType,
        original_path: String,
    ) -> Self {
        let now = Utc::now();
        Self {
            id,              // 使用传入的真实ID
            template_id,
            original_id,     // original_id 对应 local_material_id，可以重复
            name,
            material_type,
            original_path,
            remote_url: None,
            file_size: None,
            duration: None,
            width: None,
            height: None,
            upload_status: UploadStatus::Pending,
            file_exists: false,
            upload_success: false,
            metadata: None,
            created_at: now,
            updated_at: now,
        }
    }

    /// 更新上传状态
    pub fn update_upload_status(&mut self, status: UploadStatus, remote_url: Option<String>) {
        self.upload_status = status;
        if let Some(url) = remote_url {
            self.remote_url = Some(url);
        }
        self.updated_at = Utc::now();
    }

    /// 检查本地文件是否存在
    pub fn file_exists(&self) -> bool {
        if self.original_path.is_empty() {
            return false;
        }
        std::path::Path::new(&self.original_path).exists()
    }

    /// 更新文件存在状态
    pub fn update_file_exists(&mut self) {
        self.file_exists = self.file_exists();
        self.updated_at = Utc::now();
    }

    /// 更新上传成功状态
    pub fn update_upload_success(&mut self, success: bool) {
        self.upload_success = success;
        self.updated_at = Utc::now();
    }
}

impl Track {
    /// 创建新的轨道实例
    pub fn new(
        id: String,           // 轨道的真实ID（来自剪映草稿）
        template_id: String,
        name: String,
        track_type: TrackType,
        track_index: u32,
    ) -> Self {
        let now = Utc::now();
        Self {
            id,              // 使用传入的真实ID
            template_id,
            name,
            track_type,
            track_index,
            segments: Vec::new(),
            created_at: now,
            updated_at: now,
        }
    }

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

    /// 获取轨道总时长
    pub fn get_total_duration(&self) -> u64 {
        self.segments
            .iter()
            .map(|s| s.duration)
            .max()
            .unwrap_or(0)
    }
}

impl TrackSegment {
    /// 创建新的轨道片段实例
    pub fn new(
        id: String,           // 片段的真实ID（来自剪映草稿）
        track_id: String,
        name: String,
        start_time: u64,
        end_time: u64,
        segment_index: u32,
    ) -> Self {
        let now = Utc::now();
        Self {
            id,              // 使用传入的真实ID
            track_id,
            template_material_id: None,
            name,
            start_time,
            end_time,
            duration: end_time - start_time,
            segment_index,
            properties: None,
            matching_rule: SegmentMatchingRule::default(), // 默认为固定素材
            created_at: now,
            updated_at: now,
        }
    }

    /// 关联模板素材
    pub fn associate_material(&mut self, material_id: String) {
        self.template_material_id = Some(material_id);
    }

    /// 设置匹配规则
    pub fn set_matching_rule(&mut self, rule: SegmentMatchingRule) {
        self.matching_rule = rule;
        self.updated_at = Utc::now();
    }

    /// 获取匹配规则的显示名称
    pub fn get_matching_rule_display(&self) -> String {
        self.matching_rule.display_name()
    }
}

impl TemplateSegmentWeight {
    /// 创建新的模板片段权重配置
    pub fn new(
        template_id: String,
        track_segment_id: String,
        ai_classification_id: String,
        weight: i32,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: uuid::Uuid::new_v4().to_string(),
            template_id,
            track_segment_id,
            ai_classification_id,
            weight,
            created_at: now,
            updated_at: now,
        }
    }

    /// 更新权重值
    pub fn update_weight(&mut self, weight: i32) {
        self.weight = weight;
        self.updated_at = Utc::now();
    }

    /// 验证权重值是否有效
    pub fn validate_weight(weight: i32) -> Result<(), String> {
        if weight < 0 || weight > 100 {
            return Err("权重值必须在 0-100 之间".to_string());
        }
        Ok(())
    }
}
