import { Activity, AlertCircle, BarChart3, Brain, CheckCircle, Clock, Cpu, Download, FileVideo, Grid3X3, List, Loader2, Pause, Play, RefreshCw, Settings, Square, Target, Upload, Zap, } from "lucide-react" import { FC, useCallback, useMemo, useState } from "react" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Progress } from "@/components/ui/progress" import { ScrollArea } from "@/components/ui/scroll-area" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { cn } from "@/lib/utils" import { useAIIntelligence } from "../../hooks/use-ai-intelligence" import { useContentPipeline } from "../../hooks/use-content-pipeline" import type { AIConfig, IntelligentContent, MediaFileInfo, PipelineProgress, UnifiedContentAnalysis, } from "../../shared/types" import { AnalysisViewer } from "../analysis-viewer/analysis-viewer" import { PreviewGrid } from "../preview-grid/preview-grid" interface UnifiedDashboardProps { className?: string mediaFiles?: MediaFileInfo[] onFileUpload?: (files: File[]) => void onAnalysisComplete?: (analysis: UnifiedContentAnalysis) => void onProcessingComplete?: (content: IntelligentContent) => void onError?: (error: Error) => void } type DashboardView = "overview" | "analysis" | "processing" | "results" | "settings" type ProcessingStatus = "idle" | "analyzing" | "generating" | "adapting" | "completed" | "error" export const UnifiedDashboard: FC = ({ className, mediaFiles = [], onFileUpload, onAnalysisComplete, onProcessingComplete, onError, }) => { const [activeView, setActiveView] = useState("overview") const [processingStatus, setProcessingStatus] = useState("idle") const [currentAnalysis, setCurrentAnalysis] = useState(null) const [processingResults, setProcessingResults] = useState(null) const [processingProgress, setProcessingProgress] = useState(null) const [selectedFiles, setSelectedFiles] = useState>(new Set()) // AI Intelligence Hook const { isProcessing: aiProcessing, progress: aiProgress, error: aiError, result: aiResult, analyzeContent, processProject, pausePipeline, resumePipeline, cancelPipeline, reset: resetAI, } = useAIIntelligence({ onProgress: setProcessingProgress, onComplete: (result) => { setProcessingResults(result) setProcessingStatus("completed") onProcessingComplete?.(result) }, onError: (error) => { setProcessingStatus("error") onError?.(error) }, }) // Content Pipeline Hook const { isRunning: pipelineRunning, isPaused: pipelinePaused, results: pipelineResults, startPipeline, pausePipeline: pauseContentPipeline, resumePipeline: resumeContentPipeline, stopPipeline, } = useContentPipeline() // Combined processing state const isProcessing = aiProcessing || pipelineRunning const isPaused = pipelinePaused const currentProgress = aiProgress || processingProgress // Handle file upload const handleFileUpload = useCallback( (files: File[]) => { onFileUpload?.(files) setProcessingStatus("idle") setCurrentAnalysis(null) setProcessingResults(null) setProcessingProgress(null) }, [onFileUpload], ) // Start AI analysis const handleStartAnalysis = useCallback(async () => { if (mediaFiles.length === 0) return try { setProcessingStatus("analyzing") setActiveView("processing") const config: Partial = { analysis: { enableSceneDetection: true, enableObjectDetection: true, enableFaceDetection: true, enableTextDetection: true, enableAudioAnalysis: true, }, generation: { enableScriptGeneration: true, enableNarrativeStructure: true, }, adaptation: { platforms: ["youtube", "tiktok", "instagram"], enableAutomaticOptimization: true, }, } const analysis = await analyzeContent(mediaFiles, config) setCurrentAnalysis(analysis) setProcessingStatus("completed") setActiveView("analysis") onAnalysisComplete?.(analysis) } catch (error) { setProcessingStatus("error") onError?.(error as Error) } }, [mediaFiles, analyzeContent, onAnalysisComplete, onError]) // Start full AI processing const handleStartProcessing = useCallback(async () => { if (mediaFiles.length === 0) return try { setProcessingStatus("analyzing") setActiveView("processing") const config: Partial = { analysis: { enableSceneDetection: true, enableObjectDetection: true, enableFaceDetection: true, enableTextDetection: true, enableAudioAnalysis: true, }, generation: { enableScriptGeneration: true, enableNarrativeStructure: true, enableCharacterDevelopment: true, enableDialogueGeneration: true, }, adaptation: { platforms: ["youtube", "tiktok", "instagram", "twitter"], enableAutomaticOptimization: true, enableSEOOptimization: true, }, } await processProject(mediaFiles, config) } catch (error) { setProcessingStatus("error") onError?.(error as Error) } }, [mediaFiles, processProject, onError]) // Control functions const handlePause = useCallback(async () => { await pausePipeline() await pauseContentPipeline() }, [pausePipeline, pauseContentPipeline]) const handleResume = useCallback(async () => { await resumePipeline() await resumeContentPipeline() }, [resumePipeline, resumeContentPipeline]) const handleStop = useCallback(async () => { await cancelPipeline() await stopPipeline() setProcessingStatus("idle") setProcessingProgress(null) setActiveView("overview") }, [cancelPipeline, stopPipeline]) const handleReset = useCallback(() => { resetAI() setProcessingStatus("idle") setCurrentAnalysis(null) setProcessingResults(null) setProcessingProgress(null) setSelectedFiles(new Set()) setActiveView("overview") }, [resetAI]) // Statistics for overview const stats = useMemo(() => { const totalFiles = mediaFiles.length const processedFiles = currentAnalysis ? 1 : 0 const analysisComplete = currentAnalysis !== null const processingComplete = processingResults !== null return { totalFiles, processedFiles, analysisComplete, processingComplete, successRate: totalFiles > 0 ? (processedFiles / totalFiles) * 100 : 0, } }, [mediaFiles, currentAnalysis, processingResults]) return (
{/* Header */}

AI Content Intelligence

{stats.totalFiles} файлов
{/* Processing Controls */} {isProcessing && (
{isPaused ? ( ) : ( )}
)} {/* Main Actions */} {!isProcessing && (
)}
{/* Progress Bar */} {isProcessing && currentProgress && (
{currentProgress.currentStep} {isPaused && ( Пауза )}
{currentProgress.overall}%
{currentProgress.details &&

{currentProgress.details}

}
)} {/* Navigation Tabs */} setActiveView(value as DashboardView)} className="flex-1 flex flex-col" > Обзор Анализ Обработка Результаты Настройки {/* Tab Content */}
console.log("Scene selected:", sceneId)} onMomentSelect={(momentId) => console.log("Moment selected:", momentId)} />
) } // Overview Tab Component interface OverviewTabProps { stats: { totalFiles: number processedFiles: number analysisComplete: boolean processingComplete: boolean successRate: number } mediaFiles: MediaFileInfo[] processingStatus: ProcessingStatus onFileUpload: (files: File[]) => void onStartAnalysis: () => void onStartProcessing: () => void } const OverviewTab: FC = ({ stats, mediaFiles, processingStatus, onFileUpload, onStartAnalysis, onStartProcessing, }) => { return (
{/* Statistics Cards */}
} color="blue" /> } color="green" /> } color="purple" />
{/* Quick Actions */} Быстрые действия
{ const files = Array.from(e.target.files || []) onFileUpload(files) }} />
{/* Recent Files */} {mediaFiles.length > 0 && ( Загруженные файлы
{mediaFiles.slice(0, 5).map((file, index) => (

{file.filename}

{formatFileSize(file.size)} • {formatDuration(file.duration)}

{file.format}
))} {mediaFiles.length > 5 && (

и еще {mediaFiles.length - 5} файлов...

)}
)}
) } // Analysis Tab Component interface AnalysisTabProps { analysis: UnifiedContentAnalysis | null onSceneSelect: (sceneId: string) => void onMomentSelect: (momentId: string) => void } const AnalysisTab: FC = ({ analysis, onSceneSelect, onMomentSelect }) => { return (
) } // Processing Tab Component interface ProcessingTabProps { status: ProcessingStatus progress: PipelineProgress | null isProcessing: boolean isPaused: boolean error: Error | null onPause: () => void onResume: () => void onStop: () => void } const ProcessingTab: FC = ({ status, progress, isProcessing, isPaused, error, onPause, onResume, onStop, }) => { return (
{/* Processing Status */} {isProcessing ? : } Состояние обработки
Статус:
{getStatusIcon(status)} {getStatusText(status)} {isPaused && Пауза}
{progress && ( <>
Прогресс: {progress.overall}%
{progress.currentStep && (
Текущий шаг: {progress.currentStep}
)} {progress.details && (
Детали: {progress.details}
)} )} {/* Control Buttons */} {isProcessing && (
{isPaused ? ( ) : ( )}
)}
{/* Error Display */} {error && ( Ошибка обработки

{error.message}

)} {/* Processing Steps Info */} Этапы обработки
) } // Results Tab Component interface ResultsTabProps { results: IntelligentContent | null analysis: UnifiedContentAnalysis | null } const ResultsTab: FC = ({ results, analysis }) => { const [previewMode, setPreviewMode] = useState<"grid" | "list">("grid") if (!results && !analysis) { return (

