<template>
  <div class="stat-card-wrapper" :class="wrapperClass">
    <div class="stat-icon-container" :class="`bg-${color}/10`">
      <div class="stat-icon" :class="`text-${color}`">
        <slot name="icon">
          <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
            <path stroke-linecap="round" stroke-linejoin="round" d="M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z" />
          </svg>
        </slot>
      </div>
    </div>
    <div class="stat-content">
      <p class="stat-label">{{ label }}</p>
      <p class="stat-value">{{ displayValue }}</p>
      <p v-if="trend" class="stat-trend" :class="trendClass">
        <span class="trend-arrow">{{ trendArrow }}</span>
        <span>{{ trend }}</span>
      </p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'

interface Props {
  label: string
  value: number | string
  color?: 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error'
  trend?: string
  trendDirection?: 'up' | 'down' | 'neutral'
  animate?: boolean
  wrapperClass?: string
}

const props = withDefaults(defineProps<Props>(), {
  color: 'primary',
  animate: true,
  wrapperClass: ''
})

const displayValue = ref<number | string>(props.animate && typeof props.value === 'number' ? 0 : props.value)

const trendClass = computed(() => {
  if (!props.trendDirection) return ''
  return {
    up: 'text-success',
    down: 'text-error',
    neutral: 'text-base-content/60'
  }[props.trendDirection]
})

const trendArrow = computed(() => {
  if (!props.trendDirection) return ''
  return {
    up: '↑',
    down: '↓',
    neutral: '→'
  }[props.trendDirection]
})

// Animate number counting
const animateValue = (start: number, end: number, duration: number) => {
  const startTime = Date.now()
  const animate = () => {
    const now = Date.now()
    const progress = Math.min((now - startTime) / duration, 1)
    const easeOutQuad = progress * (2 - progress)
    displayValue.value = Math.floor(start + (end - start) * easeOutQuad)
    
    if (progress < 1) {
      requestAnimationFrame(animate)
    } else {
      displayValue.value = end
    }
  }
  requestAnimationFrame(animate)
}

watch(() => props.value, (newValue) => {
  if (props.animate && typeof newValue === 'number' && typeof displayValue.value === 'number') {
    animateValue(displayValue.value, newValue, 1000)
  } else {
    displayValue.value = newValue
  }
})

onMounted(() => {
  if (props.animate && typeof props.value === 'number') {
    animateValue(0, props.value, 1000)
  }
})
</script>

<style scoped>
.stat-card-wrapper {
  @apply flex items-start gap-4 p-5 bg-neutral rounded-xl shadow-soft hover-lift transition-smooth;
}

.stat-icon-container {
  @apply flex-shrink-0 w-14 h-14 rounded-xl flex items-center justify-center;
}

.stat-icon {
  @apply w-7 h-7;
}

.stat-content {
  @apply flex-1 min-w-0;
}

.stat-label {
  @apply text-sm font-medium text-base-content/70 mb-1;
}

.stat-value {
  @apply text-3xl font-bold text-base-content mb-1;
}

.stat-trend {
  @apply text-sm font-medium flex items-center gap-1;
}

.trend-arrow {
  @apply text-lg;
}
</style>
