<script lang="ts" setup>
import type { ComponentPublicInstance } from "vue";
import type { Project } from "~/types/projects";

const { locale } = useI18n();

const props = defineProps<{
  projects?: Project[];
}>();

const isRTL = computed(() => locale.value === "ar");

const currentIndex = ref(0);

const autoPlay = ref(true);
const autoPlayInterval = ref(5000);
let intervalId: NodeJS.Timeout | null = null;

const isPaused = ref(false);
const autoDirection = ref<"next" | "prev">("next");

const scrollOverlayVisible = ref<Record<number, boolean>>({});

const itemRefs = ref<Record<number, HTMLElement | null>>({});

const setItemRef = (
  id: number,
  el: Element | ComponentPublicInstance | null,
) => {
  itemRefs.value[id] = (el as HTMLElement) || null;
};

const getItemPosition = (index: number): number => {
  const totalItems = props.projects?.length || 0;
  if (totalItems === 0) return 1;
  const relativeIndex = (index - currentIndex.value + totalItems) % totalItems;
  return relativeIndex + 1;
};

const getCurrentProject = computed(() => {
  if (!props.projects || props.projects.length === 0) return null;

  const total = props.projects.length;

  return (
    props.projects.find((_, index) => getItemPosition(index) === 3) ??
    props.projects[currentIndex.value % total]
  );
});

const initializeOverlays = () => {
  if (!props.projects) return;
  props.projects.forEach((project) => {
    if (project.is_scroll) scrollOverlayVisible.value[project.id] = true;
  });
};

const onItemScroll = (projectId: number, event: Event) => {
  const target = event.target as HTMLElement | null;
  if (!target) return;
  scrollOverlayVisible.value[projectId] = target.scrollTop === 0;
};

const goToPrevious = () => {
  const projectsLength = props.projects?.length || 0;
  if (projectsLength < 5) return;

  if (isRTL.value) {
    currentIndex.value = (currentIndex.value + 1) % projectsLength;
  } else {
    currentIndex.value =
      (currentIndex.value - 1 + projectsLength) % projectsLength;
  }
};

const goToNext = () => {
  const projectsLength = props.projects?.length || 0;
  if (projectsLength < 5) return;

  if (isRTL.value) {
    currentIndex.value =
      (currentIndex.value - 1 + projectsLength) % projectsLength;
  } else {
    currentIndex.value = (currentIndex.value + 1) % projectsLength;
  }
};

const startAutoPlay = () => {
  const projectsLength = props.projects?.length || 0;
  if (!autoPlay.value || projectsLength < 5 || isPaused.value) return;

  stopAutoPlay();
  intervalId = setInterval(() => {
    if (autoDirection.value === "next") {
      goToNext();
    } else {
      goToPrevious();
    }
  }, autoPlayInterval.value);
};

const stopAutoPlay = () => {
  if (intervalId) {
    clearInterval(intervalId);
    intervalId = null;
  }
};

const pauseAutoPlay = () => {
  isPaused.value = true;
  stopAutoPlay();
};

const resumeAutoPlay = () => {
  isPaused.value = false;
  startAutoPlay();
};

// When the slide changes, reset all scrollable items back to top
watch(
  () => currentIndex.value,
  () => {
    nextTick(() => {
      for (const [idStr, el] of Object.entries(itemRefs.value)) {
        if (el) {
          el.scrollTop = 0;
          // Restore overlay visibility for scrollable projects
          const idNum = Number(idStr);
          const proj = props.projects?.find((p) => p.id === idNum);
          if (proj?.is_scroll) {
            scrollOverlayVisible.value[idNum] = true;
          }
        }
      }
    });
  },
);

const handlePrevClick = () => {
  autoDirection.value = "prev";
  goToPrevious();
};

const handleNextClick = () => {
  autoDirection.value = "next";
  goToNext();
};

onMounted(() => {
  startAutoPlay();
  initializeOverlays();
});

onBeforeUnmount(() => {
  stopAutoPlay();
});
</script>