Результаты появятся после завершения обработки

) } return (
{/* Results Header */}

Результаты обработки

{/* Results Content */}
{analysis && ( console.log("Item selected:", item)} onItemPlay={(item) => console.log("Play item:", item)} onItemDownload={(item) => console.log("Download item:", item)} /> )}
) } // Settings Tab Component const SettingsTab: FC = () => { return (
Настройки анализа
Детекция сцен Включено
Распознавание объектов Включено
Анализ аудио Включено
Генерация скрипта Включено
Настройки экспорта
Формат результатов JSON
Включать превью Да
Качество превью Высокое
) } // Helper Components interface StatsCardProps { title: string value: string | number icon: React.ReactNode color: "blue" | "green" | "purple" | "red" | "yellow" } const StatsCard: FC = ({ title, value, icon, color }) => { const colorClasses = { blue: "text-blue-600 bg-blue-50", green: "text-green-600 bg-green-50", purple: "text-purple-600 bg-purple-50", red: "text-red-600 bg-red-50", yellow: "text-yellow-600 bg-yellow-50", } return (

{title}

{value}

{icon}
) } interface ProcessingStepProps { title: string description: string status: "pending" | "active" | "completed" | "error" } const ProcessingStep: FC = ({ title, description, status }) => { const getIcon = () => { switch (status) { case "completed": return case "active": return case "error": return default: return } } return (
{getIcon()}

{title}

{description}

) } // Utility Functions function getStatusText(status: ProcessingStatus): string { switch (status) { case "idle": return "Ожидание" case "analyzing": return "Анализ" case "generating": return "Генерация" case "adapting": return "Адаптация" case "completed": return "Завершено" case "error": return "Ошибка" default: return "Неизвестно" } } function getStatusIcon(status: ProcessingStatus): React.ReactNode { switch (status) { case "idle": return case "analyzing": case "generating": case "adapting": return case "completed": return case "error": return default: return } } function getStatusColor(status: ProcessingStatus): "blue" | "green" | "purple" | "red" | "yellow" { switch (status) { case "idle": return "blue" case "analyzing": case "generating": case "adapting": return "yellow" case "completed": return "green" case "error": return "red" default: return "blue" } } function getStepStatus(step: string, currentStatus: ProcessingStatus): "pending" | "active" | "completed" | "error" { if (currentStatus === "error") return "error" if (currentStatus === "completed") return "completed" if (currentStatus === step) return "active" const steps = ["analyzing", "generating", "adapting", "completed"] const currentIndex = steps.indexOf(currentStatus) const stepIndex = steps.indexOf(step) if (stepIndex < currentIndex) return "completed" if (stepIndex === currentIndex) return "active" return "pending" } function formatFileSize(bytes: number): string { const units = ["Б", "КБ", "МБ", "ГБ"] let size = bytes let unitIndex = 0 while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024 unitIndex++ } return `${size.toFixed(1)} ${units[unitIndex]}` } function formatDuration(seconds: number): string { const hours = Math.floor(seconds / 3600) const minutes = Math.floor((seconds % 3600) / 60) const secs = Math.floor(seconds % 60) if (hours > 0) { return `${hours}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}` } return `${minutes}:${secs.toString().padStart(2, "0")}` }