<template>
  <div class="video-section">
    <tool-bar 
      :current-tool="currentTool" 
      @tool-selected="selectTool"
    />

    <div class="video-container" ref="container">
      <div class="video-wrapper">
        <video
          ref="videoRef"
          class="video-element"
          crossorigin="anonymous"
          muted
        ></video>
      </div>
      
      <div class="canvas-wrapper">
        <v-stage
          ref="stage"
          :config="stageConfig"
          @mousedown="handleMouseDown"
          @mousemove="handleMouseMove"
          @mouseup="handleMouseUp"
          class="canvas-overlay"
        >
          <v-layer ref="layer">
            <!-- Fond transparent explicite -->
            <v-rect
              :config="{
                x: position.x,
                y: position.y,
                width: imageWidth,
                height: imageHeight,
                fill: 'transparent'
              }"
            />
            
            <!-- Lignes de guidage -->
            <v-line
              v-if="mousePosition.x !== null && isInsideImage(mousePosition)"
              :config="{
                points: [
                  position.x, mousePosition.y,
                  position.x + imageWidth, mousePosition.y
                ],
                stroke: '#ffffff',
                strokeWidth: 1,
                dash: [5, 5],
                opacity: 0.5
              }"
            />
            <v-line
              v-if="mousePosition.y !== null && isInsideImage(mousePosition)"
              :config="{
                points: [
                  mousePosition.x, position.y,
                  mousePosition.x, position.y + imageHeight
                ],
                stroke: '#ffffff',
                strokeWidth: 1,
                dash: [5, 5],
                opacity: 0.5
              }"
            />
            
            <!-- Rectangle en cours de dessin -->
            <v-rect
              v-if="isDrawing && currentTool === 'rectangle'"
              :config="{
                x: rectangleStart.x,
                y: rectangleStart.y,
                width: rectangleSize.width,
                height: rectangleSize.height,
                stroke: getObjectColor(annotationStore.selectedObjectId),
                strokeWidth: 1,
                fill: null,
                dash: []
              }"
            />
            <!-- Rectangles sauvegardés -->
            <v-rect
              v-for="rect in rectangles"
              :key="rect.id"
              :config="{
                x: rect.x,
                y: rect.y,
                width: rect.width,
                height: rect.height,
                stroke: selectedId === rect.id ? '#FFD700' : rect.color,
                strokeWidth: selectedId === rect.id ? 3 : (rect.objectId === annotationStore.selectedObjectId ? 2 : 1),
                fill: null,
                dash: rect.type === 'proxy' ? [5, 5] : [],
                id: rect.id,
                objectId: rect.objectId
              }"
              @mousedown="handleShapeMouseDown($event, rect.id)"
            />
            
            <!-- Halo de sélection pour le rectangle sélectionné -->
            <v-rect
              v-if="selectedId && rectangles.find(r => r.id === selectedId)"
              :key="`halo-${selectedId}`"
              :config="{
                x: rectangles.find(r => r.id === selectedId).x - 3,
                y: rectangles.find(r => r.id === selectedId).y - 3,
                width: rectangles.find(r => r.id === selectedId).width + 6,
                height: rectangles.find(r => r.id === selectedId).height + 6,
                stroke: '#FFD700',
                strokeWidth: 1,
                fill: null,
                dash: [6, 6],
                opacity: 0.6,
                listening: false
              }"
            />
            <!-- Poignées de redimensionnement pour le rectangle sélectionné -->
            <template v-if="selectedId && currentTool === 'arrow'">
              <v-circle
                v-for="handle in getResizeHandles()"
                :key="handle.position"
                :config="{
                  x: handle.x,
                  y: handle.y,
                  radius: 4,
                  fill: 'white',
                  stroke: '#4CAF50',
                  strokeWidth: 1,
                  draggable: true
                }"
                @dragmove="handleResize($event, handle.position)"
              />
            </template>
            <!-- Points existants -->
            <v-group
              v-for="point in points"
              :key="point.id"
              :config="{
                x: point.x,
                y: point.y,
                objectId: point.objectId,
                listening: true,
                id: point.id
              }"
              @mousedown="handlePointClick(point.id, $event)"
            >
              <!-- Halo de sélection pour le point sélectionné -->
              <v-circle
                v-if="selectedId === point.id"
                :config="{
                  radius: 12,
                  fill: 'transparent',
                  stroke: '#FFD700',
                  strokeWidth: 2,
                  dash: [4, 4],
                  opacity: 0.8
                }"
              />
              
              <v-circle
                :config="{
                  radius: selectedId === point.id ? 7 : (point.objectId === annotationStore.selectedObjectId ? 6 : 5),
                  fill: point.color,
                  stroke: selectedId === point.id ? '#FFD700' : 'white',
                  strokeWidth: selectedId === point.id ? 3 : (point.objectId === annotationStore.selectedObjectId ? 2 : 1)
                }"
              />
              <v-line
                :config="{
                  points: [-2, 0, 2, 0],
                  stroke: selectedId === point.id ? '#FFD700' : 'white',
                  strokeWidth: selectedId === point.id ? 2 : 1
                }"
              />
              <v-line
                v-if="point.type === 'positive'"
                :config="{
                  points: [0, -2, 0, 2],
                  stroke: selectedId === point.id ? '#FFD700' : 'white',
                  strokeWidth: selectedId === point.id ? 2 : 1
                }"
              />
            </v-group>
            
            <!-- Masques de segmentation -->
            <v-shape
              v-for="annotation in maskedAnnotations"
              :key="`mask-${annotation.id}`"
              :config="{
                sceneFunc: (context, shape) => drawMask(context, shape, annotation),
                fill: annotation.objectId === annotationStore.selectedObjectId ? 
                  `${getObjectColor(annotation.objectId)}88` : 
                  `${getObjectColor(annotation.objectId)}44`,
                stroke: getObjectColor(annotation.objectId),
                strokeWidth: annotation.objectId === annotationStore.selectedObjectId ? 2 : 1,
                opacity: 0.8,
                listening: true,
                id: annotation.id
              }"
              @mousedown="handleMaskClick(annotation.id)"
            />

            <!-- Bounding boxes de tous les objets -->
            <v-rect
              v-for="bbox in allBoundingBoxes"
              v-show="showAllBoundingBoxes && bbox"
              :key="bbox.id"
              :config="{
                x: bbox.x,
                y: bbox.y,
                width: bbox.width,
                height: bbox.height,
                stroke: bbox.color,
                strokeWidth: bbox.objectId === annotationStore.selectedObjectId ? 2 : 1,
                fill: null,
                dash: [4, 2], // Trait pointillé uniforme pour tous les rectangles
                opacity: 0.8,
                listening: false  // Ne pas intercepter les clics sur les bbox d'affichage
              }"
            />
          </v-layer>
        </v-stage>
      </div>
    </div>


  </div>
</template>

<script>
import { useVideoStore } from '@/stores/videoStore'
import { useAnnotationStore } from '@/stores/annotationStore'
import ToolBar from './tools/ToolBar.vue'

