interface AppConfig { client_id?: string; client_secret?: string; download_path?: string; streamers?: string[]; theme?: string; download_mode?: 'parts' | 'full'; part_minutes?: number; language?: 'de' | 'en'; filename_template_vod?: string; filename_template_parts?: string; filename_template_clip?: string; smart_queue_scheduler?: boolean; performance_mode?: 'stability' | 'balanced' | 'speed'; prevent_duplicate_downloads?: boolean; persist_queue_on_restart?: boolean; metadata_cache_minutes?: number; [key: string]: unknown; } interface VOD { id: string; title: string; created_at: string; duration: string; thumbnail_url: string; url: string; view_count: number; stream_id?: string; } interface CustomClip { startSec: number; durationSec: number; startPart: number; filenameFormat: 'simple' | 'timestamp' | 'template'; filenameTemplate?: string; } interface MergeGroupItem { url: string; title: string; date: string; streamer: string; duration_str: string; } interface MergeGroup { items: MergeGroupItem[]; mergePhase: 'downloading' | 'merging' | 'splitting' | 'cleanup' | 'done'; currentItemIndex: number; downloadedFiles: Record; mergedFile?: string; splitFiles?: string[]; totalDurationSec?: number; } interface QueueItem { id: string; title: string; url: string; date: string; streamer: string; duration_str: string; status: 'pending' | 'downloading' | 'paused' | 'completed' | 'error'; progress: number; currentPart?: number; totalParts?: number; speed?: string; eta?: string; downloadedBytes?: number; totalBytes?: number; progressStatus?: string; last_error?: string; customClip?: CustomClip; mergeGroup?: MergeGroup; } interface DownloadProgress { id: string; progress: number; speed: string; speedBytesPerSec?: number; eta: string; status: string; currentPart?: number; totalParts?: number; downloadedBytes?: number; totalBytes?: number; } interface RuntimeMetricsSnapshot { cacheHits: number; cacheMisses: number; duplicateSkips: number; retriesScheduled: number; retriesExhausted: number; integrityFailures: number; downloadsStarted: number; downloadsCompleted: number; downloadsFailed: number; downloadedBytesTotal: number; lastSpeedBytesPerSec: number; avgSpeedBytesPerSec: number; activeItemId: string | null; activeItemTitle: string | null; lastErrorClass: string | null; lastRetryDelaySeconds: number; timestamp: string; queue: { pending: number; downloading: number; paused: number; completed: number; error: number; total: number; }; caches: { loginToUserId: number; vodList: number; clipInfo: number; }; config: { performanceMode: 'stability' | 'balanced' | 'speed'; smartScheduler: boolean; metadataCacheMinutes: number; duplicatePrevention: boolean; }; } interface VideoInfo { duration: number; width: number; height: number; fps: number; } interface ClipDialogData { url: string; title: string; date: string; streamer: string; duration: string; } interface UpdateInfo { version: string; releaseDate?: string; releaseName?: string; releaseNotes?: string; } interface UpdateDownloadProgress { percent: number; bytesPerSecond: number; transferred: number; total: number; } interface PreflightChecks { internet: boolean; streamlink: boolean; ffmpeg: boolean; ffprobe: boolean; downloadPathWritable: boolean; } interface PreflightResult { ok: boolean; autoFixApplied: boolean; checks: PreflightChecks; messages: string[]; timestamp: string; } interface ApiBridge { getConfig(): Promise; saveConfig(config: Partial): Promise; login(): Promise; getUserId(username: string): Promise; getVODs(userId: string, forceRefresh?: boolean): Promise; getQueue(): Promise; addToQueue(item: Omit): Promise; removeFromQueue(id: string): Promise; reorderQueue(orderIds: string[]): Promise; clearCompleted(): Promise; retryFailedDownloads(): Promise; createMergeGroup(itemIds: string[]): Promise; startDownload(): Promise; pauseDownload(): Promise; cancelDownload(): Promise; isDownloading(): Promise; downloadClip(url: string): Promise<{ success: boolean; error?: string }>; selectFolder(): Promise; selectVideoFile(): Promise; selectMultipleVideos(): Promise; saveVideoDialog(defaultName: string): Promise; openFolder(path: string): Promise; getVideoInfo(filePath: string): Promise; extractFrame(filePath: string, timeSeconds: number): Promise; cutVideo(inputFile: string, startTime: number, endTime: number): Promise<{ success: boolean; outputFile: string | null }>; mergeVideos(inputFiles: string[], outputFile: string): Promise<{ success: boolean; outputFile: string | null }>; getVersion(): Promise; checkUpdate(): Promise<{ checking?: boolean; error?: boolean; skipped?: 'ready-to-install' | 'in-progress' | 'throttled' | 'error' | string }>; downloadUpdate(): Promise<{ downloading?: boolean; error?: boolean; skipped?: 'ready-to-install' | 'in-progress' | 'error' | string }>; installUpdate(): Promise; openExternal(url: string): Promise; runPreflight(autoFix: boolean): Promise; getDebugLog(lines: number): Promise; getRuntimeMetrics(): Promise; exportRuntimeMetrics(): Promise<{ success: boolean; cancelled?: boolean; error?: string; filePath?: string }>; onDownloadProgress(callback: (progress: DownloadProgress) => void): void; onQueueUpdated(callback: (queue: QueueItem[]) => void): void; onQueueDuplicateSkipped(callback: (payload: { title: string; streamer: string; url: string }) => void): void; onDownloadStarted(callback: () => void): void; onDownloadFinished(callback: () => void): void; onCutProgress(callback: (percent: number) => void): void; onMergeProgress(callback: (percent: number) => void): void; onUpdateChecking(callback: () => void): void; onUpdateAvailable(callback: (info: UpdateInfo) => void): void; onUpdateNotAvailable(callback: () => void): void; onUpdateDownloadProgress(callback: (progress: UpdateDownloadProgress) => void): void; onUpdateDownloaded(callback: (info: UpdateInfo) => void): void; onUpdateError(callback: (payload: { message: string }) => void): void; } interface Window { api: ApiBridge; }