<template>
  <div
    v-if="props.projects && props.projects.length >= 5"
    class="gallery-wrapper"
  >
    <h3 v-if="getCurrentProject" class="project-title">
      {{ getCurrentProject.title }}
    </h3>

    <div class="gallery">
      <div class="gallery-container ws-no-scrollbar">
        <div
          v-for="(project, index) in props.projects"
          :key="project.id"
          :ref="(el) => setItemRef(project.id, el)"
          :class="[
            'gallery-item ws-no-scrollbar overlay-gradient',
            `gallery-item-${getItemPosition(index)}`,
            getItemPosition(index) !== 3 ? 'overlay-visible' : '',
          ]"
          @scroll="project.is_scroll && onItemScroll(project.id, $event)"
          @mouseenter="getItemPosition(index) === 3 ? pauseAutoPlay() : null"
          @mouseleave="getItemPosition(index) === 3 ? resumeAutoPlay() : null"
        >
          <NuxtImg
            :src="project.slider"
            :alt="project.title"
            :data-index="index + 1"
            class="w-full"
            :width="946"
            :class="!project.is_scroll ? 'h-full object-contain' : ''"
            format="webp"
            quality="85"
            loading="lazy"
            decoding="async"
            densities="x1 x2"
            :placeholder="[24, 16, 55, 0]"
            placeholder-class="img-pixel"
            sizes="100vw sm:100vw md:85vw lg:80vw xl:946px"
          />
          <div
            v-if="
              getItemPosition(index) === 3 &&
              project.is_scroll &&
              scrollOverlayVisible[project.id]
            "
            class="bg-surface-background hover:bg-surface-background/90 border-surface-border pointer-events-auto absolute bottom-2 left-1/2 z-10 -translate-x-1/2 transform animate-bounce cursor-pointer rounded-full border p-2 shadow-lg backdrop-blur-sm transition-all duration-300 hover:shadow-xl"
          >
            <SvgArrowDownIcon class="text-foreground h-[20px] w-[20px]" />
          </div>
        </div>
      </div>

      <div class="gallery-controls">
        <button
          :aria-label="$t('ariaLabels.prevBtn')"
          class="gallery-controls-previous"
          @mouseenter="pauseAutoPlay"
          @mouseleave="resumeAutoPlay"
          @click="handlePrevClick"
        >
          <SvgGradientArrowRightIcon
            class="h-5 w-5"
            :class="locale === 'en' ? 'scale-x-[-1]' : ''"
          />
        </button>
        <button
          :aria-label="$t('ariaLabels.nextBtn')"
          class="gallery-controls-next"
          @mouseenter="pauseAutoPlay"
          @mouseleave="resumeAutoPlay"
          @click="handleNextClick"
        >
          <SvgGradientArrowLeftIcon
            class="h-5 w-5"
            :class="locale === 'en' ? 'scale-x-[-1]' : ''"
          />
        </button>
      </div>
    </div>

    <div v-if="getCurrentProject" class="project-description">
      <p class="line-clamp-2">{{ getCurrentProject.short_description }}</p>
      <NuxtLinkLocale
        class="ws-gradient-border mx-auto w-fit px-4 py-2"
        :to="`/our-projects/${getCurrentProject.slug}`"
      >
        {{ $t("projectsHighlight.know-more-button") }}
      </NuxtLinkLocale>
    </div>
  </div>

  <div v-else-if="props.projects && props.projects.length < 5">
    <EmptyState
      size="100%"
      :custom-message="$t('projectsCarousel.notEnoughProjects')"
    />
  </div>
</template>

<style lang="css" scoped>
.gallery-wrapper {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.gallery {
  width: 100%;
  position: relative;
}

.gallery-container {
  height: 568.79px;
  display: flex;
  align-items: center;
  margin: 0 auto;
  position: relative;
  overflow-x: clip;
  overflow-y: visible;
}

.gallery-item {
  background-color: var(--background);
  opacity: 0;
  position: absolute;
  transition:
    transform 400ms cubic-bezier(0.4, 0, 0.2, 1),
    width 400ms cubic-bezier(0.4, 0, 0.2, 1),
    height 400ms cubic-bezier(0.4, 0, 0.2, 1),
    left 400ms cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 0;
  border-radius: var(--ws-rounded);
  overflow-x: hidden;
  overflow-y: auto;
  pointer-events: none;
}

.gallery-item-3 {
  cursor: pointer;
  pointer-events: auto;
}

.overlay-gradient::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.25) 0%,
    rgba(0, 0, 0, 0.45) 35%,
    rgba(0, 0, 0, 0.6) 100%
  );
  opacity: 0;
  transition: opacity 300ms ease-in-out;
  z-index: 3;
}

