<script lang="ts" setup>
import type { Component } from "vue";

import { useScroll, useWindowSize, useDebounceFn } from "@vueuse/core";

const { locale } = useI18n();

// Define props interface
interface TabData {
  value: string;
  title: string;
  component: string | Component;
  props?: Record<string, unknown>; // Optional props to pass to the component
}

interface Props {
  tabsData: TabData[];
  description?: boolean;
  centeredContent?: boolean;
}

const {
  tabsData,
  description = false,
  centeredContent = true,
} = defineProps<Props>();

// Template refs for scroll areas
const tabsListRef = ref<HTMLElement | { $el: HTMLElement }>();

// Scroll composables for tabs scroll area with initial empty states
const tabsArrivedState = ref({
  top: true,
  bottom: true,
  left: true,
  right: true,
});

// Store scroll watcher cleanup function
let scrollWatcherCleanup: (() => void) | null = null;

// Get reactive window size
const { width } = useWindowSize();

// Function to initialize or reinitialize scroll watchers
const initializeScrollWatcher = () => {
  // Clean up existing watcher
  if (scrollWatcherCleanup) {
    scrollWatcherCleanup();
    scrollWatcherCleanup = null;
  }

  if (tabsListRef.value) {
    const scrollElement = getScrollElement(tabsListRef.value);
    // Validate that scrollElement is a valid DOM element
    if (scrollElement) {
      try {
        const { arrivedState: tabsScroll } = useScroll(scrollElement, {
          offset: { top: 10, bottom: 10, left: 10, right: 10 },
        });

        const stopWatcher = watch(
          tabsScroll,
          (newState) => {
            tabsArrivedState.value = newState;
          },
          { immediate: true },
        );

        scrollWatcherCleanup = stopWatcher;
      } catch (error) {
        console.warn("Failed to initialize tabs scroll watcher:", error);
      }
    }
  }
};

// Create debounced function for handling window resize
const debouncedInitializeScrollWatcher = useDebounceFn(() => {
  initializeScrollWatcher();
}, 150);

// Watch for window width changes and reinitialize scroll watcher
watch(width, () => {
  // Use nextTick to ensure DOM has updated after width change
  nextTick(() => {
    debouncedInitializeScrollWatcher();
  });
});

// Initialize scroll watchers after component is mounted
onMounted(() => {
  // Use nextTick to ensure DOM is fully rendered
  nextTick(() => {
    initializeScrollWatcher();
  });
});

// Cleanup on unmount
onUnmounted(() => {
  if (scrollWatcherCleanup) {
    scrollWatcherCleanup();
  }
});

// Helper function to get the actual DOM element from a ref
const getScrollElement = (
  ref: HTMLElement | { $el: HTMLElement } | null | undefined,
): HTMLElement | null => {
  if (!ref) return null;

  // If it's a Vue component with $el property
  if (
    typeof ref === "object" &&
    "$el" in ref &&
    ref.$el instanceof HTMLElement
  ) {
    return ref.$el;
  }

  // If it's already an HTMLElement
  if (ref instanceof HTMLElement) {
    return ref;
  }

  return null;
};

// Computed classes for fade effects - only horizontal scrolling for tabs
const tabsScrollClasses = computed(() => {
  const canScrollLeft = !tabsArrivedState.value.left;
  const canScrollRight = !tabsArrivedState.value.right;
  const isRTL = locale.value === "ar";

  // For RTL, the scroll behavior is reversed
  if (isRTL) {
    return {
      "scroll-fade-left-rtl": canScrollLeft,
      "scroll-fade-right-rtl": canScrollRight,
      "scroll-fade-both-horizontal-rtl": canScrollLeft && canScrollRight,
    };
  } else {
    return {
      "scroll-fade-left": canScrollLeft,
      "scroll-fade-right": canScrollRight,
      "scroll-fade-both-horizontal": canScrollLeft && canScrollRight,
    };
  }
});

// Scroll functions
const scrollTabs = (direction: "left" | "right") => {
  if (!tabsListRef.value) return;

  // Get the actual DOM element from the Vue component
  const scrollElement = getScrollElement(tabsListRef.value);
  if (!scrollElement || typeof scrollElement.scrollBy !== "function") {
    console.warn("Invalid scroll element for tabs");
    return;
  }

  const scrollAmount = 200; // pixels to scroll

  try {
    if (direction === "left") {
      scrollElement.scrollBy({ left: -scrollAmount, behavior: "smooth" });
    } else if (direction === "right") {
      scrollElement.scrollBy({ left: scrollAmount, behavior: "smooth" });
    }
  } catch (error) {
    console.warn("Failed to scroll tabs:", error);
  }
};
</script>

