<template>
  <view class="lottery-wheel-container">
    <canvas canvas-id="canvasWheel" id="canvasWheel" :style="{ width: size + 'px', height: size + 'px' }"></canvas>
    <button class="spin-button" @click="startSpin" :disabled="isSpinning">
      {{ isSpinning ? 'Spinning...' : 'Spin' }}
    </button>
  </view>
</template>

<script setup>
import { onMounted, ref, watch } from 'vue';

const props = defineProps({
  prizes: {
    type: Array,
    required: true,
    default: () => []
  },
  size: {
    type: Number,
    default: 300
  },
  duration: {
    type: Number,
    default: 4000
  },
  targetIndex: {
    type: Number,
    default: -1
  }
});

const emit = defineEmits(['spin-end']);
const isSpinning = ref(false);
let currentRotation = 0;

const drawWheel = (rotation = 0) => {


  const context = uni.createCanvasContext('canvasWheel');
  const center = props.size / 2;
  const radius = center - 10;
  const sliceAngle = (2 * Math.PI) / props.prizes.length;

  context.clearRect(0, 0, props.size, props.size);

  // Draw rotating wheel
  context.save();
  context.translate(center, center);
  context.rotate(rotation);
  context.translate(-center, -center);
  // context.fillStyle = '#fff';
  context.strokeStyle = '#FEBF05';
  context.lineWidth = 1;
  // Draw slices
  props.prizes.forEach((prize, index) => {
    context.beginPath();
    context.moveTo(center, center);

    context.arc(
      center,
      center,
      radius,
      index * sliceAngle,
      (index + 1) * sliceAngle
    );
    context.closePath();

    // Alternate colors
    context.setFillStyle(index % 2 === 0 ? '#FF6B6B' : '#4ECDC4');
    context.fill();
    context.stroke();

    // Add text
    context.save();
    context.translate(center, center);
    // Rotate to the middle of the slice
    context.rotate(index * sliceAngle + sliceAngle / 2);
    // Rotate 90 degrees to make text perpendicular
    context.rotate(Math.PI / 2);

    // Text settings
    context.setTextAlign('center');
    context.setTextBaseline('bottom');
    context.setFillStyle('#fff');
    context.setFontSize(12);

    // Split text into lines (for Chinese characters, split every character)
    const maxCharsPerLine = 16;
    const chars = prize.toString().split('');
    let lines = [];
    let currentLine = '';

    // Character wrap logic
    chars.forEach((char, i) => {
      currentLine += char;
      if ((i + 1) % maxCharsPerLine === 0 || i === chars.length - 1) {
        lines.push(currentLine);
        currentLine = '';
      }
    });
    if (currentLine) {
      lines.push(currentLine);
    }

    // Calculate total height of text
    const lineHeight = 16;
    const totalHeight = lines.length * lineHeight;
    const startY = -radius * 0.75; // Start position from the center

    // Draw each line of text
    lines.forEach((line, lineIndex) => {
      const y = startY + lineIndex * lineHeight;
      context.fillText(line, 0, y);
    });

    context.restore();
  });

  // Restore rotation state
  context.restore();

  // Draw center circle
  context.strokeStyle = '#FEBF05';
  context.beginPath();
  context.arc(center, center, 25, 0, 2 * Math.PI);
  context.setFillStyle('#fff');
  context.fill();
  context.stroke();
  context.closePath();

  // Draw fixed pointer in center (after rotation restore)
  context.beginPath();
  context.moveTo(center, center - 25); // Top point
  context.lineTo(center + 10, center); // Right point
  context.lineTo(center - 10, center); // Left point
  context.closePath();
  context.setFillStyle('#FF0000');
  context.fill();
  context.stroke();
  context.draw();
}

const calculateTargetRotation = (targetIndex) => {
  // Calculate base rotation needed to align the target index
  const sliceAngle = (2 * Math.PI) / props.prizes.length;

  // Calculate the angle needed to rotate the target index to 12 o'clock
  // We add Math.PI/2 to start from 12 o'clock (instead of 3 o'clock)
  // We subtract the target index angle to rotate counterclockwise
  // We add sliceAngle/2 to center the slice
  const baseAngle = Math.PI - ((targetIndex - 1) * sliceAngle);

  // Add extra rotations (5-8 full spins)
  const extraRotations = Math.PI * 2 * (5 + Math.floor(Math.random() * 3));

  // Return total rotation (extra rotations + base angle)
  return extraRotations + baseAngle;
};

const startSpin = async () => {
  if (isSpinning.value) return;

  isSpinning.value = true;

  // If targetIndex is provided and valid, use it; otherwise random
  let finalIndex;
  if (props.targetIndex >= 0 && props.targetIndex < props.prizes.length) {
    finalIndex = props.targetIndex;
  } else {
    finalIndex = Math.floor(Math.random() * props.prizes.length);
  }

  const targetRotation = calculateTargetRotation(finalIndex);
  const startTime = Date.now();

  const animate = () => {
    const currentTime = Date.now();
    const elapsed = currentTime - startTime;
    const progress = Math.min(elapsed / props.duration, 1);

    const easedProgress = easeOut(progress);
    const rotation = targetRotation * easedProgress;

    drawWheel(rotation);

    if (progress < 1) {
      setTimeout(animate, 16);
    } else {
      isSpinning.value = false;
      console.log('Final Index:', finalIndex, 'Prize:', props.prizes[finalIndex]);
      emit('spin-end', props.prizes[finalIndex]);
    }
  };

  animate();
};

const easeOut = (t) => {
  return 1 - Math.pow(1 - t, 3);
};

watch(() => props.prizes, drawWheel, { immediate: false });
onMounted(() => {
  drawWheel();
})

</script>

<style scoped>
.lottery-wheel-container {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
}

.spin-button {
  margin-top: 20px;
  padding: 12px 24px;
  font-size: 16px;
  background-color: #FF6B6B;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.spin-button:hover:not(:disabled) {
  background-color: #FF5252;
}

.spin-button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}
</style>
