<template>
    <div :class="[
        'animate-pulse bg-gradient-to-r from-stone-200 via-stone-50 to-stone-200 bg-[length:200%_100%]',
        'dark:from-stone-800 dark:via-stone-700 dark:to-stone-800',
        variantClasses,
        sizeClasses,
        className
    ]" :style="{ animationDuration: `${duration}ms` }" />
</template>

<script setup lang="ts">
import { computed } from 'vue';

export interface SkeletonProps {
    variant?: 'text' | 'circular' | 'rectangular' | 'card' | 'button' | 'avatar';
    size?: 'sm' | 'md' | 'lg' | 'xl';
    width?: string | number;
    height?: string | number;
    className?: string;
    duration?: number;
}

const props = withDefaults(defineProps<SkeletonProps>(), {
    variant: 'text',
    size: 'md',
    duration: 1500,
    className: ''
});

const variantClasses = computed(() => {
    const variants = {
        text: 'rounded-md',
        circular: 'rounded-full aspect-square',
        rectangular: 'rounded-lg',
        card: 'rounded-xl',
        button: 'rounded-lg',
        avatar: 'rounded-full aspect-square'
    };

    return variants[props.variant];
});

const sizeClasses = computed(() => {
    const baseSizes = {
        text: {
            sm: 'h-3',
            md: 'h-4',
            lg: 'h-5',
            xl: 'h-6'
        },
        circular: {
            sm: 'w-8 h-8',
            md: 'w-12 h-12',
            lg: 'w-16 h-16',
            xl: 'w-20 h-20'
        },
        rectangular: {
            sm: 'h-20',
            md: 'h-32',
            lg: 'h-48',
            xl: 'h-64'
        },
        card: {
            sm: 'h-32',
            md: 'h-40',
            lg: 'h-48',
            xl: 'h-56'
        },
        button: {
            sm: 'h-8 w-16',
            md: 'h-10 w-20',
            lg: 'h-12 w-24',
            xl: 'h-14 w-28'
        },
        avatar: {
            sm: 'w-8 h-8',
            md: 'w-10 h-10',
            lg: 'w-12 h-12',
            xl: 'w-16 h-16'
        }
    };

    return baseSizes[props.variant][props.size];
});

// Handle custom width/height via CSS variables
const style = computed(() => {
    const customStyle: Record<string, string> = {};

    if (props.width) {
        customStyle.width = typeof props.width === 'number' ? `${props.width}px` : props.width;
    }

    if (props.height) {
        customStyle.height = typeof props.height === 'number' ? `${props.height}px` : props.height;
    }

    return customStyle;
});
</script>

<style scoped>
@keyframes shimmer {
    0% {
        background-position: -200% 0;
    }

    100% {
        background-position: 200% 0;
    }
}

.animate-pulse {
    animation: shimmer var(--duration, 1.5s) ease-in-out infinite;
}
</style>