"""
单个文件场景检测工作流节点
"""

import os
import json
import hashlib
from pathlib import Path
from typing import Dict, Any
from datetime import datetime

from python_core.utils.logger import logger
from python_core.utils.jsonrpc_enhanced import ProgressLevel

from ..services.detector_service import SceneDetectorService
from ..services.ai_analysis_service import AIAnalysisService
from ..utils.result_saver import ResultSaver
from ..types.single_workflow_state import SingleSceneDetectionWorkflowState, SingleVideoTask
from python_core.services.ffmpeg_slice_service_sync import FfmpegSliceService, SliceOptions, SliceSegment
from python_core.services.project_material_service import ProjectMaterialService


class SingleWorkflowNodes:
    """单个文件场景检测工作流节点"""
    
    def __init__(self):
        self.detector_service = SceneDetectorService()
        self.ai_service = AIAnalysisService()
        self.result_saver = ResultSaver()
        self.splitter_service = FfmpegSliceService()
        self.material_service = ProjectMaterialService()
    
    def process_single_video(self, state: SingleSceneDetectionWorkflowState) -> Dict[str, Any]:
        """处理单个视频文件"""
        try:
            state.mark_task_started()
            state.update_progress("started", 0.0, f"开始处理视频: {state.video_path.name}")
            
            logger.info(f"🎬 开始处理单个视频: {state.video_path.name}")
            
            # 1. 场景检测
            state.update_progress("detecting", 20.0, "正在进行场景检测...")

            # 转换检测器类型
            from ..types.enums import DetectorType
            detector_type_enum = DetectorType(state.detector_type)

            detection_result = self.detector_service.detect_scenes(
                video_path=state.video_path,
                detector_type=detector_type_enum,
                threshold=state.threshold,
                min_scene_length=state.min_scene_length
            )
            
            logger.info(f"✅ 场景检测完成: 检测到 {detection_result.total_scenes} 个场景")
            
            # 2. 保存检测结果
            if state.output_dir:
                state.update_progress("saving", 40.0, "保存检测结果...")

                # 转换输出格式
                from ..types.enums import OutputFormat
                output_format_enum = OutputFormat(state.output_format)

                # 创建结果文件路径
                result_filename = f"{state.video_path.stem}_scenes.{output_format_enum.value}"
                result_path = state.output_dir / result_filename

                self.result_saver.save_results(
                    detection_result,
                    result_path,
                    output_format_enum
                )
            
            # 3. AI分析（如果启用）
            if state.enable_ai_analysis:
                state.update_progress("ai_analysis", 60.0, "正在进行AI分析...")
                try:
                    ai_result = self.ai_service.analyze_scenes(detection_result)
                    detection_result.ai_analysis = ai_result
                    logger.info("✅ AI分析完成")
                except Exception as e:
                    logger.warning(f"⚠️ AI分析失败: {e}")
            
            # 4. 视频切分（如果启用）
            split_results = []
            if state.enable_video_splitting and state.output_dir:
                state.update_progress("splitting", 70.0, "正在进行视频切分...")
                split_results = self._handle_video_splitting(state, detection_result)
            
            # 5. 项目素材管理（如果是项目导入）
            if state.project_id and state.project_directory:
                state.update_progress("project_import", 90.0, "导入到项目素材库...")
                self._handle_project_material_import(state, detection_result, split_results)
            
            # 标记完成
            state.mark_task_completed(detection_result, split_results)
            state.update_progress("completed", 100.0, "处理完成")
            
            logger.info(f"🎉 视频处理完成: {state.video_path.name}")
            
            return {
                "success": True,
                "detection_result": detection_result,
                "split_results": split_results,
                "processing_time": state.processing_time,
                "total_scenes": state.total_scenes,
                "total_segments": state.total_split_segments
            }
            
        except Exception as e:
            error_msg = f"处理视频失败: {str(e)}"
            logger.error(f"❌ {error_msg}")
            state.mark_task_failed(error_msg)
            state.update_progress("failed", 0.0, error_msg)
            
            return {
                "success": False,
                "error": error_msg,
                "processing_time": state.processing_time
            }
    
    def _handle_video_splitting(self, state: SingleSceneDetectionWorkflowState, detection_result) -> list:
        """处理视频切分"""
        try:
            # 创建切分选项
            slice_options = SliceOptions(
                crf=state.split_quality,
                preset=state.split_preset
            )
            
            # 转换场景为SliceSegment
            segments = [
                SliceSegment(start=scene.start_time, end=scene.end_time)
                for scene in detection_result.scenes
            ]
            
            # 创建输出目录
            scenes_dir = state.output_dir / "scenes"
            scenes_dir.mkdir(parents=True, exist_ok=True)
            
            # 检查是否无场景，如果是则跳过切分
            if len(segments) <= 0:
                logger.info(f"🔄 检测到 0 个场景切换，跳过切分，直接使用源文件")
                
                # 直接复制源文件作为结果
                import shutil
                source_file = state.video_path
                target_file = scenes_dir / f"{state.video_path.stem}_scene_001.mp4"
                
                try:
                    shutil.copy2(source_file, target_file)
                    logger.info(f"✅ 源文件已复制到: {target_file}")
                    
                    # 获取源文件元数据
                    metadata = self.splitter_service.get_video_metadata(str(source_file))
                    
                    # 创建模拟的切分结果
                    slice_results = [(str(target_file), metadata)]
                    
                    # 修正场景统计：无场景切换 = 1个场景（整个视频）
                    detection_result.total_scenes = 1
                    
                except Exception as e:
                    logger.error(f"❌ 复制源文件失败: {e}")
                    slice_results = []
            else:
                logger.info(f"🎬 检测到 {len(segments)} 个场景，开始切分")
                
                # 生成输出路径
                base_output_path = str(scenes_dir / f"{state.video_path.stem}_scene")
                
                # 使用同步方法进行切分
                slice_results = self.splitter_service.slice_video(
                    media_path=str(state.video_path),
                    segments=segments,
                    options=slice_options,
                    output_path=base_output_path
                )
            
            # 转换为兼容格式
            split_results_raw = []
            
            # 创建一个简单的结果对象
            class SplitResult:
                def __init__(self, scene_index, output_path, start_time, end_time, duration, file_size, success, error=None):
                    self.scene_index = scene_index
                    self.output_path = Path(output_path)
                    self.start_time = start_time
                    self.end_time = end_time
                    self.duration = duration
                    self.file_size = file_size
                    self.success = success
                    self.error = error
            
            for i, (output_path, metadata) in enumerate(slice_results):
                if len(detection_result.scenes) == 0:
                    # 无场景切换的情况：整个视频作为一个场景
                    split_result = SplitResult(
                        scene_index=0,
                        output_path=output_path,
                        start_time=0.0,
                        end_time=metadata.duration,
                        duration=metadata.duration,
                        file_size=metadata.size,
                        success=Path(output_path).exists(),
                        error=None if Path(output_path).exists() else "文件不存在"
                    )
                    split_results_raw.append(split_result)
                else:
                    # 有场景切换的情况
                    scene = detection_result.scenes[i] if i < len(detection_result.scenes) else None
                    if scene:
                        split_result = SplitResult(
                            scene_index=i,
                            output_path=output_path,
                            start_time=scene.start_time,
                            end_time=scene.end_time,
                            duration=scene.duration,
                            file_size=metadata.size,
                            success=Path(output_path).exists(),
                            error=None if Path(output_path).exists() else "文件不存在"
                        )
                        split_results_raw.append(split_result)
            
            # 4. 添加视频时长检查，如果时长大于最大视频时长那么就要进行二次切分
            final_split_results = []
            
            for split_result in split_results_raw:
                try:
                    # 检查切分后的视频时长
                    video_path = str(split_result.output_path)
                    
                    if split_result.duration > state.max_video_duration:
                        logger.info(f"⚠️ 片段 {split_result.scene_index + 1} 时长 {split_result.duration:.2f}s 超过限制 {state.max_video_duration:.2f}s，进行二次切分")
                        
                        # 进行二次切分
                        secondary_results = self.splitter_service.check_and_split_by_duration(
                            video_path=video_path,
                            max_duration=state.max_video_duration,
                            options=slice_options,
                            output_dir=str(split_result.output_path.parent)
                        )
                        
                        # 处理二次切分结果
                        for i, (secondary_path, secondary_metadata) in enumerate(secondary_results):
                            if len(secondary_results) > 1:
                                # 如果进行了二次切分，创建新的结果对象
                                secondary_split_result = SplitResult(
                                    scene_index=split_result.scene_index,
                                    output_path=secondary_path,
                                    start_time=split_result.start_time + (i * state.max_video_duration),
                                    end_time=min(split_result.start_time + ((i + 1) * state.max_video_duration), split_result.end_time),
                                    duration=secondary_metadata.duration,
                                    file_size=secondary_metadata.size,
                                    success=Path(secondary_path).exists(),
                                    error=None if Path(secondary_path).exists() else "二次切分文件不存在"
                                )
                                final_split_results.append(secondary_split_result)
                                
                                # 删除原始的过长片段（如果二次切分成功）
                                if Path(video_path).exists() and len(secondary_results) > 1:
                                    try:
                                        Path(video_path).unlink()
                                        logger.info(f"🗑️ 已删除过长的原始片段: {Path(video_path).name}")
                                    except Exception as e:
                                        logger.warning(f"⚠️ 删除原始片段失败: {e}")
                            else:
                                # 如果没有进行二次切分（时长检查通过），保持原结果
                                final_split_results.append(split_result)
                    else:
                        # 时长未超过限制，直接添加到最终结果
                        final_split_results.append(split_result)
                        
                except Exception as e:
                    logger.error(f"❌ 处理片段 {split_result.scene_index + 1} 的时长检查时出错: {e}")
                    # 出错时保持原结果
                    final_split_results.append(split_result)
            
            # 使用最终的切分结果
            split_results_raw = final_split_results
            
            # 更新统计信息
            logger.info(f"📊 最终生成 {len(split_results_raw)} 个视频片段（包含二次切分）")
            
            return split_results_raw
            
        except Exception as e:
            logger.error(f"❌ 视频切分失败: {e}")
            return []

    def _handle_project_material_import(self, state: SingleSceneDetectionWorkflowState, detection_result, split_results):
        """处理项目素材导入"""
        try:
            if not state.project_directory:
                logger.warning("⚠️ 项目目录未设置，跳过素材导入")
                return

            # 使用项目素材管理服务
            result = self.material_service.import_video_materials(
                video_segments=split_results,
                project_id=state.project_id,
                project_directory=state.project_directory,
                source_video_path=str(state.video_path),
                material_tags=state.material_tags
            )

            if result["success"]:
                logger.info(f"📝 项目素材导入完成: 新增 {result['imported_count']} 个素材，跳过 {result['skipped_count']} 个重复素材")
            else:
                logger.error(f"❌ 项目素材导入失败: {result.get('error', '未知错误')}")

        except Exception as e:
            logger.error(f"❌ 项目素材导入失败: {e}")

