use crate::data::models::material_segment_view::*;
use crate::data::models::material::{Material, MaterialSegment};
use crate::data::models::video_classification::VideoClassificationRecord;
use crate::data::models::model::Model;
use crate::data::repositories::material_repository::MaterialRepository;
use crate::data::repositories::video_classification_repository::VideoClassificationRepository;
use crate::data::repositories::model_repository::ModelRepository;
use anyhow::Result;
use std::sync::Arc;
use std::collections::HashMap;

/// MaterialSegment聚合视图业务服务
/// 遵循 Tauri 开发规范的业务逻辑层设计原则
pub struct MaterialSegmentViewService {
    material_repository: Arc<MaterialRepository>,
    video_classification_repository: Arc<VideoClassificationRepository>,
    model_repository: Arc<ModelRepository>,
}

impl MaterialSegmentViewService {
    /// 创建新的MaterialSegment聚合视图服务实例
    pub fn new(
        material_repository: Arc<MaterialRepository>,
        video_classification_repository: Arc<VideoClassificationRepository>,
        model_repository: Arc<ModelRepository>,
    ) -> Self {
        Self {
            material_repository,
            video_classification_repository,
            model_repository,
        }
    }

    /// 获取项目的MaterialSegment聚合视图
    pub async fn get_project_segment_view(&self, project_id: &str) -> Result<MaterialSegmentView> {
        println!("🔍 开始获取项目片段视图，project_id: {}", project_id);

        // 获取项目的所有素材
        let materials = self.material_repository.get_by_project_id(project_id)?;
        println!("📁 获取到 {} 个素材", materials.len());

        // 为每个素材加载片段信息
        let mut materials_with_segments = Vec::new();
        for mut material in materials {
            let segments = self.material_repository.get_segments(&material.id)?;
            material.segments = segments;
            materials_with_segments.push(material);
        }

        // 获取所有模特信息
        let models = self.get_project_models(&materials_with_segments).await?;
        println!("👤 获取到 {} 个模特", models.len());

        // 构建MaterialSegment聚合视图
        let mut view = MaterialSegmentView::new(project_id.to_string());

        // 收集所有片段和相关信息
        let segments_with_details = self.collect_segments_with_details(&materials_with_segments, &models).await?;
        println!("🎬 收集到 {} 个片段详情", segments_with_details.len());

        // 按AI分类聚合
        view.by_classification = self.group_by_classification(&segments_with_details);
        println!("🏷️ 按分类聚合：{} 个分类组", view.by_classification.len());

        // 按模特聚合
        view.by_model = self.group_by_model(&segments_with_details);
        println!("👥 按模特聚合：{} 个模特组", view.by_model.len());

        // 计算统计信息
        view.stats = self.calculate_stats(&segments_with_details);
        println!("📊 统计信息：总片段数 {}", view.stats.total_segments);

        Ok(view)
    }

    /// 根据查询条件获取MaterialSegment聚合视图
    pub async fn get_project_segment_view_with_query(
        &self, 
        query: &MaterialSegmentQuery
    ) -> Result<MaterialSegmentView> {
        // 获取基础视图
        let mut view = self.get_project_segment_view(&query.project_id).await?;
        
        // 应用过滤条件
        if let Some(category) = &query.category_filter {
            view.by_classification.retain(|group| group.category == *category);
        }
        
        if let Some(model_id) = &query.model_id_filter {
            view.by_model.retain(|group| group.model_id == *model_id);
        }
        
        // 应用时长过滤
        if query.min_duration.is_some() || query.max_duration.is_some() {
            self.apply_duration_filter(&mut view, query.min_duration, query.max_duration);
        }
        
        // 应用搜索过滤
        if let Some(search_term) = &query.search_term {
            self.apply_search_filter(&mut view, search_term);
        }
        
        // 应用排序
        if let Some(sort_by) = &query.sort_by {
            self.apply_sorting(&mut view, sort_by, &query.sort_direction);
        }
        
        // 应用分页
        if let Some(page_size) = query.page_size {
            self.apply_pagination(&mut view, page_size, query.page.unwrap_or(0));
        }
        
        Ok(view)
    }

