// 3D dice renderer with physics bounce & spin animation

const DIE_SIZE = 38;
const DOT_RADIUS = 3.5;

export function drawDice(ctx, x, y, values, options = {}) {
  const { used = [], rolling = false, frame = 0, totalFrames = 24 } = options;

  for (let i = 0; i < values.length; i++) {
    const dx = x + i * (DIE_SIZE + 12);
    const val = rolling ? Math.floor(Math.random() * 6) + 1 : values[i];
    const isUsed = used.includes(i);

    // Stagger animation per die
    const dieFrame = rolling ? Math.max(0, frame - i * 3) : 0;
    drawSingleDie(ctx, dx, y, val, isUsed, dieFrame, totalFrames);
  }
}

function drawSingleDie(ctx, x, y, value, isUsed, frame, totalFrames) {
  const t = frame > 0 ? frame / totalFrames : 0;

  // Physics: bounce with damping
  const bounceY = frame > 0 ? -Math.abs(Math.sin(t * Math.PI * 3)) * 12 * (1 - t) : 0;
  const rotation = frame > 0 ? t * Math.PI * 6 * (1 - t * 0.5) : 0;
  const scale = frame > 0 ? 1 + Math.sin(t * Math.PI) * 0.15 : 1;

  ctx.save();
  ctx.translate(x + DIE_SIZE / 2, y + DIE_SIZE / 2 + bounceY);
  ctx.rotate(rotation);
  ctx.scale(scale, scale);
  ctx.translate(-DIE_SIZE / 2, -DIE_SIZE / 2);

  // Shadow (moves with bounce)
  if (!isUsed) {
    const shadowBlur = 6 + Math.abs(bounceY) * 0.5;
    ctx.shadowColor = 'rgba(0,0,0,0.4)';
    ctx.shadowBlur = shadowBlur;
    ctx.shadowOffsetY = 3 - bounceY * 0.3;
  }

  // Die body — 3D face with gradient
  const bodyGrad = ctx.createLinearGradient(0, 0, DIE_SIZE, DIE_SIZE);
  if (isUsed) {
    bodyGrad.addColorStop(0, 'rgba(180, 180, 180, 0.35)');
    bodyGrad.addColorStop(1, 'rgba(140, 140, 140, 0.25)');
  } else {
    bodyGrad.addColorStop(0, '#FFFEF5');
    bodyGrad.addColorStop(0.4, '#FFF8E8');
    bodyGrad.addColorStop(1, '#F0E0C0');
  }
  ctx.fillStyle = bodyGrad;
  roundRect(ctx, 0, 0, DIE_SIZE, DIE_SIZE, 6);
  ctx.fill();
  ctx.shadowBlur = 0;
  ctx.shadowOffsetY = 0;

  // Border
  ctx.strokeStyle = isUsed ? 'rgba(150,150,150,0.3)' : '#8B6914';
  ctx.lineWidth = isUsed ? 1 : 1.5;
  roundRect(ctx, 0, 0, DIE_SIZE, DIE_SIZE, 6);
  ctx.stroke();

  // Inner edge highlight (3D effect)
  if (!isUsed) {
    ctx.strokeStyle = 'rgba(255,255,255,0.4)';
    ctx.lineWidth = 1;
    roundRect(ctx, 1.5, 1.5, DIE_SIZE - 3, DIE_SIZE - 3, 5);
    ctx.stroke();
  }

  if (isUsed) ctx.globalAlpha = 0.35;

  // Dots with slight shadow
  const dotColor = isUsed ? '#666' : '#1A0800';
  const positions = getDotPositions(value, DIE_SIZE);
  for (const [dx, dy] of positions) {
    if (!isUsed) {
      ctx.beginPath();
      ctx.arc(dx + 0.5, dy + 0.5, DOT_RADIUS, 0, Math.PI * 2);
      ctx.fillStyle = 'rgba(0,0,0,0.15)';
      ctx.fill();
    }
    ctx.beginPath();
    ctx.arc(dx, dy, DOT_RADIUS, 0, Math.PI * 2);
    ctx.fillStyle = dotColor;
    ctx.fill();
  }

  ctx.restore();
}

function getDotPositions(value, size) {
  const c = size / 2;
  const q1 = size * 0.24;
  const q3 = size * 0.76;

  switch (value) {
    case 1: return [[c, c]];
    case 2: return [[q1, q3], [q3, q1]];
    case 3: return [[q1, q3], [c, c], [q3, q1]];
    case 4: return [[q1, q1], [q1, q3], [q3, q1], [q3, q3]];
    case 5: return [[q1, q1], [q1, q3], [c, c], [q3, q1], [q3, q3]];
    case 6: return [[q1, q1], [q1, c], [q1, q3], [q3, q1], [q3, c], [q3, q3]];
    default: return [[c, c]];
  }
}

function roundRect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.arcTo(x + w, y, x + w, y + h, r);
  ctx.arcTo(x + w, y + h, x, y + h, r);
  ctx.arcTo(x, y + h, x, y, r);
  ctx.arcTo(x, y, x + w, y, r);
  ctx.closePath();
}

export function createRollAnimation(onFrame, onComplete) {
  const totalFrames = 24;
  const duration = 700;
  let startTime = null;

  function tick(now) {
    if (!startTime) startTime = now;
    const elapsed = now - startTime;
    const frame = Math.min(totalFrames, Math.floor((elapsed / duration) * totalFrames));
    onFrame(frame, totalFrames);

    if (elapsed < duration) {
      requestAnimationFrame(tick);
    } else {
      onComplete();
    }
  }
  requestAnimationFrame(tick);
}
