---
interface Props {
  title: string;
  description?: string;
  image?: string;
  link?: string;
  className?: string;
  color?: string;
  spotlightSize?: 'small' | 'medium' | 'large';
  spotlightIntensity?: 'subtle' | 'medium' | 'strong';
}

const { 
  title, 
  description, 
  image, 
  link, 
  className = "",
  color = "rgba(75, 107, 255, 0.3)", // 默认是蓝色光晕
  spotlightSize = 'medium',
  spotlightIntensity = 'medium'
} = Astro.props;

const id = `spotlight-card-${Math.random().toString(36).substring(2, 11)}`;

// 计算光晕大小
const sizeMap = {
  small: '70%',
  medium: '100%',
  large: '130%'
};

// 计算光晕强度
const intensityMap = {
  subtle: '0.15',
  medium: '0.25',
  strong: '0.4'
};

const spotlightSizeValue = sizeMap[spotlightSize];
const spotlightIntensityValue = intensityMap[spotlightIntensity];
---

<div 
  id={id}
  class={`spotlight-card group relative overflow-hidden rounded-xl border border-white/10 dark:bg-color-dark-card bg-white p-6 shadow-lg transition-all hover:shadow-xl ${className}`}
  style="transform-style: preserve-3d; transform: perspective(1000px);"
  data-spotlight-size={spotlightSizeValue}
  data-spotlight-intensity={spotlightIntensityValue}
>
  <div class="spotlight-primary absolute pointer-events-none inset-0 z-0 transition duration-300 opacity-0"></div>
  <div class="spotlight-secondary absolute pointer-events-none inset-0 z-0 transition duration-300 opacity-0"></div>
  <div class="spotlight-border absolute pointer-events-none inset-0 z-0 transition duration-300 opacity-0"></div>
  
  {image && (
    <div class="mb-4 overflow-hidden rounded-lg">
      <div class="h-40 bg-gray-300 dark:bg-gray-700 flex items-center justify-center">
        <span class="text-gray-500 dark:text-gray-400">{title} 图片</span>
      </div>
    </div>
  )}
  
  <h3 class="group-hover:text-color-primary-600 dark:group-hover:text-color-primary-400 text-lg font-semibold text-gray-900 dark:text-white mb-2 transition-colors">
    {title}
  </h3>
  
  {description && (
    <p class="text-gray-600 dark:text-gray-400 mb-4 text-sm">
      {description}
    </p>
  )}
  
  {link && (
    <a 
      href={link} 
      class="text-color-primary-600 hover:text-color-primary-700 dark:text-color-primary-400 dark:hover:text-color-primary-300 font-medium text-sm"
    >
      查看详情 &rarr;
    </a>
  )}
  
  <slot />
</div>

<style define:vars={{ 
  spotlightColor: color, 
  spotlightSize: spotlightSizeValue,
  spotlightIntensity: spotlightIntensityValue
}}>
  .spotlight-primary {
    background: radial-gradient(
      circle at center,
      var(--spotlightColor) 0%,
      transparent 70%
    );
    filter: blur(5px);
    opacity: 0;
    /* 确保径向渐变是一个完美的圆 */
    border-radius: 50%;
  }
  
  .spotlight-secondary {
    background: radial-gradient(
      circle at center,
      rgba(255, 255, 255, 0.1) 0%,
      transparent 60%
    );
    opacity: 0;
    /* 确保径向渐变是一个完美的圆 */
    border-radius: 50%;
  }
  
  .spotlight-border {
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: inherit;
    opacity: 0;
  }
  
  [data-theme='dark'] .spotlight-primary {
    background: radial-gradient(
      circle at center,
      var(--spotlightColor) 0%,
      transparent 70%
    );
  }
  
  [data-theme='dark'] .spotlight-secondary {
    background: radial-gradient(
      circle at center,
      rgba(255, 255, 255, 0.07) 0%,
      transparent 60%
    );
  }
</style>