    /// 收集所有片段及其详细信息
    async fn collect_segments_with_details(
        &self,
        materials: &[Material],
        models: &HashMap<String, Model>,
    ) -> Result<Vec<SegmentWithDetails>> {
        let mut segments_with_details = Vec::new();
        
        for material in materials {
            // 获取该素材的分类记录
            let classification_records = self.video_classification_repository
                .get_by_material_id(&material.id)
                .await?;
            
            // 为每个片段创建详细信息
            for segment in &material.segments {
                let classification_info = self.get_classification_info(segment, &classification_records);
                let model_info = self.get_model_info(material, models);
                
                let segment_with_details = SegmentWithDetails {
                    segment: segment.clone(),
                    material_name: material.name.clone(),
                    material_type: format!("{:?}", material.material_type),
                    classification: classification_info,
                    model: model_info,
                };
                
                segments_with_details.push(segment_with_details);
            }
        }
        
        Ok(segments_with_details)
    }

    /// 获取项目相关的所有模特
    async fn get_project_models(&self, materials: &[Material]) -> Result<HashMap<String, Model>> {
        let mut models = HashMap::new();
        
        for material in materials {
            if let Some(model_id) = &material.model_id {
                if !models.contains_key(model_id) {
                    if let Ok(Some(model)) = self.model_repository.get_by_id(model_id) {
                        models.insert(model_id.clone(), model);
                    }
                }
            }
        }
        
        Ok(models)
    }

    /// 获取片段的分类信息
    fn get_classification_info(
        &self,
        segment: &MaterialSegment,
        classification_records: &[VideoClassificationRecord],
    ) -> Option<ClassificationInfo> {
        classification_records
            .iter()
            .find(|record| record.segment_id == segment.id)
            .map(|record| ClassificationInfo {
                category: record.category.clone(),
                confidence: record.confidence,
                reasoning: record.reasoning.clone(),
                features: record.features.clone(),
                product_match: record.product_match,
                quality_score: record.quality_score,
            })
    }

    /// 获取素材的模特信息
    fn get_model_info(
        &self,
        material: &Material,
        models: &HashMap<String, Model>,
    ) -> Option<ModelInfo> {
        material.model_id.as_ref().and_then(|model_id| {
            models.get(model_id).map(|model| ModelInfo {
                id: model.id.clone(),
                name: model.name.clone(),
                model_type: format!("{:?}", model.gender),
            })
        })
    }

    /// 按AI分类聚合片段
    fn group_by_classification(&self, segments: &[SegmentWithDetails]) -> Vec<ClassificationGroup> {
        let mut groups: HashMap<String, Vec<&SegmentWithDetails>> = HashMap::new();
        
        for segment in segments {
            let category = segment.classification
                .as_ref()
                .map(|c| c.category.clone())
                .unwrap_or_else(|| "未分类".to_string());
            
            groups.entry(category).or_default().push(segment);
        }
        
        groups.into_iter().map(|(category, segments)| {
            let total_duration: f64 = segments.iter()
                .map(|s| s.segment.duration)
                .sum();
            
            ClassificationGroup {
                category,
                segment_count: segments.len(),
                total_duration,
                segments: segments.into_iter().cloned().collect(),
            }
        }).collect()
    }

    /// 按模特聚合片段
    fn group_by_model(&self, segments: &[SegmentWithDetails]) -> Vec<ModelGroup> {
        let mut groups: HashMap<String, Vec<&SegmentWithDetails>> = HashMap::new();

        for segment in segments {
            let model_id = segment.model
                .as_ref()
                .map(|m| m.id.clone())
                .unwrap_or_else(|| "unassigned".to_string());

            groups.entry(model_id).or_default().push(segment);
        }
        
        groups.into_iter().map(|(model_id, segments)| {
            let model_name = segments.first()
                .and_then(|s| s.model.as_ref())
                .map(|m| m.name.clone())
                .unwrap_or_else(|| "未关联模特".to_string());
            
            let total_duration: f64 = segments.iter()
                .map(|s| s.segment.duration)
                .sum();
            
            ModelGroup {
                model_id,
                model_name,
                segment_count: segments.len(),
                total_duration,
                segments: segments.into_iter().cloned().collect(),
            }
        }).collect()
    }