/*
FONCTIONNALITÉS DES BOUNDING BOXES :

1. Affichage automatique des bounding boxes pour tous les objets sur chaque frame :
   - Annotations en cours : rectangles et masques créés dans cette session
   - Objet sélectionné : trait plus épais pour mise en évidence

2. Différenciation visuelle :
   - Annotations rectangles : trait continu []
   - Annotations masques : trait pointillé court [- - -]
   - Couleurs : selon la couleur de l'objet définie

3. Contrôles clavier :
   - Touche 'b' : Basculer l'affichage des bounding boxes (on/off)
   - Touche 'd' : Afficher les informations de débogage dans la console
   - Par défaut : affichage activé

4. Sources de données :
   - Store d'annotations (this.annotationStore) : annotations créées en temps réel

5. Stockage des bounding boxes :
   - Rectangles : coordonnées directes (x, y, width, height)
   - Masques de segmentation : bbox calculée à partir des points ou du masque

6. Débogage :
   - Appel automatique de debugBoundingBoxes() à chaque changement de frame
   - Informations détaillées sur les annotations trouvées
*/

export default {
  name: 'VideoSection',

  components: {
    ToolBar
  },

  props: {
    selectedObjectId: {
      type: String,
      default: null
    }
  },

  setup() {
    const videoStore = useVideoStore()
    const annotationStore = useAnnotationStore()
    
    return { videoStore, annotationStore }
  },

  data() {
    return {
      videoElement: null,
      imageWidth: 0,
      imageHeight: 0,
      position: { x: 0, y: 0 },
      stageConfig: {
        width: 0,
        height: 0
      },
      currentTool: 'arrow',
      isDrawing: false,
      rectangleStart: { x: 0, y: 0 },
      rectangleSize: { width: 0, height: 0 },
      mousePosition: { x: null, y: null },
      selectedId: null,
      isDragging: false,
      dragStartPos: { x: 0, y: 0 },
      resizing: false,
      resizeTimeout: null,
      animationId: null,
      currentFrameNumber: 0,
      originalVideoPath: null,
      proxyVideoPath: null,
      isUsingProxy: true,
      originalVideoDimensions: { width: 0, height: 0 },
      maskCache: {},
      showAllBoundingBoxes: true, // Nouvelle propriété pour contrôler l'affichage des bbox
    }
  }, 

  mounted() {
    // Réactiver l'élément vidéo
    this.videoElement = this.$refs.videoRef
    this.videoElement.muted = true
    this.videoElement.addEventListener('loadedmetadata', this.handleVideoLoaded)
    this.videoElement.addEventListener('timeupdate', this.updateCurrentFrame)
    
    // S'abonner aux changements de vidéo dans le store
    this.subscribeToVideoStore()
    
    window.addEventListener('resize', this.handleWindowResize)
    window.addEventListener('keydown', this.handleKeyDown)
  },

  beforeUnmount() {
    window.removeEventListener('resize', this.handleWindowResize)
    window.removeEventListener('keydown', this.handleKeyDown)
    
    if (this.videoElement) {
      this.videoElement.removeEventListener('loadedmetadata', this.handleVideoLoaded)
      this.videoElement.pause()
    }
    
    this.stopAnimation()
    
    // Supprimer l'écouteur d'événement
    this.videoElement.removeEventListener('timeupdate', this.updateCurrentFrame)
  },

  computed: {

    availableObjects() {
      return Object.values(this.annotationStore.objects)
    },
    hasSelectedObject() {
      return !!this.annotationStore.selectedObjectId
    },
    rectangles() {
      const frameAnnotations = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber) || []
      
      // Convertir les annotations en rectangles pour l'affichage
      return frameAnnotations
        .filter(annotation => annotation && annotation.type === 'rectangle')
        .map(annotation => {
          const object = this.annotationStore.objects[annotation.objectId]
          const color = object ? object.color : '#4CAF50'
          
          // Convertir les coordonnées originales en coordonnées d'affichage
          const displayX = this.position.x + (annotation.x / this.scaleX)
          const displayY = this.position.y + (annotation.y / this.scaleY)
          const displayWidth = annotation.width / this.scaleX
          const displayHeight = annotation.height / this.scaleY
          
          return {
            id: annotation.id,
            objectId: annotation.objectId,
            x: displayX,
            y: displayY,
            width: displayWidth,
            height: displayHeight,
            color: color
          }
        })
    },
    points() {
      const frameAnnotations = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber) || []
      
      // Points directs de type "point" (nouveau système)
      const directPoints = frameAnnotations
        .filter(annotation => annotation && annotation.type === 'point')
        .map(annotation => ({
          id: annotation.id,
          objectId: annotation.objectId,
          x: this.position.x + (annotation.x / this.scaleX),
          y: this.position.y + (annotation.y / this.scaleY),
          type: annotation.pointType,
          color: this.getObjectColor(annotation.objectId),
          isDirect: true
        }))
      
      // Points des annotations de type "mask" qui contiennent des points (ancien système)
      const annotationPoints = frameAnnotations
        .filter(annotation => annotation && annotation.type === 'mask' && annotation.points)
        .flatMap(annotation => annotation.points.map(point => ({
          id: `${annotation.id}-point-${point.x}-${point.y}`,
          objectId: annotation.objectId,
          x: this.position.x + (point.x / this.scaleX),
          y: this.position.y + (point.y / this.scaleY),
          type: point.type,
          color: this.getObjectColor(annotation.objectId),
          fromAnnotation: annotation.id
        })))
      
      // Points temporaires (ne devrait plus être utilisé mais gardé pour sécurité)
      const tempPoints = (this.annotationStore.temporaryPoints || []).map(point => ({
        id: `temp-point-${point.id}`,
        objectId: point.objectId,
        x: this.position.x + (point.x / this.scaleX),
        y: this.position.y + (point.y / this.scaleY),
        type: point.pointType,
        color: this.getObjectColor(point.objectId),
        isTemporary: true
      }))
      
      return [...directPoints, ...annotationPoints, ...tempPoints]
    },
    scaleX() {
      if (this.originalVideoDimensions.width && this.imageWidth) {
        return this.originalVideoDimensions.width / this.imageWidth
      }
      if (!this.videoElement || !this.imageWidth) return 1
      return this.videoElement.videoWidth / this.imageWidth
    },
    scaleY() {
      if (this.originalVideoDimensions.height && this.imageHeight) {
        return this.originalVideoDimensions.height / this.imageHeight
      }
      if (!this.videoElement || !this.imageHeight) return 1
      return this.videoElement.videoHeight / this.imageHeight
    },
    maskedAnnotations() {
      const frameAnnotations = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber) || [];
      return frameAnnotations.filter(annotation => annotation && annotation.mask && annotation.maskImageSize);
    },
    // Nouvelle computed property pour toutes les bounding boxes
    allBoundingBoxes() {
      // Temporairement désactivé pour isoler l'erreur
      return []
      
      // Le code original sera restauré une fois l'erreur identifiée
      /*
      const frameAnnotations = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber) || []
      const boundingBoxes = []

      // 1. BOUNDING BOXES DES ANNOTATIONS EN COURS (STORE D'ANNOTATIONS)
      frameAnnotations.forEach(annotation => {
        if (!annotation) return // Vérifier que l'annotation existe
        
        const object = this.annotationStore.objects[annotation.objectId]
        const color = object ? object.color : '#CCCCCC'
        const objectName = object ? object.name : `Objet ${annotation.objectId}`

        if (annotation.type === 'rectangle') {
          // Pour les rectangles, utiliser directement leurs coordonnées
          const displayX = this.position.x + (annotation.x / this.scaleX)
          const displayY = this.position.y + (annotation.y / this.scaleY)
          const displayWidth = annotation.width / this.scaleX
          const displayHeight = annotation.height / this.scaleY

          boundingBoxes.push({
            id: `bbox-${annotation.id}`,
            objectId: annotation.objectId,
            x: displayX,
            y: displayY,
            width: displayWidth,
            height: displayHeight,
            color: color,
            name: objectName,
            type: 'rectangle',
            annotationId: annotation.id,
            source: 'current' // Annotations en cours
          })
        } else if (annotation.type === 'mask' && annotation.mask) {
          // Pour les masques, calculer la bounding box ou utiliser celle stockée
          let bbox = null
          
          if (annotation.bbox && annotation.bbox.output) {
            // Si la bbox est déjà stockée, l'utiliser
            bbox = annotation.bbox.output
          } else if (annotation.bbox) {
            // Si c'est juste bbox sans output
            bbox = annotation.bbox
          } else {
            // Sinon, essayer de calculer une bbox approximative à partir des dimensions du masque
            // Cette méthode n'est pas parfaite mais donne une approximation
            const maskSize = annotation.maskImageSize || { width: this.originalVideoDimensions.width, height: this.originalVideoDimensions.height }
            
            // Pour une approximation, on peut supposer que le masque couvre une région significative
            // En attendant une vraie bbox calculée côté serveur
            bbox = {
              x: Math.round(maskSize.width * 0.1), // 10% du bord gauche
              y: Math.round(maskSize.height * 0.1), // 10% du bord haut
              width: Math.round(maskSize.width * 0.8), // 80% de la largeur
              height: Math.round(maskSize.height * 0.8) // 80% de la hauteur
            }
          }

          if (bbox) {
            // Convertir les coordonnées originales en coordonnées d'affichage
            const displayX = this.position.x + (bbox.x / this.scaleX)
            const displayY = this.position.y + (bbox.y / this.scaleY)
            const displayWidth = bbox.width / this.scaleX
            const displayHeight = bbox.height / this.scaleY

            boundingBoxes.push({
              id: `bbox-${annotation.id}`,
              objectId: annotation.objectId,
              x: displayX,
              y: displayY,
              width: displayWidth,
              height: displayHeight,
              color: color,
              name: objectName,
              type: 'mask',
              annotationId: annotation.id,
              source: 'current' // Annotations en cours
            })
          }
        }
      })

      // Filtrer les bounding boxes invalides avant de retourner
      return boundingBoxes.filter(bbox => bbox && bbox.type && bbox.id)
      */
    },
  },

  methods: {
    subscribeToVideoStore() {
      const videoStore = useVideoStore()
      
      // Observer les changements dans le store
      this.$watch(
        () => videoStore.selectedVideo,
        (newVideo) => {
          if (newVideo) {
            console.log('Nouvelle vidéo sélectionnée dans VideoSection:', newVideo)
            this.loadVideo(newVideo.path)
          }
        },
        { immediate: true }
      )
      
      // Observer les changements de temps dans la timeline
      this.$watch(
        () => videoStore.currentTime,
        (newTime) => {
          if (this.videoElement && newTime !== undefined) {
            // Seulement mettre à jour si la différence est significative
            if (Math.abs(this.videoElement.currentTime - newTime) > 0.05) {
              this.videoElement.currentTime = newTime
            }
          }
        }
      )
      
      // Observer l'état de lecture (play/pause)
      this.$watch(
        () => videoStore.isPlaying,
        (isPlaying) => {
          // console.log('État de lecture changé dans VideoSection:', isPlaying)
          if (isPlaying) {
            this.playVideo()
          } else {
            this.pauseVideo()
          }
        }
      )
    },
    
    loadVideo(videoPath) {
      if (!videoPath) return
      
      // Arrêter toute animation en cours
      this.stopAnimation()
      
      this.originalVideoPath = videoPath
      
      // Si l'élément vidéo est commenté, ne pas essayer de charger la vidéo
      if (!this.videoElement) {
        console.log("Mode test: élément vidéo non disponible, simulation uniquement")
        // Simuler des dimensions pour le test
        this.imageWidth = 640
        this.imageHeight = 360
        this.updateDimensions()
        return
      }
      
      // Si c'est une URL blob (vidéo uploadée), charger directement sans proxy
      if (videoPath.startsWith('blob:')) {
        console.log("Chargement direct d'une vidéo uploadée (blob URL)")
        this.videoElement.src = videoPath
        this.videoElement.load()
        return
      }
      
      // Si c'est un fichier média par défaut depuis les assets, le charger directement
      if (videoPath.includes('/assets/') || videoPath.includes('assets/') || 
          videoPath.includes('.jpg') || videoPath.includes('.png') || 
          videoPath.includes('.jpeg') || videoPath.includes('.mp4') || 
          videoPath.includes('.webm') || videoPath.includes('.mov')) {
        console.log("Chargement direct d'un fichier média par défaut")
        this.videoElement.src = videoPath
        this.videoElement.load()
        return
      }
      
      // Pour les fichiers locaux, utiliser le système de proxy existant
      this.getOriginalVideoDimensions(videoPath)
        .then(dimensions => {
          console.log("Dimensions de la vidéo originale:", dimensions.width, "x", dimensions.height)
          // Stocker les dimensions originales pour les utiliser dans les calculs de coordonnées
          this.originalVideoDimensions = dimensions
          
          // Vérifier si un proxy existe déjà ou en créer un
          this.createOrLoadProxy(videoPath)
            .then(proxyPath => {
              this.proxyVideoPath = proxyPath
              
              // Charger le proxy si l'option est activée, sinon charger l'original
              const sourceToLoad = this.isUsingProxy ? proxyPath : videoPath
              this.videoElement.src = sourceToLoad
              this.videoElement.load()
            })
            .catch(err => {
              console.error("Erreur lors de la création du proxy:", err)
              // En cas d'erreur, charger la vidéo originale
              this.videoElement.src = videoPath
              this.videoElement.load()
            })
        })
        .catch(err => {
          console.error("Erreur lors de l'obtention des dimensions de la vidéo originale:", err)
          // Continuer avec le chargement normal
          this.videoElement.src = videoPath
          this.videoElement.load()
        })
    },
    
    async getOriginalVideoDimensions(videoPath) {
      return new Promise((resolve, reject) => {
        // Créer un élément vidéo temporaire pour obtenir les dimensions
        const tempVideo = document.createElement('video')
        tempVideo.style.display = 'none'
        
        // Configurer les gestionnaires d'événements
        tempVideo.onloadedmetadata = () => {
          const dimensions = {
            width: tempVideo.videoWidth,
            height: tempVideo.videoHeight
          }
          
          // Nettoyer
          document.body.removeChild(tempVideo)
          
          resolve(dimensions)
        }
        
        tempVideo.onerror = (error) => {
          // Nettoyer
          if (document.body.contains(tempVideo)) {
            document.body.removeChild(tempVideo)
          }
          
          reject(error)
        }
        
        // Ajouter l'élément au DOM et charger la vidéo
        document.body.appendChild(tempVideo)
        tempVideo.src = videoPath
      })
    },
    
    async createOrLoadProxy(originalPath) {
      // Générer un nom de fichier pour le proxy
      const proxyPath = this.generateProxyPath(originalPath)
      
      // Vérifier si le proxy existe déjà
      const proxyExists = await this.checkIfFileExists(proxyPath)
      
      if (proxyExists) {
        console.log("Proxy vidéo existant trouvé:", proxyPath)
        return proxyPath
      }
      
      // Créer un nouveau proxy
      console.log("Création d'un nouveau proxy vidéo...")
      return this.createVideoProxy(originalPath, proxyPath)
    },
    
    generateProxyPath(originalPath) {
      // Exemple: transformer "/videos/original.mp4" en "/videos/original_proxy.mp4"
      const pathParts = originalPath.split('.')
      const extension = pathParts.pop()
      return `${pathParts.join('.')}_proxy.${extension}`
    },
    
    async checkIfFileExists() {
      // DÉSACTIVÉ - utilisation de vidéo statique dans assets
      console.log("Vérification de fichier désactivée - utilisation de vidéo statique");
      return true; // Toujours vrai pour la vidéo statique
    },
    
    async createVideoProxy(originalPath) {
      // DÉSACTIVÉ - utilisation de vidéo statique dans assets
      console.log("Création de proxy désactivée - utilisation de vidéo statique");
      return originalPath; // Retourner le chemin original
    },
    
    toggleProxyMode() {
      this.isUsingProxy = !this.isUsingProxy
      
      // Sauvegarder la position actuelle
      const currentTime = this.videoElement.currentTime
      
      // Charger la vidéo appropriée
      this.videoElement.src = this.isUsingProxy ? this.proxyVideoPath : this.originalVideoPath
      this.videoElement.load()
      
      // Restaurer la position après le chargement
      this.videoElement.addEventListener('loadedmetadata', () => {
        this.videoElement.currentTime = currentTime
      }, { once: true })
    },
    
    handleVideoLoaded() {
      console.log('Vidéo chargée, dimensions:', this.videoElement.videoWidth, 'x', this.videoElement.videoHeight)
      
      // Vérifier que les dimensions sont valides
      if (!this.videoElement.videoWidth || !this.videoElement.videoHeight) {
        console.error('Dimensions de vidéo invalides après chargement')
        return
      }

      // Stocker les dimensions si elles ne sont pas déjà définies
      if (!this.originalVideoDimensions.width || !this.originalVideoDimensions.height) {
        this.originalVideoDimensions = {
          width: this.videoElement.videoWidth,
          height: this.videoElement.videoHeight
        }
      }
      
      // Ajouter un log pour indiquer si c'est le proxy ou l'original
      const sourceType = this.isUsingProxy ? "proxy" : "originale"
      console.log(`Vidéo ${sourceType} chargée. Dimensions d'affichage:`, 
                  this.videoElement.videoWidth, 'x', this.videoElement.videoHeight)
      
      this.initializeView()
      
      // Démarrer l'animation pour le rendu fluide
      this.startAnimation()
    },
    
    playVideo() {
      if (!this.videoElement) {
        console.log("Mode test: élément vidéo non disponible")
        return
      }
      
      this.videoElement.play()
      this.startAnimation()
    },
    
    pauseVideo() {
      if (!this.videoElement) {
        console.log("Mode test: élément vidéo non disponible")
        return
      }
      
      this.videoElement.pause()
    },
    
    startAnimation() {
      // Arrêter l'animation existante si elle existe
      this.stopAnimation()
      
      // Démarrer l'animation
      this.animationId = requestAnimationFrame(this.animate)
    },
    
    stopAnimation() {
      if (this.animationId) {
        cancelAnimationFrame(this.animationId)
        this.animationId = null
      }
    },
    
    initializeView() {
      this.$nextTick(() => {
        this.updateDimensions()
      })
    },

    handleWindowResize() {
      if (this.resizeTimeout) {
        clearTimeout(this.resizeTimeout)
      }
      this.resizeTimeout = setTimeout(() => {
        this.updateDimensions()
      }, 100)
    },

    updateDimensions() {
      const container = this.$refs.container
      if (!container) return

      const containerWidth = container.clientWidth
      const containerHeight = container.clientHeight

      // Obtenir les dimensions de la vidéo avec des valeurs par défaut
      let videoWidth = 0
      let videoHeight = 0

      if (this.videoElement && this.videoElement.videoWidth && this.videoElement.videoHeight) {
        videoWidth = this.videoElement.videoWidth
        videoHeight = this.videoElement.videoHeight
      } else if (this.originalVideoDimensions.width && this.originalVideoDimensions.height) {
        videoWidth = this.originalVideoDimensions.width
        videoHeight = this.originalVideoDimensions.height
      } else if (this.imageWidth && this.imageHeight) {
        videoWidth = this.imageWidth
        videoHeight = this.imageHeight
      } else {
        // Valeurs par défaut si aucune dimension n'est disponible
        videoWidth = 640
        videoHeight = 480
      }

      // Vérifier que les dimensions sont valides
      if (!videoWidth || !videoHeight || videoWidth <= 0 || videoHeight <= 0) {
        console.warn('Dimensions vidéo invalides, utilisation de valeurs par défaut')
        videoWidth = 640
        videoHeight = 480
      }

      const videoRatio = videoWidth / videoHeight

      let width = containerWidth
      let height = width / videoRatio

      if (height > containerHeight) {
        height = containerHeight
        width = height * videoRatio
      }

      // S'assurer que les dimensions finales sont valides
      if (isNaN(width) || isNaN(height) || width <= 0 || height <= 0) {
        console.error('Dimensions calculées invalides, utilisation des dimensions du conteneur')
        width = containerWidth || 640
        height = containerHeight || 480
      }

      this.stageConfig.width = containerWidth
      this.stageConfig.height = containerHeight
      this.imageWidth = width
      this.imageHeight = height

      this.position = {
        x: Math.floor((containerWidth - width) / 2),
        y: Math.floor((containerHeight - height) / 2)
      }
      
      console.log('Dimensions mises à jour:', { videoWidth, videoHeight, displayWidth: width, displayHeight: height })
      
      // Forcer une mise à jour du canvas
      if (this.$refs.layer) {
        const layer = this.$refs.layer.getNode();
        layer.batchDraw();
      }
    },

    selectTool(tool) {
      this.currentTool = tool
    },

    handleMouseDown(e) {
      if (e.evt.button !== 0) return

      const stage = this.$refs.stage.getStage()
      const pointerPos = stage.getPointerPosition()

      if (!this.isInsideImage(pointerPos)) return

      if (this.currentTool === 'arrow' && this.selectedId) {
        const handles = this.getResizeHandles()
        const clickedHandle = handles.find(handle => {
          const dx = handle.x - pointerPos.x
          const dy = handle.y - pointerPos.y
          return Math.sqrt(dx * dx + dy * dy) <= 5
        })
        
        if (clickedHandle) {
          this.resizing = true
          return
        }
      }

      // Sélection des rectangles (fonctionne avec tous les outils)
      const clickedRect = this.rectangles.find(rect => 
        pointerPos.x >= rect.x && 
        pointerPos.x <= rect.x + rect.width &&
        pointerPos.y >= rect.y && 
        pointerPos.y <= rect.y + rect.height
      )
      
      if (clickedRect) {
        this.selectedId = clickedRect.id
        if (this.currentTool === 'arrow') {
          this.isDragging = true
          this.dragStartPos = pointerPos
        }
        console.log('Selected rectangle:', this.selectedId)
        return
      }

      // Sélection des points (fonctionne avec tous les outils)
      const clickedPoint = this.points.find(point => {
        const dx = point.x - pointerPos.x
        const dy = point.y - pointerPos.y
        return Math.sqrt(dx * dx + dy * dy) <= 8 // Augmenter la zone de détection
      })

      if (clickedPoint) {
        this.selectedId = clickedPoint.id
        if (this.currentTool === 'arrow') {
          this.isDragging = true
          this.dragStartPos = pointerPos
        }
        console.log('Selected point:', this.selectedId)
        return
      }

      // Déselectionner si aucun élément n'est cliqué
      this.selectedId = null

      switch(this.currentTool) {
        case 'rectangle':
          if (!this.annotationStore.selectedObjectId) {
            this.annotationStore.addObject()
          }
          
          this.isDrawing = true
          this.rectangleStart = {
            x: pointerPos.x,
            y: pointerPos.y
          }
          this.rectangleSize = { width: 0, height: 0 }
          break
        case 'positive':
          this.addPoint(pointerPos, 'positive')
          break
        case 'negative':
          this.addPoint(pointerPos, 'negative')
          break
      }
    },

    handleMouseMove() {
      const stage = this.$refs.stage.getStage();
      const pointerPos = stage.getPointerPosition();
      this.mousePosition = pointerPos;

      if (this.isDragging && this.selectedId && this.currentTool === 'arrow') {
        const dx = pointerPos.x - this.dragStartPos.x
        const dy = pointerPos.y - this.dragStartPos.y

        const selectedRect = this.rectangles.find(r => r.id === this.selectedId)
        if (selectedRect) {
          selectedRect.x += dx
          selectedRect.y += dy
        }

        const selectedPoint = this.points.find(p => p.id === this.selectedId)
        if (selectedPoint) {
          selectedPoint.x += dx
          selectedPoint.y += dy
        }

        this.dragStartPos = pointerPos
        return
      }

      if (!this.isDrawing || this.currentTool !== 'rectangle') return;

      this.rectangleSize = {
        width: pointerPos.x - this.rectangleStart.x,
        height: pointerPos.y - this.rectangleStart.y
      };
    },

    async handleMouseUp() {
      if (this.resizing) {
        this.resizing = false;
        return;
      }

      if (this.isDragging) {
        this.isDragging = false;
        
        // Mettre à jour la position dans le store après le drag
        if (this.selectedId) {
          const selectedRect = this.rectangles.find(r => r.id === this.selectedId)
          if (selectedRect) {
            // Convertir les coordonnées d'affichage en coordonnées réelles
            const realX = Math.round((selectedRect.x - this.position.x) * this.scaleX)
            const realY = Math.round((selectedRect.y - this.position.y) * this.scaleY)
            const realWidth = Math.round(selectedRect.width * this.scaleX)
            const realHeight = Math.round(selectedRect.height * this.scaleY)
            
            // Mettre à jour l'annotation dans le store
            this.annotationStore.updateAnnotation(this.currentFrameNumber, this.selectedId, {
              x: realX,
              y: realY,
              width: realWidth,
              height: realHeight
            })
          }
          
          const selectedPoint = this.points.find(p => p.id === this.selectedId)
          if (selectedPoint) {
            // Convertir les coordonnées d'affichage en coordonnées réelles
            const realX = Math.round((selectedPoint.x - this.position.x) * this.scaleX)
            const realY = Math.round((selectedPoint.y - this.position.y) * this.scaleY)
            
            // Mettre à jour l'annotation dans le store
            this.annotationStore.updateAnnotation(this.currentFrameNumber, this.selectedId, {
              x: realX,
              y: realY
            })
          }
        }
        return;
      }

      if (!this.isDrawing || this.currentTool !== 'rectangle') return;

      // Normaliser les coordonnées du rectangle pour s'assurer que x, y est le coin supérieur gauche
      // et que width, height sont positifs
      let normalizedRect = this.normalizeRectangle(
        this.rectangleStart.x,
        this.rectangleStart.y,
        this.rectangleSize.width,
        this.rectangleSize.height
      );
      
      const relativeStart = {
        x: normalizedRect.x - this.position.x,
        y: normalizedRect.y - this.position.y
      };

      // Utiliser les dimensions réelles de la vidéo originale, pas du proxy
      const originalRect = {
        x: Math.round(relativeStart.x * this.scaleX),
        y: Math.round(relativeStart.y * this.scaleY),
        width: Math.round(normalizedRect.width * this.scaleX),
        height: Math.round(normalizedRect.height * this.scaleY)
      };

      // Vérifier s'il existe déjà des annotations pour cet objet sur cette frame
      const existingAnnotations = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber)
        .filter(annotation => annotation.objectId === this.annotationStore.selectedObjectId);
      
      // Si des annotations existent déjà, les supprimer avant d'ajouter la nouvelle
      if (existingAnnotations.length > 0) {
        console.log(`Suppression de ${existingAnnotations.length} annotations existantes pour l'objet ${this.annotationStore.selectedObjectId}`);
        existingAnnotations.forEach(annotation => {
          this.annotationStore.removeAnnotation(this.currentFrameNumber, annotation.id);
        });
      }

      // Créer l'annotation avec les coordonnées réelles
      const annotation = {
        objectId: this.annotationStore.selectedObjectId,
        type: 'rectangle',
        x: originalRect.x,
        y: originalRect.y,
        width: originalRect.width,
        height: originalRect.height
      };

      // Ajouter l'annotation au store
      const annotationId = this.annotationStore.addAnnotation(this.currentFrameNumber, annotation);

      // Log détaillé pour le mode annotation uniquement
      console.log('Rectangle ajouté à la frame', this.currentFrameNumber, 'avec ID:', annotationId, ':', annotation);
      console.log('État actuel des annotations:', JSON.parse(JSON.stringify(this.annotationStore.frameAnnotations)));

      this.isDrawing = false;
      this.rectangleSize = { width: 0, height: 0 };
    },

    // Ajouter cette nouvelle méthode pour normaliser les coordonnées du rectangle
    normalizeRectangle(x, y, width, height) {
      // Si la largeur est négative, ajuster x et width
      let newX = x;
      let newWidth = width;
      if (width < 0) {
        newX = x + width;
        newWidth = Math.abs(width);
      }
      
      // Si la hauteur est négative, ajuster y et height
      let newY = y;
      let newHeight = height;
      if (height < 0) {
        newY = y + height;
        newHeight = Math.abs(height);
      }
      
      return {
        x: newX,
        y: newY,
        width: newWidth,
        height: newHeight
      };
    },

    isInsideImage(point) {
      return point.x >= this.position.x && 
             point.x <= this.position.x + this.imageWidth &&
             point.y >= this.position.y && 
             point.y <= this.position.y + this.imageHeight
    },

    addPoint(pos, type) {
      if (!this.annotationStore.selectedObjectId) {
        this.annotationStore.addObject()
      }
      
      const relativeX = pos.x - this.position.x
      const relativeY = pos.y - this.position.y
      
      // Utiliser les dimensions réelles de la vidéo originale, pas du proxy
      const imageX = Math.round(relativeX * this.scaleX)
      const imageY = Math.round(relativeY * this.scaleY)
      
      // Vérifier s'il existe des rectangles pour cet objet sur cette frame
      const existingRectangles = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber)
        .filter(annotation => 
          annotation.objectId === this.annotationStore.selectedObjectId && 
          annotation.type === 'rectangle'
        );
      
      // Si des rectangles existent, les supprimer avant d'ajouter le point
      if (existingRectangles.length > 0) {
        console.log(`Suppression de ${existingRectangles.length} rectangles existants pour l'objet ${this.annotationStore.selectedObjectId}`);
        existingRectangles.forEach(rectangle => {
          this.annotationStore.removeAnnotation(this.currentFrameNumber, rectangle.id);
        });
        
        // Supprimer également les masques associés à ces rectangles
        const associatedMasks = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber)
          .filter(annotation => 
            annotation.objectId === this.annotationStore.selectedObjectId && 
            annotation.type === 'mask' && 
            (!annotation.points || annotation.points.length === 0)
          );
        
        associatedMasks.forEach(mask => {
          this.annotationStore.removeAnnotation(this.currentFrameNumber, mask.id);
        });
      }
      
      // Créer directement une annotation pour le point (comme pour les rectangles)
      const annotation = {
        objectId: this.annotationStore.selectedObjectId,
        type: 'point',
        x: imageX,
        y: imageY,
        pointType: type
      };
      
      // Ajouter l'annotation au store
      const annotationId = this.annotationStore.addAnnotation(this.currentFrameNumber, annotation);
      
      // Log détaillé
      console.log('Point ajouté à la frame', this.currentFrameNumber, 'avec ID:', annotationId, ':', annotation);
      console.log('État des frameAnnotations après ajout:', JSON.parse(JSON.stringify(this.annotationStore.frameAnnotations)));
    },

    handleKeyDown(e) {
      // Raccourci pour supprimer un élément sélectionné (annotations uniquement)
      // Note: Pour supprimer un objet, utiliser Ctrl+Suppr dans la liste des objets
      if (e.key === 'Delete' && this.selectedId) {
        console.log('Tentative de suppression de l\'élément:', this.selectedId)
        
        // Déterminer le type d'élément sélectionné
        const selectedRect = this.rectangles.find(r => r.id === this.selectedId);
        const selectedPoint = this.points.find(p => p.id === this.selectedId);
        
        if (selectedRect) {
          console.log('Suppression du rectangle:', this.selectedId)
          // Supprimer le rectangle
          this.annotationStore.removeAnnotation(this.currentFrameNumber, this.selectedId);
          
          // Vérifier s'il reste des annotations pour cet objet sur cette frame
          this.checkAndCleanupMasks(selectedRect.objectId);
        } 
        else if (selectedPoint) {
          console.log('Suppression du point:', this.selectedId, 'Type:', selectedPoint.isDirect ? 'direct' : 'depuis annotation')
          
          if (selectedPoint.isTemporary) {
            // Supprimer un point temporaire
            this.annotationStore.removeTemporaryPoint(selectedPoint.id.replace('temp-point-', ''));
          } else if (selectedPoint.isDirect) {
            // Nouveau système : point direct - supprimer directement l'annotation
            this.annotationStore.removeAnnotation(this.currentFrameNumber, this.selectedId);
            console.log('Point direct supprimé')
          } else {
            // Ancien système : point d'une annotation existante
            const annotationId = selectedPoint.fromAnnotation;
            const annotation = this.annotationStore.getAnnotation(this.currentFrameNumber, annotationId);
            
            if (annotation && annotation.points) {
              // Filtrer les points pour retirer celui qui est sélectionné
              const pointKey = selectedPoint.id.split('-point-')[1]; // Récupérer les coordonnées du point
              const [pointX, pointY] = pointKey.split('-').map(Number);
              
              const updatedPoints = annotation.points.filter(p => 
                !(p.x === pointX && p.y === pointY)
              );
              
              if (updatedPoints.length > 0) {
                // Mettre à jour l'annotation avec les points restants
                this.annotationStore.updateAnnotation(this.currentFrameNumber, annotationId, {
                  points: updatedPoints
                });
                console.log('Point retiré de l\'annotation, points restants:', updatedPoints.length)
              } else {
                // Si plus aucun point, supprimer l'annotation complètement
                this.annotationStore.removeAnnotation(this.currentFrameNumber, annotationId);
                console.log('Annotation complètement supprimée (plus de points)')
              }
              
              // Vérifier s'il reste des annotations pour cet objet sur cette frame
              this.checkAndCleanupMasks(selectedPoint.objectId);
            }
          }
        } else {
          console.log('Aucun élément trouvé avec l\'ID:', this.selectedId)
        }
        
        this.selectedId = null;
        console.log('Element deleted');
      }
      
      // Raccourci "v" supprimé - Les points sont maintenant sauvegardés directement
      
      // Raccourci Escape supprimé - Plus de points temporaires à annuler
      
      // Raccourci pour basculer l'affichage des bounding boxes (touche 'b')
      if (e.key === 'b' || e.key === 'B') {
        e.preventDefault();
        this.toggleBoundingBoxes();
      }
      
      // Raccourci pour déboguer les bounding boxes (touche 'd')
      if (e.key === 'd' || e.key === 'D') {
        e.preventDefault();
        this.debugBoundingBoxes();
      }
      
      // Navigation frame par frame avec les flèches
      if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
        e.preventDefault() // Empêcher le défilement de la page
        
        // Calculer la nouvelle frame
        const frameRate = this.annotationStore.currentSession.frameRate || 30
        const currentFrame = this.currentFrameNumber
        const newFrame = e.key === 'ArrowLeft' ? Math.max(0, currentFrame - 1) : currentFrame + 1
        
        // Calculer le nouveau temps basé sur la frame
        const newTime = newFrame / frameRate
        
        // Mettre à jour le temps dans le store et la vidéo
        this.videoStore.setCurrentTime(newTime)
        if (this.videoElement) {
          this.videoElement.currentTime = newTime
        }
        
        // console.log(`Navigation: Frame ${currentFrame} -> ${newFrame}, Temps: ${newTime.toFixed(3)}s`)
      }
    },

    // Nouvelle méthode pour vérifier et nettoyer les masques orphelins
    checkAndCleanupMasks(objectId) {
      const frameAnnotations = this.annotationStore.getAnnotationsForFrame(this.currentFrameNumber) || [];
      
      // Vérifier s'il reste des annotations (rectangles ou points) pour cet objet sur cette frame
      const hasRemainingElements = frameAnnotations.some(annotation => 
        annotation.objectId === objectId && 
        (annotation.type === 'rectangle' || 
         (annotation.type === 'mask' && annotation.points && annotation.points.length > 0))
      );
      
      if (!hasRemainingElements) {
        // Si aucun élément ne reste, supprimer tous les masques associés à cet objet sur cette frame
        const masksToRemove = frameAnnotations
          .filter(annotation => 
            annotation.objectId === objectId && 
            annotation.type === 'mask' && 
            (!annotation.points || annotation.points.length === 0)
          )
          .map(annotation => annotation.id);
        
        masksToRemove.forEach(maskId => {
          this.annotationStore.removeAnnotation(this.currentFrameNumber, maskId);
        });
        
        if (masksToRemove.length > 0) {
          console.log(`Suppression de ${masksToRemove.length} masques orphelins pour l'objet ${objectId}`);
        }
      }
    },

    getResizeHandles() {
      const rect = this.rectangles.find(r => r.id === this.selectedId)
      if (!rect) return []

      return [
        { position: 'nw', x: rect.x, y: rect.y },
        { position: 'ne', x: rect.x + rect.width, y: rect.y },
        { position: 'se', x: rect.x + rect.width, y: rect.y + rect.height },
        { position: 'sw', x: rect.x, y: rect.y + rect.height },
        
        { position: 'n', x: rect.x + rect.width/2, y: rect.y },
        { position: 'e', x: rect.x + rect.width, y: rect.y + rect.height/2 },
        { position: 's', x: rect.x + rect.width/2, y: rect.y + rect.height },
        { position: 'w', x: rect.x, y: rect.y + rect.height/2 }
      ]
    },

    handleResize(e, position) {
      const rect = this.rectangles.find(r => r.id === this.selectedId)
      if (!rect) return

      const stage = this.$refs.stage.getStage()
      const pos = stage.getPointerPosition()

      const originalX = rect.x
      const originalY = rect.y
      const originalWidth = rect.width
      const originalHeight = rect.height
      let newWidth, newHeight

      // Appliquer le redimensionnement selon la poignée utilisée
      switch (position) {
        case 'e':
          rect.width = Math.max(10, pos.x - rect.x)
          break
        case 'w':
          newWidth = originalWidth + (originalX - pos.x)
          if (newWidth >= 10) {
            rect.x = pos.x
            rect.width = newWidth
          }
          break
        case 'n':
          newHeight = originalHeight + (originalY - pos.y)
          if (newHeight >= 10) {
            rect.y = pos.y
            rect.height = newHeight
          }
          break
        case 's':
          rect.height = Math.max(10, pos.y - rect.y)
          break
        case 'nw':
          if (originalWidth + (originalX - pos.x) >= 10) {
            rect.x = pos.x
            rect.width = originalWidth + (originalX - pos.x)
          }
          if (originalHeight + (originalY - pos.y) >= 10) {
            rect.y = pos.y
            rect.height = originalHeight + (originalY - pos.y)
          }
          break
        case 'ne':
          rect.width = Math.max(10, pos.x - rect.x)
          if (originalHeight + (originalY - pos.y) >= 10) {
            rect.y = pos.y
            rect.height = originalHeight + (originalY - pos.y)
          }
          break
        case 'se':
          rect.width = Math.max(10, pos.x - rect.x)
          rect.height = Math.max(10, pos.y - rect.y)
          break
        case 'sw':
          if (originalWidth + (originalX - pos.x) >= 10) {
            rect.x = pos.x
            rect.width = originalWidth + (originalX - pos.x)
          }
          rect.height = Math.max(10, pos.y - rect.y)
          break
      }
      
      // Convertir les coordonnées d'affichage en coordonnées réelles
      const realX = Math.round((rect.x - this.position.x) * this.scaleX)
      const realY = Math.round((rect.y - this.position.y) * this.scaleY)
      const realWidth = Math.round(rect.width * this.scaleX)
      const realHeight = Math.round(rect.height * this.scaleY)
      
      // Mettre à jour l'annotation dans le store avec les coordonnées réelles
      this.annotationStore.updateAnnotation(this.currentFrameNumber, this.selectedId, {
        x: realX,
        y: realY,
        width: realWidth,
        height: realHeight
      })
    },

    updateCurrentFrame() {
      if (!this.videoElement) return
      
      const frameRate = this.annotationStore.currentSession.frameRate || 30
      
      // Utiliser Math.round au lieu de Math.floor pour une meilleure précision
      const newFrameNumber = Math.round(this.videoElement.currentTime * frameRate)
      
      // Ne mettre à jour que si la frame a changé
      if (newFrameNumber !== this.currentFrameNumber) {
        this.currentFrameNumber = newFrameNumber
        
        // Forcer le rafraîchissement du canvas pour s'assurer que seules les annotations
        // de la frame actuelle sont affichées
        if (this.$refs.layer) {
          const layer = this.$refs.layer.getNode()
          layer.batchDraw()
        }
        
        // Debug des bounding boxes pour la nouvelle frame
        this.$nextTick(() => {
          this.debugBoundingBoxes()
        })
        
        // Log pour débogage
        // console.log(`Temps: ${this.videoElement.currentTime.toFixed(3)}s, Frame: ${this.currentFrameNumber}`)
      }
    },

    selectObject(objectId) {
      this.annotationStore.selectObject(objectId)
      this.$emit('object-selected', objectId)
    },

    createNewObject() {
      this.annotationStore.addObject()
    },

    animate() {
      // Récupérer les éléments sélectionnés
      if (this.$refs.layer && this.annotationStore.selectedObjectId) {
        const layer = this.$refs.layer.getNode();
        
        // Trouver tous les éléments de l'objet sélectionné
        const selectedRects = layer.find('Rect').filter(rect => {
          return rect.attrs.objectId === this.annotationStore.selectedObjectId;
        });
        
        const selectedPoints = layer.find('Group').filter(group => {
          return group.attrs.objectId === this.annotationStore.selectedObjectId;
        });
        
        // Appliquer l'animation
        [...selectedRects, ...selectedPoints].forEach(shape => {
          // Animation de pulsation
          const scale = 1 + Math.sin(Date.now() / 300) * 0.05; // Pulsation subtile
          shape.scale({ x: scale, y: scale });
        });
        
        layer.batchDraw();
      }
      
      // Continuer l'animation
      this.animationId = requestAnimationFrame(this.animate);
    },

    getObjectColor(objectId) {
      const object = this.annotationStore.objects[objectId];
      return object ? object.color : '#CCCCCC';
    },
    
    handleMaskClick(maskId, e) {
      // Empêcher la propagation pour éviter que handleMouseDown ne soit aussi appelé
      if (e && e.evt) {
        e.evt.stopPropagation(); // Remplacer cancelBubble par stopPropagation
      }
      
      // Sélectionner le masque
      this.selectedId = maskId;
      
      console.log('Selected mask:', maskId);
    },
    
    drawMask(context, shape, annotation) {
      if (!annotation.mask || !annotation.maskImageSize) {
        console.warn('Annotation sans masque ou dimensions:', annotation);
        return;
      }
      
      // Vérifier si le masque est déjà dans le cache
      const cacheKey = `${annotation.id}-${annotation.mask.substring(0, 20)}`;
      let maskImage = this.maskCache[cacheKey];
      
      if (!maskImage) {
        try {
          console.log(`Décodage du masque pour l'annotation ${annotation.id}`);
          console.log('Début du masque:', annotation.mask.substring(0, 50) + '...');
          
          // Créer une nouvelle image pour charger le masque base64
          maskImage = new Image();
          
          // Attendre que l'image soit chargée avant de continuer
          const loadPromise = new Promise((resolve, reject) => {
            maskImage.onload = () => resolve();
            maskImage.onerror = (e) => reject(new Error(`Erreur de chargement de l'image: ${e}`));
          });
          
          // Définir la source de l'image (base64)
          if (annotation.mask.startsWith('data:')) {
            // Si c'est déjà un data URL
            maskImage.src = annotation.mask;
          } else {
            // Sinon, supposer que c'est un base64 brut et créer un data URL
            maskImage.src = `data:image/png;base64,${annotation.mask}`;
          }
          
          // Attendre que l'image soit chargée
          loadPromise.then(() => {
            console.log(`Image du masque chargée: ${maskImage.width}x${maskImage.height}`);
            
            // Créer un canvas temporaire pour traiter l'image
            const tempCanvas = document.createElement('canvas');
            tempCanvas.width = maskImage.width;
            tempCanvas.height = maskImage.height;
            const tempCtx = tempCanvas.getContext('2d');
            
            // Dessiner l'image sur le canvas temporaire
            tempCtx.drawImage(maskImage, 0, 0);
            
            // Obtenir les données de l'image
            const imageData = tempCtx.getImageData(0, 0, maskImage.width, maskImage.height);
            const data = imageData.data;
            
            // Obtenir la couleur de l'objet
            const objectColor = this.getObjectColor(annotation.objectId);
            const r = parseInt(objectColor.slice(1, 3), 16);
            const g = parseInt(objectColor.slice(3, 5), 16);
            const b = parseInt(objectColor.slice(5, 7), 16);
            
            // Parcourir tous les pixels
            for (let i = 0; i < data.length; i += 4) {
              // Si le pixel est blanc (ou presque blanc)
              if (data[i] > 200 && data[i+1] > 200 && data[i+2] > 200) {
                // Remplacer par la couleur de l'objet avec une transparence
                data[i] = r;
                data[i+1] = g;
                data[i+2] = b;
                data[i+3] = 180; // Semi-transparent
              } else {
                // Rendre le pixel complètement transparent
                data[i+3] = 0;
              }
            }
            
            // Remettre les données modifiées dans le canvas
            tempCtx.putImageData(imageData, 0, 0);
            
            // Créer une nouvelle image à partir du canvas modifié
            const coloredMaskImage = new Image();
            coloredMaskImage.src = tempCanvas.toDataURL();
            
            // Mettre en cache l'image colorée
            this.maskCache[cacheKey] = coloredMaskImage;
            
            // Forcer un nouveau rendu
            this.$nextTick(() => {
              if (this.$refs.layer) {
                this.$refs.layer.getNode().batchDraw();
              }
            });
          }).catch(error => {
            console.error('Erreur lors du traitement de l\'image du masque:', error);
          });
          
          // Retourner tôt car l'image n'est pas encore chargée
          return;
        } catch (error) {
          console.error('Erreur lors de la création de l\'image du masque:', error);
          return;
        }
      }
      
      // Si l'image n'est pas encore complètement chargée, retourner
      if (!maskImage.complete) {
        return;
      }
      
      // Calculer l'échelle pour adapter le masque à la taille d'affichage
      const scaleX = this.imageWidth / annotation.maskImageSize.width;
      const scaleY = this.imageHeight / annotation.maskImageSize.height;
      
      // Dessiner le masque sur le canvas principal
      const ctx = context._context;
      ctx.save();
      
      // Appliquer la transformation pour positionner correctement le masque
      ctx.translate(this.position.x, this.position.y);
      ctx.scale(scaleX, scaleY);
      
      // Dessiner l'image du masque coloré
      ctx.drawImage(maskImage, 0, 0);
      
      // Restaurer le contexte
      ctx.restore();
      
      // Indiquer à Konva que le dessin est terminé
      shape.strokeEnabled(false); // Désactiver le contour automatique
    },

    handleShapeMouseDown(e, shapeId) {
      // Empêcher la propagation pour éviter que handleMouseDown ne soit aussi appelé
      e.evt.stopPropagation(); // Remplacer cancelBubble par stopPropagation
      
      // Sélectionner la forme
      this.selectedId = shapeId;
      
      // Si l'outil actuel est la flèche, activer le mode de déplacement
      if (this.currentTool === 'arrow') {
        this.isDragging = true;
        
        const stage = this.$refs.stage.getStage();
        this.dragStartPos = stage.getPointerPosition();
        
        console.log('Selected shape:', shapeId);
      }
    },

    // Ajouter cette méthode pour gérer l'ajout de points à un masque existant
    addPointToExistingMask(pos, type) {
      if (!this.annotationStore.selectedObjectId) {
        this.annotationStore.addObject();
      }
      
      const relativeX = pos.x - this.position.x;
      const relativeY = pos.y - this.position.y;
      
      // Utiliser les dimensions réelles de la vidéo originale
      const imageX = Math.round(relativeX * this.scaleX);
      const imageY = Math.round(relativeY * this.scaleY);
      
      // Ajouter le point à la collection temporaire
      this.annotationStore.addTemporaryPoint({
        objectId: this.annotationStore.selectedObjectId,
        x: imageX,
        y: imageY,
        pointType: type
      });
      
      console.log('Point temporaire ajouté:', { x: imageX, y: imageY, type });
    },

    // Nouvelle méthode pour basculer l'affichage des bounding boxes
    toggleBoundingBoxes() {
      this.showAllBoundingBoxes = !this.showAllBoundingBoxes;
      console.log('Affichage des bounding boxes:', this.showAllBoundingBoxes ? 'activé' : 'désactivé');
    },

    // Méthode de débogage pour afficher les informations des bounding boxes
    debugBoundingBoxes() {
      const boxes = this.allBoundingBoxes;
      if (boxes.length > 0) {
        console.log(`🔍 Frame ${this.currentFrameNumber}: ${boxes.length} bounding box(es) trouvée(s)`);
        
        const currentBoxes = boxes.filter(b => b.source === 'current');
        
        if (currentBoxes.length > 0) {
          console.log(`  ✏️ Annotations en cours: ${currentBoxes.length}`);
          currentBoxes.forEach(box => {
            console.log(`    - ${box.name} (${box.type}): x=${Math.round(box.x)}, y=${Math.round(box.y)}, w=${Math.round(box.width)}, h=${Math.round(box.height)}`);
          });
        }
      }
    },

    // Nouvelle méthode pour gérer les clics sur les points
    handlePointClick(pointId, e) {
      // Empêcher la propagation pour éviter que handleMouseDown ne soit aussi appelé
      e.evt.stopPropagation()
      
      // Sélectionner le point
      this.selectedId = pointId
      
      // Si l'outil actuel est la flèche, activer le mode de déplacement
      if (this.currentTool === 'arrow') {
        this.isDragging = true
        const stage = this.$refs.stage.getStage()
        this.dragStartPos = stage.getPointerPosition()
      }
      
      console.log('Selected point via direct click:', pointId)
    },
  },

  watch: {
    'stageConfig.width'() {
      this.$nextTick(() => {
        this.updateDimensions()
      })
    },
    'stageConfig.height'() {
      this.$nextTick(() => {
        this.updateDimensions()
      })
    },
    'videoStore.currentTime'() {
      this.updateCurrentFrame()
    },
    'annotationStore.selectedObjectId'(newId) {
      console.log('Objet sélectionné changé:', newId)
      // Redémarrer l'animation quand l'objet sélectionné change
      this.startAnimation()
    },
    currentFrameNumber() {
      // Forcer le rafraîchissement du canvas quand la frame change
      this.$nextTick(() => {
        if (this.$refs.layer) {
          const layer = this.$refs.layer.getNode()
          layer.batchDraw()
        }
      })
    }
  },
}
</script>

<style scoped>
.video-section {
  width: 100%;
  height: 100%;
  display: flex;
  gap: 8px;
}

.video-container {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.video-wrapper, .canvas-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.video-wrapper {
  z-index: 1;
}

.canvas-wrapper {
  z-index: 999;
}

.video-element {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  z-index: 1;
}

.canvas-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
  background: transparent;
  pointer-events: auto;
}

.tool-btn {
  width: 34px;
  height: 34px;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.tool-btn:hover {
  background: #4a4a4a;
}

.tool-btn.active {
  background: #3a3a3a;
  color: white;
}

.tool-btn svg {
  width: 20px;
  height: 20px;
  stroke-width: 2;
}

.tool-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  background: transparent;
}

.tool-btn:not(:disabled):hover {
  background: #4a4a4a;
}

.pulse-animation {
  animation: pulse 1.5s infinite ease-in-out;
}

.spinner {
  width: 20px;
  height: 20px;
  border: 3px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: white;
  animation: spin 1s ease-in-out infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
</style> 