<template>
  <div class="four-zero-four">
    <svg
      class="four-zero-four__message"
      fill="none"
      viewBox="0 0 607 511"
      xmlns="http://www.w3.org/2000/svg"
    >
      <title>404 Page Not Found</title>
      <text x="50%" y="90%" class="four-zero-four__text">Page not found</text>
      <circle cx="126.5" cy="301.5" r="4.5" fill="#fff" />
      <circle cx="21.5" cy="279.5" r="4.5" fill="#fff" />
      <circle cx="276.5" cy="233.5" r="4.5" fill="#fff" />
      <circle cx="276.5" cy="311.5" r="4.5" fill="#fff" />
      <circle cx="429.5" cy="86.5" r="4.5" fill="#fff" />
      <circle cx="533.5" cy="108.5" r="4.5" fill="#fff" />
      <g filter="url(#a)" class="four-zero-four__circle">
        <circle cx="22" cy="280" r="16" fill="#fff" fill-opacity=".2" />
      </g>
      <g filter="url(#b)" class="four-zero-four__circle">
        <circle cx="126" cy="302" r="16" fill="#fff" fill-opacity=".2" />
      </g>
      <g filter="url(#c)" class="four-zero-four__circle">
        <circle cx="276" cy="234" r="16" fill="#fff" fill-opacity=".2" />
      </g>
      <g filter="url(#d)" class="four-zero-four__circle">
        <circle cx="429" cy="87" r="16" fill="#fff" fill-opacity=".2" />
      </g>
      <g filter="url(#e)" class="four-zero-four__circle">
        <circle cx="533" cy="109" r="16" fill="#fff" fill-opacity=".2" />
      </g>
      <g filter="url(#f)" class="four-zero-four__circle">
        <circle cx="276" cy="312" r="16" fill="#fff" fill-opacity=".2" />
      </g>
      <g filter="url(#g)">
        <path
          d="M126.4 296.9V225l61.7-29V432l-80.5 37.8V392l-85.8 39.3v-147m0 0a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm259 24.8 64.9-30.4v-77.3l-65 30.4M533.5 104V32.3l61.7-29V239L514.7 277V199L429 238.5v-147m0 0a5 5 0 1 0 0-10 5 5 0 0 0 0 10Zm-37.3 6.2v235.8l-166.3 78.2V175.9l166.3-78.2ZM131.4 301.9a5 5 0 1 1-10 0 5 5 0 0 1 10 0Zm149.8-68a5 5 0 1 1-10 0 5 5 0 0 1 10 0Zm0 77.5a5 5 0 1 1-10 0 5 5 0 0 1 10 0ZM538.6 109a5 5 0 1 1-10 0 5 5 0 0 1 10 0Z"
          stroke="url(#h)"
          stroke-width="3"
          stroke-miterlimit="10"
        />
      </g>
      <defs>
        <filter
          id="a"
          x="0"
          y="262"
          width="44"
          height="44"
          filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB"
        >
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="4" />
          <feGaussianBlur stdDeviation="3" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" />
          <feBlend in2="BackgroundImageFix" result="effect1_dropShadow" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="2" />
          <feGaussianBlur stdDeviation="2" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
          <feBlend in2="effect1_dropShadow" result="effect2_dropShadow" />
          <feBlend in="SourceGraphic" in2="effect2_dropShadow" result="shape" />
        </filter>
        <filter
          id="b"
          x="104"
          y="284"
          width="44"
          height="44"
          filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB"
        >
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="4" />
          <feGaussianBlur stdDeviation="3" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" />
          <feBlend in2="BackgroundImageFix" result="effect1_dropShadow" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="2" />
          <feGaussianBlur stdDeviation="2" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
          <feBlend in2="effect1_dropShadow" result="effect2_dropShadow" />
          <feBlend in="SourceGraphic" in2="effect2_dropShadow" result="shape" />
        </filter>
        <filter
          id="c"
          x="254"
          y="216"
          width="44"
          height="44"
          filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB"
        >
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="4" />
          <feGaussianBlur stdDeviation="3" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" />
          <feBlend in2="BackgroundImageFix" result="effect1_dropShadow" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="2" />
          <feGaussianBlur stdDeviation="2" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
          <feBlend in2="effect1_dropShadow" result="effect2_dropShadow" />
          <feBlend in="SourceGraphic" in2="effect2_dropShadow" result="shape" />
        </filter>
        <filter
          id="d"
          x="407"
          y="69"
          width="44"
          height="44"
          filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB"
        >
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="4" />
          <feGaussianBlur stdDeviation="3" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" />
          <feBlend in2="BackgroundImageFix" result="effect1_dropShadow" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="2" />
          <feGaussianBlur stdDeviation="2" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
          <feBlend in2="effect1_dropShadow" result="effect2_dropShadow" />
          <feBlend in="SourceGraphic" in2="effect2_dropShadow" result="shape" />
        </filter>
        <filter
          id="e"
          x="511"
          y="91"
          width="44"
          height="44"
          filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB"
        >
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="4" />
          <feGaussianBlur stdDeviation="3" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" />
          <feBlend in2="BackgroundImageFix" result="effect1_dropShadow" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="2" />
          <feGaussianBlur stdDeviation="2" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
          <feBlend in2="effect1_dropShadow" result="effect2_dropShadow" />
          <feBlend in="SourceGraphic" in2="effect2_dropShadow" result="shape" />
        </filter>
        <filter
          id="f"
          x="254"
          y="294"
          width="44"
          height="44"
          filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB"
        >
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="4" />
          <feGaussianBlur stdDeviation="3" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0" />
          <feBlend in2="BackgroundImageFix" result="effect1_dropShadow" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="2" />
          <feGaussianBlur stdDeviation="2" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" />
          <feBlend in2="effect1_dropShadow" result="effect2_dropShadow" />
          <feBlend in="SourceGraphic" in2="effect2_dropShadow" result="shape" />
        </filter>
        <filter
          id="g"
          x="5.3"
          y=".9"
          width="601.4"
          height="491.2"
          filterUnits="userSpaceOnUse"
          color-interpolation-filters="sRGB"
        >
          <feFlood flood-opacity="0" result="BackgroundImageFix" />
          <feColorMatrix
            in="SourceAlpha"
            values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
            result="hardAlpha"
          />
          <feOffset dy="10" />
          <feGaussianBlur stdDeviation="5" />
          <feComposite in2="hardAlpha" operator="out" />
          <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" />
          <feBlend in2="BackgroundImageFix" result="effect1_dropShadow" />
          <feBlend in="SourceGraphic" in2="effect1_dropShadow" result="shape" />
        </filter>
        <linearGradient
          id="h"
          x1="306"
          y1="3.3"
          x2="306"
          y2="469.7"
          gradientUnits="userSpaceOnUse"
        >
          <stop stop-color="#2CCFFE" />
          <stop offset="1" stop-color="#115AF4" />
        </linearGradient>
      </defs>
    </svg>
  </div>