    /// 计算统计信息
    fn calculate_stats(&self, segments: &[SegmentWithDetails]) -> MaterialSegmentStats {
        let total_segments = segments.len();
        let classified_segments = segments.iter()
            .filter(|s| s.classification.is_some())
            .count();
        let unclassified_segments = total_segments - classified_segments;
        
        let classification_coverage = if total_segments > 0 {
            classified_segments as f64 / total_segments as f64
        } else {
            0.0
        };
        
        let mut classification_counts = HashMap::new();
        let mut model_counts = HashMap::new();
        let total_duration: f64 = segments.iter().map(|s| s.segment.duration).sum();
        
        for segment in segments {
            if let Some(classification) = &segment.classification {
                *classification_counts.entry(classification.category.clone()).or_insert(0) += 1;
            }
            
            if let Some(model) = &segment.model {
                *model_counts.entry(model.name.clone()).or_insert(0) += 1;
            } else {
                *model_counts.entry("未关联模特".to_string()).or_insert(0) += 1;
            }
        }
        
        MaterialSegmentStats {
            total_segments,
            classified_segments,
            unclassified_segments,
            classification_coverage,
            classification_counts,
            model_counts,
            total_duration,
        }
    }

    /// 应用时长过滤
    fn apply_duration_filter(
        &self,
        view: &mut MaterialSegmentView,
        min_duration: Option<f64>,
        max_duration: Option<f64>,
    ) {
        // 过滤分类视图
        for group in &mut view.by_classification {
            group.segments.retain(|segment| {
                let duration = segment.segment.duration;
                let min_ok = min_duration.map_or(true, |min| duration >= min);
                let max_ok = max_duration.map_or(true, |max| duration <= max);
                min_ok && max_ok
            });

            // 更新统计信息
            group.segment_count = group.segments.len();
            group.total_duration = group.segments.iter().map(|s| s.segment.duration).sum();
        }

        // 过滤模特视图
        for group in &mut view.by_model {
            group.segments.retain(|segment| {
                let duration = segment.segment.duration;
                let min_ok = min_duration.map_or(true, |min| duration >= min);
                let max_ok = max_duration.map_or(true, |max| duration <= max);
                min_ok && max_ok
            });

            // 更新统计信息
            group.segment_count = group.segments.len();
            group.total_duration = group.segments.iter().map(|s| s.segment.duration).sum();
        }

        // 移除空分组
        view.by_classification.retain(|group| group.segment_count > 0);
        view.by_model.retain(|group| group.segment_count > 0);

        // 更新全局统计信息
        let all_segments: Vec<SegmentWithDetails> = view.by_classification.iter()
            .flat_map(|g| g.segments.clone())
            .collect();
        view.stats = self.calculate_stats(&all_segments);
    }

    /// 应用搜索过滤
    fn apply_search_filter(&self, view: &mut MaterialSegmentView, search_term: &str) {
        let search_term = search_term.to_lowercase();

        // 过滤分类视图
        for group in &mut view.by_classification {
            group.segments.retain(|segment| {
                // 搜索素材名称
                let name_match = segment.material_name.to_lowercase().contains(&search_term);

                // 搜索分类信息
                let category_match = segment.classification.as_ref()
                    .map(|c| c.category.to_lowercase().contains(&search_term))
                    .unwrap_or(false);

                // 搜索模特信息
                let model_match = segment.model.as_ref()
                    .map(|m| m.name.to_lowercase().contains(&search_term))
                    .unwrap_or(false);

                name_match || category_match || model_match
            });

            // 更新统计信息
            group.segment_count = group.segments.len();
            group.total_duration = group.segments.iter().map(|s| s.segment.duration).sum();
        }

        // 过滤模特视图
        for group in &mut view.by_model {
            group.segments.retain(|segment| {
                // 搜索素材名称
                let name_match = segment.material_name.to_lowercase().contains(&search_term);

                // 搜索分类信息
                let category_match = segment.classification.as_ref()
                    .map(|c| c.category.to_lowercase().contains(&search_term))
                    .unwrap_or(false);

                name_match || category_match
            });

            // 更新统计信息
            group.segment_count = group.segments.len();
            group.total_duration = group.segments.iter().map(|s| s.segment.duration).sum();
        }

        // 移除空分组
        view.by_classification.retain(|group| group.segment_count > 0);
        view.by_model.retain(|group| group.segment_count > 0);

        // 更新全局统计信息
        let all_segments: Vec<SegmentWithDetails> = view.by_classification.iter()
            .flat_map(|g| g.segments.clone())
            .collect();
        view.stats = self.calculate_stats(&all_segments);
    }

