/**
 * 视频处理 Hook
 * 统一的视频上传、分析和处理
 */

import { useState, useCallback, useRef, useEffect } from 'react';
import type { VideoInfo, VideoAnalysis, Scene, Keyframe } from '@/core/types';
import { delay, formatDuration } from '@/shared';
import type { TaskStatusInfo } from '@/core/services/ai/types';

export interface UseVideoReturn {
  // 视频信息
  video: VideoInfo | null;
  analysis: VideoAnalysis | null;
  
  // 上传状态
  isUploading: boolean;
  uploadProgress: number;
  
  // 分析状态
  isAnalyzing: boolean;
  analysisProgress: number;
  
  // 任务状态
  taskStatus: TaskStatusInfo | null;
  
  // 操作方法
  uploadVideo: (file: File) => Promise<VideoInfo | null>;
  analyzeVideo: (videoId: string) => Promise<VideoAnalysis | null>;
  cancelAnalysis: () => void;
  extractThumbnail: (timestamp: number) => Promise<string | null>;
  extractKeyframes: (interval?: number) => Promise<string[]>;
  
  // 状态
  error: string | null;
  isLoading: boolean;
}

// 支持的格式
const SUPPORTED_FORMATS = ['mp4', 'mov', 'avi', 'mkv', 'webm', 'flv', 'wmv'];
const MAX_FILE_SIZE = 2 * 1024 * 1024 * 1024; // 2GB
const UPLOAD_PROGRESS_INTERVAL_MS = 200;
const UPLOAD_MAX_PROGRESS_BEFORE_COMPLETE = 90;
const UPLOAD_PROGRESS_STEP = 10;
const DEFAULT_FPS = 30;

// 模拟数据生成常量
const SCENE_DURATION_SECONDS = 30;
const KEYFRAME_INTERVAL_SECONDS = 5;
const DEFAULT_SCENE_SCORE = 0.8;
const ANALYSIS_STEPS: ReadonlyArray<{ progress: number; message: string; delay: number }> = [
  { progress: 10, message: '提取关键帧...', delay: 1000 },
  { progress: 30, message: '场景检测...', delay: 2000 },
  { progress: 50, message: '对象识别...', delay: 2000 },
  { progress: 70, message: '情感分析...', delay: 1500 },
  { progress: 90, message: '生成摘要...', delay: 1000 },
];

// 获取视频信息
const getVideoInfo = (file: File): Promise<VideoInfo> => {
  return new Promise((resolve, reject) => {
    const video = document.createElement('video');
    const url = URL.createObjectURL(file);
    
    video.onloadedmetadata = () => {
      URL.revokeObjectURL(url);
      
      const info: VideoInfo = {
        id: crypto.randomUUID(),
        path: url,
        name: file.name,
        duration: video.duration,
        width: video.videoWidth,
        height: video.videoHeight,
        fps: DEFAULT_FPS, // 默认
        format: file.name.split('.').pop()?.toLowerCase() || 'mp4',
        size: file.size,
        createdAt: new Date().toISOString()
      };
      
      resolve(info);
    };
    
    video.onerror = () => {
      URL.revokeObjectURL(url);
      reject(new Error('无法读取视频文件'));
    };
    
    video.src = url;
  });
};

// 生成缩略图
const generateThumbnail = (videoUrl: string, timestamp: number = 0): Promise<string> => {
  return new Promise((resolve, reject) => {
    const video = document.createElement('video');
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    
    video.crossOrigin = 'anonymous';
    
    video.onloadeddata = () => {
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      
      video.currentTime = timestamp;
    };
    
    video.onseeked = () => {
      if (ctx) {
        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
        const thumbnail = canvas.toDataURL('image/jpeg', 0.8);
        resolve(thumbnail);
      } else {
        reject(new Error('无法创建画布上下文'));
      }
    };
    
    video.onerror = () => {
      reject(new Error('无法加载视频'));
    };
    
    video.src = videoUrl;
  });
};