.overlay-visible::after {
  opacity: 1;
}

.gallery-controls {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  padding-inline: 12px;
  display: flex;
  justify-content: space-between;
  z-index: 10;
  pointer-events: none;
}

.gallery-controls button {
  background: rgba(255, 255, 255, 0.9);
  border: none;
  border-radius: 50%;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition:
    background 0.3s ease,
    transform 0.3s ease,
    box-shadow 0.3s ease;
  pointer-events: auto;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.gallery-controls button:hover {
  background: rgba(255, 255, 255, 1);
  transform: scale(1.1);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}

.gallery-controls button:active {
  transform: scale(0.95);
}

.project-title {
  width: 100%;
  text-align: center;
  font-size: 1.125rem;
  font-weight: 600;
  z-index: 10;
  display: block;
  margin-bottom: 20px;
}

.project-description {
  width: 720px;
  max-width: 100%;
  margin-top: 40px;
  text-align: center;
  z-index: 10;
  opacity: 0.9;
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
}

@media (max-width: 1279px) {
  .gallery-container {
    position: relative;
    display: block;
    height: 550px;
  }

  .gallery-item {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    opacity: 0;
    z-index: 1;
    border-radius: var(--ws-rounded);
    transition: all 600ms cubic-bezier(0.4, 0, 0.2, 1);
    transform: translateX(100%);
  }
  .gallery-item-1 {
    width: 100%;
    left: 0;
    opacity: 0;
    transform: translateX(-100%);
    z-index: 1;
  }

  .gallery-item-2 {
    width: 100%;
    left: 0;
    opacity: 0;
    transform: translateX(-100%);
    z-index: 1;
  }

  .gallery-item-3 {
    width: 100%;
    left: 0;
    opacity: 1;
    transform: translateX(0);
    z-index: 2;
    box-shadow: none;
    position: relative;
  }

  .gallery-item-4 {
    width: 100%;
    left: 0;
    opacity: 0;
    transform: translateX(100%);
    z-index: 1;
  }

  .gallery-item-5 {
    width: 100%;
    left: 0;
    opacity: 0;
    transform: translateX(100%);
    z-index: 1;
  }

  .project-description {
    width: 100%;
    padding: 0 20px;
  }
}

.img-pixel {
  image-rendering: pixelated;
  opacity: 0.9;
  transition: opacity 200ms ease;
}

@media (prefers-reduced-motion: reduce) {
  .img-pixel {
    transition: none;
  }
}
@media (max-width: 768px) {
  .gallery-container {
    height: 400px;
  }
  .gallery-controls button {
    width: 40px;
    height: 40px;
  }
}
@media (min-width: 1280px) {
  .gallery-item-1 {
    width: 480px;
    height: 292.4px;
    left: 20%;
    opacity: 1;
    transform: translateX(-50%);
    z-index: 1;
  }

  .gallery-item-2,
  .gallery-item-4 {
    width: 742px;
    height: 452px;
    opacity: 1;
    z-index: 2;
  }

  .gallery-item-2 {
    left: 35%;
    transform: translateX(-50%);
  }

  .gallery-item-3 {
    box-shadow: -2px 5px 33px 6px rgba(0, 0, 0, 0.35);
    width: 946.02px;
    height: 568.79px;
    opacity: 1;
    left: 50%;
    transform: translateX(-50%);
    z-index: 5;
  }

  .gallery-item-4 {
    left: 65%;
    transform: translateX(-50%);
  }

  .gallery-item-5 {
    width: 480px;
    height: 292.4px;
    left: 80%;
    opacity: 1;
    transform: translateX(-50%);
    z-index: 1;
  }
}
</style>