<script>
  // 等待 DOM 加载完成
  document.addEventListener('DOMContentLoaded', () => {
    // 获取所有光标效果卡片
    const cards = document.querySelectorAll('.spotlight-card');
    
    cards.forEach(card => {
      const primaryEffect = card.querySelector('.spotlight-primary');
      const secondaryEffect = card.querySelector('.spotlight-secondary');
      const borderEffect = card.querySelector('.spotlight-border');
      
      if (!primaryEffect || !secondaryEffect || !borderEffect) return;
      
      // 获取配置
      const size = card.getAttribute('data-spotlight-size') || '100%';
      const intensity = parseFloat(card.getAttribute('data-spotlight-intensity') || '0.25');
      
      // 上一次鼠标位置
      let lastX = 0;
      let lastY = 0;
      
      // 平滑因子 (值越小越平滑)
      const smoothFactor = 0.15;
      
      // 用于动画的requestAnimationFrame ID
      let animationFrameId: number | null = null;
      
      // 鼠标移入时添加效果
      card.addEventListener('mouseenter', () => {
        // 计算光效尺寸 - 使用卡片对角线长度确保覆盖整个卡片区域
        const rect = card.getBoundingClientRect();
        const diagonalLength = Math.sqrt(rect.width * rect.width + rect.height * rect.height);
        const effectSize = diagonalLength * 1.5 + 'px'; // 增加50%确保覆盖
        
        // 设置光效元素尺寸
        (primaryEffect as HTMLElement).style.width = effectSize;
        (primaryEffect as HTMLElement).style.height = effectSize;
        (secondaryEffect as HTMLElement).style.width = effectSize;
        (secondaryEffect as HTMLElement).style.height = effectSize;
        
        // 设置可见度
        (primaryEffect as HTMLElement).style.opacity = intensity.toString();
        (secondaryEffect as HTMLElement).style.opacity = (intensity * 0.7).toString();
        (borderEffect as HTMLElement).style.opacity = (intensity * 0.5).toString();
        
        // 启动平滑动画
        if (animationFrameId === null) {
          animateSpotlight();
        }
      });
      
      // 鼠标移出时移除效果
      card.addEventListener('mouseleave', () => {
        (primaryEffect as HTMLElement).style.opacity = '0';
        (secondaryEffect as HTMLElement).style.opacity = '0';
        (borderEffect as HTMLElement).style.opacity = '0';
        
        // 重置卡片的 3D 效果
        (card as HTMLElement).style.transform = 'perspective(1000px)';
        
        // 取消动画
        if (animationFrameId !== null) {
          cancelAnimationFrame(animationFrameId);
          animationFrameId = null;
        }
      });
      
      // 鼠标移动时更新光标位置和 3D 效果
      card.addEventListener('mousemove', (e) => {
        const mouseEvent = e as MouseEvent;
        const rect = card.getBoundingClientRect();
        lastX = mouseEvent.clientX - rect.left;
        lastY = mouseEvent.clientY - rect.top;
        
        // 计算 3D 旋转效果
        const centerX = rect.width / 2;
        const centerY = rect.height / 2;
        const rotateY = (lastX - centerX) / 20;
        const rotateX = (centerY - lastY) / 20;
        
        // 应用 3D 效果
        (card as HTMLElement).style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
      });
      
      // 平滑动画函数
      function animateSpotlight() {
        const rect = card.getBoundingClientRect();
        
        // 获取当前位置
        const currentPrimaryStyle = window.getComputedStyle(primaryEffect as Element);
        const currentSecondaryStyle = window.getComputedStyle(secondaryEffect as Element);
        
        // 解析当前位置
        let currentX = parseInt(currentPrimaryStyle.left || '0');
        let currentY = parseInt(currentPrimaryStyle.top || '0');
        
        if (isNaN(currentX)) currentX = rect.width / 2;
        if (isNaN(currentY)) currentY = rect.height / 2;
        
        // 计算新位置 (平滑过渡)
        const newX = currentX + (lastX - currentX) * smoothFactor;
        const newY = currentY + (lastY - currentY) * smoothFactor;
        
        // 应用位置
        // 不再在这里设置宽高，而是在mouseenter时设置一次
        (primaryEffect as HTMLElement).style.left = `${newX}px`;
        (primaryEffect as HTMLElement).style.top = `${newY}px`;
        (primaryEffect as HTMLElement).style.transform = `translate(-50%, -50%)`;
        
        (secondaryEffect as HTMLElement).style.left = `${newX}px`;
        (secondaryEffect as HTMLElement).style.top = `${newY}px`;
        (secondaryEffect as HTMLElement).style.transform = `translate(-50%, -50%) scale(1.2)`;
        
        // 边框位置不需要移动，但可以随鼠标位置变化透明度
        const distanceFromCenter = Math.sqrt(
          Math.pow((newX / rect.width - 0.5) * 2, 2) + 
          Math.pow((newY / rect.height - 0.5) * 2, 2)
        );
        
        // 越靠近边缘，边框越明显
        const borderOpacity = Math.min(distanceFromCenter * intensity, intensity * 0.5);
        (borderEffect as HTMLElement).style.opacity = borderOpacity.toString();
        
        // 继续动画循环
        animationFrameId = requestAnimationFrame(animateSpotlight);
      }
    });
  });
</script> 