    /// 应用排序
    fn apply_sorting(
        &self,
        view: &mut MaterialSegmentView,
        sort_by: &SegmentSortField,
        sort_direction: &Option<SortDirection>,
    ) {
        let direction = sort_direction.clone().unwrap_or(SortDirection::Ascending);

        // 对分类内的片段排序
        for group in &mut view.by_classification {
            self.sort_segments(&mut group.segments, sort_by, &direction);
        }

        // 对模特内的片段排序
        for group in &mut view.by_model {
            self.sort_segments(&mut group.segments, sort_by, &direction);
        }

        // 对分组本身排序
        match sort_by {
            SegmentSortField::Category => {
                view.by_classification.sort_by(|a, b| {
                    match direction {
                        SortDirection::Ascending => a.category.cmp(&b.category),
                        SortDirection::Descending => b.category.cmp(&a.category),
                    }
                });
            },
            SegmentSortField::Model => {
                view.by_model.sort_by(|a, b| {
                    match direction {
                        SortDirection::Ascending => a.model_name.cmp(&b.model_name),
                        SortDirection::Descending => b.model_name.cmp(&a.model_name),
                    }
                });
            },
            _ => {}
        }
    }

    /// 对片段列表排序
    fn sort_segments(
        &self,
        segments: &mut Vec<SegmentWithDetails>,
        sort_by: &SegmentSortField,
        direction: &SortDirection,
    ) {
        match sort_by {
            SegmentSortField::CreatedAt => {
                segments.sort_by(|a, b| {
                    let a_time = a.segment.created_at;
                    let b_time = b.segment.created_at;
                    match direction {
                        SortDirection::Ascending => a_time.cmp(&b_time),
                        SortDirection::Descending => b_time.cmp(&a_time),
                    }
                });
            },
            SegmentSortField::Duration => {
                segments.sort_by(|a, b| {
                    let a_duration = a.segment.duration;
                    let b_duration = b.segment.duration;
                    match direction {
                        SortDirection::Ascending => a_duration.partial_cmp(&b_duration).unwrap_or(std::cmp::Ordering::Equal),
                        SortDirection::Descending => b_duration.partial_cmp(&a_duration).unwrap_or(std::cmp::Ordering::Equal),
                    }
                });
            },
            SegmentSortField::Category => {
                segments.sort_by(|a, b| {
                    let a_category = a.classification.as_ref().map(|c| c.category.as_str()).unwrap_or("");
                    let b_category = b.classification.as_ref().map(|c| c.category.as_str()).unwrap_or("");
                    match direction {
                        SortDirection::Ascending => a_category.cmp(&b_category),
                        SortDirection::Descending => b_category.cmp(&a_category),
                    }
                });
            },
            SegmentSortField::Model => {
                segments.sort_by(|a, b| {
                    let a_model = a.model.as_ref().map(|m| m.name.as_str()).unwrap_or("");
                    let b_model = b.model.as_ref().map(|m| m.name.as_str()).unwrap_or("");
                    match direction {
                        SortDirection::Ascending => a_model.cmp(&b_model),
                        SortDirection::Descending => b_model.cmp(&a_model),
                    }
                });
            },
            SegmentSortField::Confidence => {
                segments.sort_by(|a, b| {
                    let a_confidence = a.classification.as_ref().map(|c| c.confidence).unwrap_or(0.0);
                    let b_confidence = b.classification.as_ref().map(|c| c.confidence).unwrap_or(0.0);
                    match direction {
                        SortDirection::Ascending => a_confidence.partial_cmp(&b_confidence).unwrap_or(std::cmp::Ordering::Equal),
                        SortDirection::Descending => b_confidence.partial_cmp(&a_confidence).unwrap_or(std::cmp::Ordering::Equal),
                    }
                });
            },
        }
    }

    /// 应用分页
    fn apply_pagination(&self, view: &mut MaterialSegmentView, page_size: usize, page: usize) {
        // 对分类视图应用分页
        for group in &mut view.by_classification {
            let start = page * page_size;
            let end = (page + 1) * page_size;

            if start < group.segments.len() {
                let end = end.min(group.segments.len());
                group.segments = group.segments[start..end].to_vec();
                group.segment_count = group.segments.len();
                group.total_duration = group.segments.iter().map(|s| s.segment.duration).sum();
            } else {
                group.segments.clear();
                group.segment_count = 0;
                group.total_duration = 0.0;
            }
        }

        // 对模特视图应用分页
        for group in &mut view.by_model {
            let start = page * page_size;
            let end = (page + 1) * page_size;

            if start < group.segments.len() {
                let end = end.min(group.segments.len());
                group.segments = group.segments[start..end].to_vec();
                group.segment_count = group.segments.len();
                group.total_duration = group.segments.iter().map(|s| s.segment.duration).sum();
            } else {
                group.segments.clear();
                group.segment_count = 0;
                group.total_duration = 0.0;
            }
        }
    }
}