export function useVideo(): UseVideoReturn {
  const [video, setVideo] = useState<VideoInfo | null>(null);
  const [analysis, setAnalysis] = useState<VideoAnalysis | null>(null);
  const [isUploading, setIsUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [isAnalyzing, setIsAnalyzing] = useState(false);
  const [analysisProgress, setAnalysisProgress] = useState(0);
  const [taskStatus, setTaskStatus] = useState<TaskStatusInfo | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [isLoading, _setIsLoading] = useState(false);
  
  const abortControllerRef = useRef<AbortController | null>(null);

  // 组件卸载时清理 AbortController
  useEffect(() => {
    const controller = abortControllerRef.current;
    return () => {
      if (controller) {
        controller.abort();
      }
    };
  }, []);

  // 上传视频
  const uploadVideo = useCallback(async (file: File): Promise<VideoInfo | null> => {
    setError(null);
    setIsUploading(true);
    setUploadProgress(0);
    
    try {
      // 验证文件类型
      const ext = file.name.split('.').pop()?.toLowerCase();
      if (!ext || !SUPPORTED_FORMATS.includes(ext)) {
        throw new Error(`不支持的格式: ${ext}。请使用: ${SUPPORTED_FORMATS.join(', ')}`);
      }
      
      // 验证文件大小
      if (file.size > MAX_FILE_SIZE) {
        throw new Error(`文件过大: ${(file.size / 1024 / 1024).toFixed(0)}MB。最大支持 2GB`);
      }
      
      // 模拟上传进度
      const progressInterval = setInterval(() => {
        setUploadProgress(prev => {
          if (prev >= UPLOAD_MAX_PROGRESS_BEFORE_COMPLETE) {
            clearInterval(progressInterval);
            return UPLOAD_MAX_PROGRESS_BEFORE_COMPLETE;
          }
          return prev + UPLOAD_PROGRESS_STEP;
        });
      }, UPLOAD_PROGRESS_INTERVAL_MS);
      
      // 获取视频信息
      const info = await getVideoInfo(file);
      
      // 生成缩略图
      const thumbnail = await generateThumbnail(info.path);
      info.thumbnail = thumbnail;
      
      clearInterval(progressInterval);
      setUploadProgress(100);
      setVideo(info);
      
      return info;
    } catch (_err) {
      setError(_err instanceof Error ? _err.message : '上传失败');
      return null;
    } finally {
      setIsUploading(false);
    }
  }, []);
  
  // 分析视频
  const analyzeVideo = useCallback(async (videoId: string): Promise<VideoAnalysis | null> => {
    if (!video) return null;
    
    setError(null);
    setIsAnalyzing(true);
    setAnalysisProgress(0);
    
    // 创建任务状态
    const task: TaskStatusInfo = {
      id: crypto.randomUUID(),
      type: 'analysis',
      status: 'running',
      progress: 0,
      message: '开始分析视频...',
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString()
    };
    setTaskStatus(task);
    
    try {
      // 模拟分析过程
      for (const step of ANALYSIS_STEPS) {
        await delay(step.delay);
        setAnalysisProgress(step.progress);
        setTaskStatus((prev) => prev ? {
          ...prev,
          progress: step.progress,
          message: step.message,
          updatedAt: new Date().toISOString()
        } : null);
      }
      
      // 生成模拟分析结果
      const analysisResult: VideoAnalysis = {
        id: crypto.randomUUID(),
        videoId,
        scenes: generateMockScenes(video.duration),
        keyframes: generateMockKeyframes(video.duration),
        objects: [],
        emotions: [],
        summary: `视频时长 ${formatDuration(video.duration)}，分辨率 ${video.width}x${video.height}，包含 ${Math.floor(video.duration / 30)} 个场景。`,
        createdAt: new Date().toISOString()
      };
      
      setAnalysisProgress(100);
      setAnalysis(analysisResult);
      setTaskStatus(prev => prev ? {
        ...prev,
        status: 'completed',
        progress: 100,
        message: '分析完成',
        completedAt: new Date().toISOString()
      } : null);
      
      return analysisResult;
    } catch (_err) {
      setError(_err instanceof Error ? _err.message : '分析失败');
      setTaskStatus(prev => prev ? {
        ...prev,
        status: 'failed',
        error: _err instanceof Error ? _err.message : '分析失败'
      } : null);
      return null;
    } finally {
      setIsAnalyzing(false);
    }
  }, [video]);
  
  // 取消分析
  const cancelAnalysis = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    setIsAnalyzing(false);
    setTaskStatus(prev => prev ? {
      ...prev,
      status: 'cancelled',
      message: '已取消'
    } : null);
  }, []);
  
  // 提取缩略图
  const extractThumbnail = useCallback(async (timestamp: number): Promise<string | null> => {
    if (!video) return null;
    
    try {
      return await generateThumbnail(video.path, timestamp);
    } catch (_err) {
      setError('提取缩略图失败');
      return null;
    }
  }, [video]);
  
  // 提取关键帧
  const extractKeyframes = useCallback(async (interval: number = 5): Promise<string[]> => {
    if (!video) return [];

    const count = Math.floor(video.duration / interval);

    // 并发提取所有关键帧（分批控制，每批最多 5 个）
    const BATCH_SIZE = 5;
    const thumbnails: string[] = [];
    for (let i = 0; i < count; i += BATCH_SIZE) {
      const batch = Array.from({ length: Math.min(BATCH_SIZE, count - i) }, async (_, j) => {
        const timestamp = (i + j) * interval;
        return extractThumbnail(timestamp);
      });
      const results = await Promise.all(batch);
      thumbnails.push(...results.filter((t): t is string => t !== null));
    }
    return thumbnails;
  }, [video, extractThumbnail]);
  
  return {
    video,
    analysis,
    isUploading,
    uploadProgress,
    isAnalyzing,
    analysisProgress,
    taskStatus,
    uploadVideo,
    analyzeVideo,
    cancelAnalysis,
    extractThumbnail,
    extractKeyframes,
    error,
    isLoading
  };
}

// 辅助函数
function generateMockScenes(duration: number): Scene[] {
  const scenes: Scene[] = [];
  const sceneCount = Math.floor(duration / SCENE_DURATION_SECONDS);

  for (let i = 0; i < sceneCount; i++) {
    scenes.push({
      id: crypto.randomUUID(),
      startTime: i * SCENE_DURATION_SECONDS,
      endTime: Math.min((i + 1) * SCENE_DURATION_SECONDS, duration),
      type: 'action',
      score: DEFAULT_SCENE_SCORE,
      thumbnail: '',
      description: `场景 ${i + 1}`,
      tags: ['场景', `片段${i + 1}`]
    });
  }

  return scenes;
}

function generateMockKeyframes(duration: number): Keyframe[] {
  if (duration <= 0) return [];
  const count = Math.floor(duration / KEYFRAME_INTERVAL_SECONDS);
  return Array.from({ length: count }, (_, i) => {
    const t = i * KEYFRAME_INTERVAL_SECONDS;
    return {
      id: `mock_keyframe_${t}s`,
      timestamp: t,
      imageUrl: `mock://frame/${t}`,
      description: `场景帧 at ${t}s`
    };
  });
}


