<template>

  <div class="scene" id="scene">
    <div class="box" id="box">
      <div class="face front">
        <img class="cover" src="https://evilspins.com/ES01A/object.png" alt="">
      </div>
      <div class="face back"></div>
      <div class="face right"></div>
      <div class="face left"></div>
      <div class="face top"></div>
      <div class="face bottom"></div>
    </div>
  </div>
</template>

<script setup>
/*
  Rotation 3D au touch / clic maintenu
  - Utilise Pointer Events (fonctionne pour souris, stylet, touch)
  - rotateX et rotateY mis à jour pendant le drag
  - inertie légère à la release (configurable)
*/

(function () {
  const box = document.getElementById('box');
  const scene = document.getElementById('scene');

  // état
  let angleX = -20; // angle initial (pour montrer la 3D)
  let angleY = 20;
  let dragging = false;
  let lastPointer = { x: 0, y: 0, time: 0 };
  let velocity = { x: 0, y: 0 };
  let raf = null;

  // paramètres
  const sensitivity = 0.3;    // combien de degrés par px
  const friction = 0.95;      // inertie (0..1) ; 1 = pas de friction
  const minVelocity = 0.02;   // seuil pour arrêter l'inertie
  const enableInertia = true; // tu peux mettre false pour pas d'inertie

  // applique la transformation (raf-friendly)
  function applyTransform() {
    box.style.transform = `rotateX(${angleX}deg) rotateY(${angleY}deg)`;
  }

  applyTransform();

  // boucle d'inertie
  function tickInertia() {
    if (!enableInertia) return;
    // appliquer friction
    velocity.x *= friction;
    velocity.y *= friction;

    angleX += velocity.y;
    angleY += velocity.x;

    // clamp angleX pour éviter flip complet (optionnel)
    angleX = Math.max(-80, Math.min(80, angleX));

    applyTransform();

    if (Math.abs(velocity.x) > minVelocity || Math.abs(velocity.y) > minVelocity) {
      raf = requestAnimationFrame(tickInertia);
    } else {
      raf = null;
    }
  }

  // pointerdown
  scene.addEventListener('pointerdown', (ev) => {
    ev.preventDefault();
    dragging = true;
    scene.setPointerCapture(ev.pointerId);
    lastPointer.x = ev.clientX;
    lastPointer.y = ev.clientY;
    lastPointer.time = performance.now();
    velocity.x = 0;
    velocity.y = 0;
    if (raf) { cancelAnimationFrame(raf); raf = null; } // stop inertie en commençant un nouveau drag
  });

  // pointermove
  scene.addEventListener('pointermove', (ev) => {
    if (!dragging) return;
    ev.preventDefault();
    const now = performance.now();
    const dx = ev.clientX - lastPointer.x;
    const dy = ev.clientY - lastPointer.y;

    // mise à jour angles (inverser si tu veux sens différent)
    angleY += dx * sensitivity;
    angleX -= dy * sensitivity;

    // clamp angleX
    angleX = Math.max(-80, Math.min(80, angleX));

    // calculer vitesse (px per frame approximative)
    const dt = Math.max(1, now - lastPointer.time); // ms
    velocity.x = (dx / dt) * 16 * sensitivity; // normalisé approximativement à 60fps
    velocity.y = (-dy / dt) * 16 * sensitivity;

    lastPointer.x = ev.clientX;
    lastPointer.y = ev.clientY;
    lastPointer.time = now;

    applyTransform();
  });

  // pointerup / cancel
  const endDrag = (ev) => {
    if (!dragging) return;
    dragging = false;
    try { scene.releasePointerCapture(ev.pointerId); } catch (e) { }
    // si inertie activée, lancer la boucle
    if (enableInertia && (Math.abs(velocity.x) > minVelocity || Math.abs(velocity.y) > minVelocity)) {
      if (!raf) raf = requestAnimationFrame(tickInertia);
    }
  };

  scene.addEventListener('pointerup', endDrag);
  scene.addEventListener('pointercancel', endDrag);
  scene.addEventListener('pointerleave', endDrag); // utile sur desktop si tu sors du container

  // accessibility : permettre rotation via clavier (optionnel)
  scene.tabIndex = 0;
  scene.addEventListener('keydown', (e) => {
    const step = 8;
    if (e.key === 'ArrowLeft') { angleY -= step; applyTransform(); }
    if (e.key === 'ArrowRight') { angleY += step; applyTransform(); }
    if (e.key === 'ArrowUp') { angleX -= step; applyTransform(); }
    if (e.key === 'ArrowDown') { angleX += step; applyTransform(); }
  });

})();
</script>

<style>
/*  H      W   D
    k7  5   :  8 : 1
    CD  12  : 14 : 1
    VHS 4.5 :  8 : 1
    DVD 14  : 10 : 1
    */

:root {
  --size: 100px;
  --height: 150px;
  --width: 150px;
  --depth: 10px;
  --bg: #0f172a;
}

html,
body {
  height: 100%;
  margin: 0;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: system-ui, Segoe UI, Roboto, Helvetica, Arial;
  -webkit-font-smoothing: antialiased;
}

/* scène avec perspective */
.scene {
  width: calc(var(--height) * 1.2);
  height: calc(var(--width) * 1.2);
  perspective: 1000px;
  touch-action: none;
  /* essentiel pour empêcher le scroll pendant le drag */
}

/* l'objet 3D (box simple) */
.box {
  width: var(--width);
  height: var(--height);
  position: relative;
  transform-style: preserve-3d;
  transition: transform 120ms linear;
  /* légère smoothing quand on lâche */
  margin: auto;
  user-select: none;
  cursor: grab;
}

.box:active {
  cursor: grabbing;
}

/* faces du box */
.face {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  color: white;
  font-weight: 600;
  backface-visibility: hidden;
  border: 2px solid rgba(255, 255, 255, 0.06);
  box-sizing: border-box;
  transform-origin: top right;
}

.front,
.back {
  width: 100%;
  height: 100%;
}

.face.top,
.face.bottom {
  width: var(--width);
  height: var(--depth);
}

.face.left,
.face.right {
  width: var(--depth);
  height: var(--height);
}

.face.front {
  background: linear-gradient(180deg, #2563eb, #7dd3fc);
  transform: translateX(0px) translateY(0px) translateZ(0px);
}

.face.back {
  background: linear-gradient(180deg, #7c3aed, #a78bfa);
  transform: rotateY(180deg) translateX(var(--width)) translateY(0px) translateZ(var(--depth));
}

.face.right {
  background: linear-gradient(180deg, #10b981, #6ee7b7);
  transform: rotateY(90deg) translateX(0px) translateY(0px) translateZ(var(--width));
  transform-origin: top left;
}

.face.left {
  background: linear-gradient(180deg, #ef4444, #fca5a5);
  transform: rotateY(-90deg) translateX(0) translateY(0px) translateZ(var(--depth));
}

.face.top {
  background: linear-gradient(180deg, #f59e0b, #fcd34d);
  transform: rotateX(90deg) translateX(0px) translateY(calc(var(--depth) * -1)) translateZ(0px);
}

.face.bottom {
  background: linear-gradient(180deg, #06b6d4, #67e8f9);
  transform: rotateX(-90deg) translateX(0) translateY(0px) translateZ(calc(var(--height)));
}

.cover {
  height: 100%;
  width: 100%;
  object-fit: cover;
}
</style>