import { defineStore } from 'pinia' export const useUploadStore = defineStore('upload', { state: () => ({ selectedFile: null, fileType: null, // 'image' ou 'video' filePreview: null, uploadStatus: 'idle', // 'idle', 'uploading', 'success', 'error' error: null, // Spécifique aux vidéos videoType: null, // 'static' ou 'dynamic' extractedFrame: null // Pour les vidéos statiques }), getters: { isFileSelected: (state) => state.selectedFile !== null, isImage: (state) => state.fileType === 'image', isVideo: (state) => state.fileType === 'video', isUploading: (state) => state.uploadStatus === 'uploading', // Nouveaux getters pour les vidéos isStaticVideo: (state) => state.fileType === 'video' && state.videoType === 'static', isDynamicVideo: (state) => state.fileType === 'video' && state.videoType === 'dynamic', shouldProcessDirectly: (state) => state.fileType === 'image' || state.isStaticVideo, needsParameters: (state) => state.isDynamicVideo }, actions: { setFile(file) { this.selectedFile = file this.fileType = file.type.startsWith('image/') ? 'image' : 'video' this.createPreview(file) this.uploadStatus = 'idle' this.error = null // Reset video-specific data this.videoType = null this.extractedFrame = null }, async setVideoType(type) { this.videoType = type if (type === 'static') { console.log('🔥 Starting frame extraction for static video...') await this.extractFrameFromVideo() console.log('🔥 Frame extraction completed:', { hasExtractedFrame: !!this.extractedFrame, extractedFrameType: this.extractedFrame?.type, extractedFrameName: this.extractedFrame?.name }) } }, createPreview(file) { if (file.type.startsWith('image/')) { this.filePreview = URL.createObjectURL(file) } else { this.filePreview = URL.createObjectURL(file) } }, async extractFrameFromVideo() { if (!this.selectedFile || !this.isVideo) { console.error('🔥 Cannot extract frame: no file or not a video') return null } try { const video = document.createElement('video') video.src = URL.createObjectURL(this.selectedFile) return new Promise((resolve, reject) => { video.addEventListener('loadedmetadata', () => { console.log('🔥 Video metadata loaded, seeking to frame 0') video.currentTime = 0 // Première image }) video.addEventListener('seeked', () => { try { console.log('🔥 Video seeked, drawing to canvas') const canvas = document.createElement('canvas') canvas.width = video.videoWidth canvas.height = video.videoHeight if (video.videoWidth === 0 || video.videoHeight === 0) { throw new Error('Video dimensions are 0') } const ctx = canvas.getContext('2d') ctx.drawImage(video, 0, 0) canvas.toBlob((blob) => { if (!blob) { reject(new Error('Failed to create blob from canvas')) return } // Créer un File avec un nom au lieu d'un Blob simple const file = new File([blob], 'extracted_frame.jpg', { type: 'image/jpeg' }) this.extractedFrame = file console.log('🔥 Frame extracted successfully:', { name: file.name, type: file.type, size: file.size }) URL.revokeObjectURL(video.src) resolve(file) }, 'image/jpeg', 0.9) } catch (err) { console.error('🔥 Error during canvas operations:', err) URL.revokeObjectURL(video.src) reject(err) } }) video.addEventListener('error', (err) => { console.error('🔥 Video loading error:', err) URL.revokeObjectURL(video.src) reject(err) }) // Timeout de sécurité setTimeout(() => { console.error('🔥 Frame extraction timeout') URL.revokeObjectURL(video.src) reject(new Error('Frame extraction timeout')) }, 10000) }) } catch (error) { console.error('🔥 Erreur extraction frame:', error) this.setError('Impossible d\'extraire une image de la vidéo: ' + error.message) return null } }, clearFile() { if (this.filePreview) { URL.revokeObjectURL(this.filePreview) } this.selectedFile = null this.fileType = null this.filePreview = null this.uploadStatus = 'idle' this.error = null this.videoType = null this.extractedFrame = null }, setUploadStatus(status) { this.uploadStatus = status }, setError(error) { this.error = error this.uploadStatus = 'error' } } })