<template>
  <Tabs
    v-if="tabsData && tabsData.length > 0"
    orientation="horizontal"
    :default-value="tabsData[0].value"
    class="w-full"
  >
    <div class="flex flex-col gap-6">
      <!-- Tabs Navigation -->
      <div v-if="tabsData.length > 1" class="flex w-full justify-center">
        <div class="relative container mx-auto flex justify-center px-4">
          <!-- Scroll Indicators for Tabs -->

          <ClientOnly>
            <div class="pointer-events-none absolute inset-0 z-10">
              <!-- Left arrow (or right in RTL) -->
              <div
                v-if="!tabsArrivedState.left"
                class="bg-surface-background hover:bg-surface-background/90 border-surface-border pointer-events-auto absolute top-1/2 -translate-y-1/2 transform animate-pulse cursor-pointer rounded-full border p-2 shadow-lg backdrop-blur-sm transition-colors hover:shadow-xl"
                :class="locale === 'ar' ? 'right-2' : 'left-2'"
                @click="scrollTabs(locale === 'ar' ? 'right' : 'left')"
              >
                <SvgArrowLeftIcon
                  v-if="locale !== 'ar'"
                  class="text-foreground"
                />
                <SvgArrowRightIcon v-else class="text-foreground" />
              </div>
              <!-- Right arrow (or left in RTL) -->
              <div
                v-if="!tabsArrivedState.right"
                class="bg-surface-background hover:bg-surface-background/90 border-surface-border pointer-events-auto absolute top-1/2 -translate-y-1/2 transform animate-pulse cursor-pointer rounded-full border p-2 shadow-lg backdrop-blur-sm transition-colors hover:shadow-xl"
                :class="locale === 'ar' ? 'left-2' : 'right-2'"
                @click="scrollTabs(locale === 'ar' ? 'left' : 'right')"
              >
                <SvgArrowRightIcon
                  v-if="locale !== 'ar'"
                  class="text-foreground"
                />
                <SvgArrowLeftIcon v-else class="text-foreground" />
              </div>
            </div>
          </ClientOnly>
          <TabsList
            ref="tabsListRef"
            :dir="locale === 'ar' ? 'rtl' : 'ltr'"
            class="rounded-ws-rounded ws-no-scrollbar tabs-gradient-border flex h-auto w-fit max-w-full flex-row justify-start gap-[4px] overflow-x-auto overflow-y-visible p-0"
            :class="tabsScrollClasses"
          >
            <TabsTrigger
              v-for="tab in tabsData"
              :key="tab.value"
              :value="tab.value"
              :gradient="true"
              class="rounded-ws-rounded min-h-[48px] w-auto flex-shrink-0 flex-grow-0 cursor-pointer border-transparent bg-transparent px-10 transition-all duration-300"
            >
              <div class="text-center">
                <span
                  class="text-base leading-6 font-medium whitespace-nowrap"
                  >{{ tab.title }}</span
                >
              </div>
            </TabsTrigger>
          </TabsList>
        </div>
      </div>
      <div
        v-if="description"
        class="container mx-auto flex justify-center px-4"
      >
        <p
          class="dark-text-gradient mx-auto text-center text-[1.125rem] md:w-[712px]"
        >
          {{ $t("projectStages.description") }}
        </p>
      </div>
      <div
        :class="centeredContent ? 'container mx-auto px-4' : ''"
        class="w-full"
      >
        <TabsContent
          v-for="tab in tabsData"
          :key="tab.value"
          :value="tab.value"
          :dir="locale === 'ar' ? 'rtl' : 'ltr'"
        >
          <Transition name="tab-content" mode="out-in" appear>
            <component
              :is="tab.component"
              :key="tab.value"
              v-bind="tab.props || {}"
            />
          </Transition>
        </TabsContent>
      </div>
    </div>
  </Tabs>
  <div v-else class="w-full text-center">
    <EmptyState size="100%" :custom-message="$t('emptyState')" />
  </div>
</template>

<style scoped>
.tabs-gradient-border {
  position: relative;
  border: 1px solid transparent;
  background:
    linear-gradient(var(--surface-background), var(--surface-background))
      padding-box,
    var(--tabs-border-gradient) border-box;
  border-radius: var(--ws-rounded, 0.375rem);
}

.scroll-fade-left {
  -webkit-mask: linear-gradient(90deg, transparent 0%, black 4%, black 100%);
  mask: linear-gradient(90deg, transparent 0%, black 4%, black 100%);
}

.scroll-fade-right {
  -webkit-mask: linear-gradient(90deg, black 0%, black 96%, transparent 100%);
  mask: linear-gradient(90deg, black 0%, black 96%, transparent 100%);
}

.scroll-fade-both-horizontal {
  -webkit-mask: linear-gradient(
    90deg,
    transparent 0%,
    black 4%,
    black 96%,
    transparent 100%
  );
  mask: linear-gradient(
    90deg,
    transparent 0%,
    black 4%,
    black 96%,
    transparent 100%
  );
}

.scroll-fade-left-rtl {
  -webkit-mask: linear-gradient(270deg, transparent 0%, black 4%, black 100%);
  mask: linear-gradient(270deg, transparent 0%, black 4%, black 100%);
}

.scroll-fade-right-rtl {
  -webkit-mask: linear-gradient(270deg, black 0%, black 96%, transparent 100%);
  mask: linear-gradient(270deg, black 0%, black 96%, transparent 100%);
}

.scroll-fade-both-horizontal-rtl {
  -webkit-mask: linear-gradient(
    270deg,
    transparent 0%,
    black 4%,
    black 96%,
    transparent 100%
  );
  mask: linear-gradient(
    270deg,
    transparent 0%,
    black 4%,
    black 96%,
    transparent 100%
  );
}

.tab-content-enter-active,
.tab-content-leave-active {
  transition: all 0.3s ease-in-out;
}

.tab-content-enter-from {
  opacity: 0;
  transform: translateY(16px);
}

.tab-content-leave-to {
  opacity: 0;
  transform: translateY(-16px);
}

.tab-content-enter-to,
.tab-content-leave-from {
  opacity: 1;
  transform: translateY(0);
}
</style>