</template>

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

  const circles = ref<Element[]>([])
  const interval = ref<number>(0)

  const randomNumber = (min: number, max: number): number => {
    return Math.floor(Math.random() * (max - min + 1) + min)
  }

  const uniqueElementFilter = (value: Element, index: number, array: Element[]): boolean => {
    return array.indexOf(value) === index
  }

  const animateCircle = (circle: Element): void => {
    const animationClass = 'four-zero-four__circle--animate'
    circle.addEventListener(
      'animationend',
      () => {
        circle.classList.remove(animationClass)
      },
      { once: true },
    )
    circle.classList.add(animationClass)
  }

  const animateRandomCircles = (): void => {
    const selectedCircles: Element[] = []
    while (selectedCircles.length < 3) {
      const index = randomNumber(0, circles.value.length - 1)
      const circle = circles.value[index]
      selectedCircles.push(circle)
    }
    selectedCircles
      .filter(uniqueElementFilter)
      .forEach(animateCircle)
  }

  const startAnimation = (): void => {
    const delay = randomNumber(3, 4) * 1000
    interval.value = window.setTimeout(() => {
      animateRandomCircles()
      startAnimation()
    }, delay)
  }

  onMounted(() => {
    circles.value = Array.from(document.querySelectorAll('.four-zero-four__circle'))
    startAnimation()
  })

  onBeforeUnmount(() => {
    window.clearInterval(interval.value)
  })
</script>

<style>
.four-zero-four {
  display: flex;
  align-items: center;
  justify-content: center;
}

.four-zero-four { @apply
  w-full
  h-full
}

@media screen and (max-width: 1024px) {
  .four-zero-four {
    background-size: 150px auto, 500px auto;
  }
}

.four-zero-four__message {
  width: 600px;
  max-width: 80%;
  margin-top: -15%;
}

.four-zero-four__text { @apply
  text-xl
  font-semibold
  text-subdued
}

.four-zero-four__circle {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
}

.four-zero-four__circle--animate {
  animation: pulse-black 1.5s;
}

@keyframes pulse-black {
  0% {
    transform: scale(0);
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    transform: scale(1);
    opacity: 0;
  }
}
</style>