<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";

interface Skill {
    id: string;
    name: string;
    level: number;
}

const props = defineProps<{
    skills: Skill[];
}>();

const skillsSection = ref<HTMLElement | null>(null);
const animatedLevels = ref<{ [key: string]: number }>({});
const hasAnimated = ref(false);
let observer: IntersectionObserver | null = null;
let animationFrameId: number | null = null;

const animateSkills = () => {
    const duration = 1000;
    const startTime = performance.now();

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

        props.skills.forEach((skill) => {
            animatedLevels.value[skill.id] = skill.level * progress;
        });

        if (progress < 1) {
            animationFrameId = requestAnimationFrame(animate);
        }
    };

    animationFrameId = requestAnimationFrame(animate);
};

onMounted(() => {
    observer = new IntersectionObserver(
        (entries) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting && !hasAnimated.value) {
                    hasAnimated.value = true;
                    animateSkills();

                    if (skillsSection.value && observer) {
                        observer.unobserve(skillsSection.value);
                    }
                }
            });
        },
        { threshold: 0.3 },
    );

    if (skillsSection.value) {
        observer.observe(skillsSection.value);
    }
});

onUnmounted(() => {
    if (observer) {
        observer.disconnect();
    }
    if (animationFrameId !== null) {
        cancelAnimationFrame(animationFrameId);
    }
});
</script>

<template>
    <div id="skills-section" ref="skillsSection" class="space-y-3 sm:space-y-4">
        <div v-for="skill in skills" :key="skill.id" class="p-1 sm:p-2">
            <div class="flex justify-between items-center mb-2">
                <span
                    class="text-sm sm:text-base font-medium truncate pr-2 min-w-0 flex-1"
                    :title="skill.name"
                >
                    {{ skill.name }}
                </span>
                <span
                    class="text-xs sm:text-sm text-base-content/70 whitespace-nowrap"
                >
                    {{ Math.round(animatedLevels[skill.id] || 0) }}/5
                </span>
            </div>
            <progress
                class="progress progress-primary w-full h-2 sm:h-3 min-h-2 transition-all duration-100 ease-out"
                :value="(animatedLevels[skill.id] || 0) * 20"
                max="100"
                :aria-label="`${skill.name} skill level: ${Math.round(animatedLevels[skill.id] || 0)} out of 5`"
            ></progress>
        </div>
    </div>
</template>
