<script setup lang="ts">
interface Star {
	x: number;
	y: number;
	size: number;
}

const props = withDefaults(
	defineProps<{
		starCount?: number;
		color?: string;
		speed?: "slow" | "normal" | "fast";
		size?: { min: number; max: number };
	}>(),
	{
		starCount: 300,
		color: "var(--ui-primary)",
		speed: "normal",
		size: () => ({
			min: 1,
			max: 2,
		}),
	},
);

// Generate random star positions and sizes
const generateStars = (count: number): Star[] => {
	return Array.from({ length: count }, () => ({
		x: Math.floor(Math.random() * 2000),
		y: Math.floor(Math.random() * 2000),
		size:
			typeof props.size === "number"
				? props.size
				: Math.random() * (props.size.max - props.size.min) + props.size.min,
	}));
};

// Define speed configurations once
const speedMap = {
	slow: { duration: 200, opacity: 0.5, ratio: 0.3 },
	normal: { duration: 150, opacity: 0.75, ratio: 0.3 },
	fast: { duration: 100, opacity: 1, ratio: 0.4 },
};

// Use a more efficient approach to generate and store stars
const stars = useState<{ slow: Star[]; normal: Star[]; fast: Star[] }>(
	"stars",
	() => {
		return {
			slow: generateStars(Math.floor(props.starCount * speedMap.slow.ratio)),
			normal: generateStars(
				Math.floor(props.starCount * speedMap.normal.ratio),
			),
			fast: generateStars(Math.floor(props.starCount * speedMap.fast.ratio)),
		};
	},
);

// Compute star layers with different speeds and opacities
const starLayers = computed(() => [
	{ stars: stars.value.fast, ...speedMap.fast },
	{ stars: stars.value.normal, ...speedMap.normal },
	{ stars: stars.value.slow, ...speedMap.slow },
]);
</script>

<template>
  <div class="absolute pointer-events-none z-[-1] inset-y-0 inset-x-5 sm:inset-x-7 lg:inset-x-9 overflow-hidden">
    <svg
      class="absolute inset-0 pointer-events-none"
      viewBox="0 0 1017 181"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <g opacity="0.5">
        <mask
          id="path-1-inside-1_846_160841"
          fill="white"
        >
          <path d="M0 0H1017V181H0V0Z" />
        </mask>
        <path
          d="M0 0H1017V181H0V0Z"
          fill="url(#paint0_radial_846_160841)"
          fill-opacity="0.22"
        />
      </g>
      <defs>
        <radialGradient
          id="paint0_radial_846_160841"
          cx="0"
          cy="0"
          r="1"
          gradientUnits="userSpaceOnUse"
          gradientTransform="translate(508.999 19.5) rotate(90.177) scale(161.501 509.002)"
        >
          <stop stop-color="var(--ui-primary)" />
          <stop
            offset="1"
            stop-color="var(--ui-primary)"
            stop-opacity="0"
          />
        </radialGradient>
        <linearGradient
          id="paint1_linear_846_160841"
          x1="10.9784"
          y1="91"
          x2="1017"
          y2="90.502"
          gradientUnits="userSpaceOnUse"
        >
          <stop
            stop-color="var(--ui-primary)"
            stop-opacity="0"
          />
          <stop
            offset="0.395"
            stop-color="var(--ui-primary)"
          />
          <stop
            offset="1"
            stop-color="var(--ui-primary)"
            stop-opacity="0"
          />
        </linearGradient>
      </defs>
    </svg>

    <div class="stars size-full absolute inset-x-0 top-0">
      <div
        v-for="(layer, index) in starLayers"
        :key="index"
        class="star-layer"
        :style="{
          '--star-duration': `${layer.duration}s`,
          '--star-opacity': layer.opacity,
          '--star-color': color
        }"
      >
        <div
          v-for="(star, starIndex) in layer.stars"
          :key="starIndex"
          class="star absolute rounded-full"
          :style="{
            left: `${star.x}px`,
            top: `${star.y}px`,
            width: `${star.size}px`,
            height: `${star.size}px`,
            backgroundColor: 'var(--star-color)',
            opacity: 'var(--star-opacity)'
          }"
        />
      </div>
    </div>
  </div>
</template>

<style scoped>
.stars {
  left: 50%;
  transform: translate(-50%);
  -webkit-mask-image: linear-gradient(180deg,
      rgba(217, 217, 217, 0) 0%,
      rgba(217, 217, 217, 0.8) 25%,
      #d9d9d9 50%,
      rgba(217, 217, 217, 0.8) 75%,
      rgba(217, 217, 217, 0) 100%);
  mask-image: linear-gradient(180deg,
      rgba(217, 217, 217, 0) 0%,
      rgba(217, 217, 217, 0.8) 25%,
      #d9d9d9 50%,
      rgba(217, 217, 217, 0.8) 75%,
      rgba(217, 217, 217, 0) 100%);
  -webkit-mask-size: cover;
  mask-size: cover;
}

.star-layer {
  animation: risingStarsAnimation linear infinite;
  animation-duration: var(--star-duration);
  will-change: transform;
}

@keyframes risingStarsAnimation {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-2000px);
  }
}
</style>
