<script lang="ts" setup>
import { useScroll, useWindowSize, useDebounceFn } from "@vueuse/core";
import type { ServiceItem } from "~/types/Tabs";

const { locale } = useI18n();

// Ensure services prop is valid to prevent runtime errors
const props = defineProps<{ services: ServiceItem[] }>();
const safeServices = computed(() => props.services || []);

const tabsListRef = ref<HTMLElement | { $el: HTMLElement }>();
const currentTabContentRef = ref<HTMLElement | { $el: HTMLElement }>();

const tabsArrivedState = ref({
  top: true,
  bottom: true,
  left: true,
  right: true,
});

const contentArrivedState = ref({
  top: true,
  bottom: true,
});

const { width } = useWindowSize();
const isMobile = computed(() => width.value < 1024);

// Prevent layout shift by providing stable initial state
const isHydrated = ref(false);

const getScrollElement = (
  ref: HTMLElement | { $el: HTMLElement } | null | undefined,
): HTMLElement | null => {
  if (!ref) return null;

  if (
    typeof ref === "object" &&
    "$el" in ref &&
    ref.$el instanceof HTMLElement
  ) {
    return ref.$el;
  }

  if (ref instanceof HTMLElement) {
    return ref;
  }

  return null;
};

// Store scroll watcher cleanup functions
const scrollWatcherCleanup = {
  tabs: null as (() => void) | null,
  content: null as (() => void) | null,
};

const initializeScrollWatcher = (
  elementRef: HTMLElement | { $el: HTMLElement } | null | undefined,
  stateRef: Ref<{
    top: boolean;
    bottom: boolean;
    left?: boolean;
    right?: boolean;
  }>,
  offset: { top?: number; bottom?: number; left?: number; right?: number },
  cleanupKey: "tabs" | "content",
) => {
  // Clean up existing watcher
  if (scrollWatcherCleanup[cleanupKey]) {
    scrollWatcherCleanup[cleanupKey]!();
    scrollWatcherCleanup[cleanupKey] = null;
  }

  const scrollElement = getScrollElement(elementRef);
  if (!scrollElement) return;

  try {
    const { arrivedState } = useScroll(scrollElement, { offset });
    const stopWatcher = watch(
      arrivedState,
      (newState) => (stateRef.value = newState),
      {
        immediate: true,
      },
    );
    scrollWatcherCleanup[cleanupKey] = stopWatcher;
  } catch (error) {
    console.warn("Failed to initialize scroll watcher:", error);
  }
};

// Function to reinitialize all scroll watchers
const reinitializeScrollWatchers = () => {
  initializeScrollWatcher(
    tabsListRef.value,
    tabsArrivedState,
    { top: 10, bottom: 10, left: 10, right: 10 },
    "tabs",
  );

  initializeScrollWatcher(
    currentTabContentRef.value,
    contentArrivedState,
    { top: 10, bottom: 10 },
    "content",
  );
};

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

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

onMounted(() => {
  isHydrated.value = true;
  nextTick(() => {
    reinitializeScrollWatchers();
  });
});

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

const tabsScrollClasses = computed(() => {
  // Only apply classes after hydration to prevent layout shift
  if (!isHydrated.value) return {};

  if (isMobile.value) {
    const canScrollLeft = !tabsArrivedState.value.left;
    const canScrollRight = !tabsArrivedState.value.right;
    const isRTL = locale.value === "ar";

    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,
      };
    }
  } else {
    return {
      "scroll-fade-top": !tabsArrivedState.value.top,
      "scroll-fade-bottom": !tabsArrivedState.value.bottom,
      "scroll-fade-both":
        !tabsArrivedState.value.top && !tabsArrivedState.value.bottom,
    };
  }
});

const contentScrollClasses = computed(() => {
  // Only apply classes after hydration to prevent layout shift
  if (!isHydrated.value) return {};

  return {
    "scroll-fade-top": !contentArrivedState.value.top,
    "scroll-fade-bottom": !contentArrivedState.value.bottom,
    "scroll-fade-both":
      !contentArrivedState.value.top && !contentArrivedState.value.bottom,
  };
});

const scrollElement = (
  elementRef: typeof tabsListRef | typeof currentTabContentRef,
  direction: "up" | "down" | "left" | "right",
  amount = 200,
) => {
  if (!elementRef.value) return;

  const element = getScrollElement(elementRef.value);
  if (!element?.scrollBy) {
    console.warn("Invalid scroll element");
    return;
  }

  try {
    const scrollOptions: ScrollToOptions = { behavior: "smooth" };

    if (direction === "up") scrollOptions.top = -amount;
    else if (direction === "down") scrollOptions.top = amount;
    else if (direction === "left") scrollOptions.left = -amount;
    else if (direction === "right") scrollOptions.left = amount;

    element.scrollBy(scrollOptions);
  } catch (error) {
    console.warn("Failed to scroll:", error);
  }
};

const scrollTabs = (direction: "up" | "down" | "left" | "right") =>
  scrollElement(tabsListRef, direction);

const scrollContent = (direction: "up" | "down" | "left" | "right") =>
  scrollElement(currentTabContentRef, direction);
</script>

<template>
  <div
    v-if="safeServices.length === 0"
    class="flex min-h-[29.5625rem] w-full items-center justify-center"
  >
    <p class="text-muted-foreground">
      {{ $t("noServicesAvailable") || "No services available" }}
    </p>
  </div>
  <Tabs
    v-else
    orientation="vertical"
    :default-value="safeServices[0]?.value"
    class="min-h-[29.5625rem] w-full"
  >
    <div
      class="flex flex-col gap-2 lg:flex-row lg:gap-6 rtl:lg:flex-row-reverse"
    >
      <div class="relative w-full lg:max-w-[19.8125rem]">
        <ClientOnly fallback-tag="div">
          <template #fallback>
            <!-- Fallback to prevent layout shift - reserve space for scroll buttons -->
            <div class="pointer-events-none absolute inset-0 z-10">
              <!-- Reserve space for potential scroll buttons without showing them -->
              <div
                class="absolute top-2 left-1/2 h-10 w-10 -translate-x-1/2 transform rounded-full p-2 opacity-0"
              />
              <div
                class="absolute bottom-2 left-1/2 h-10 w-10 -translate-x-1/2 transform rounded-full p-2 opacity-0"
              />
            </div>
          </template>
          <div
            v-if="!isMobile && isHydrated"
            class="pointer-events-none absolute inset-0 z-10"
          >
            <div
              v-if="!tabsArrivedState.top"
              class="bg-surface-background hover:bg-surface-background/90 border-surface-border pointer-events-auto absolute top-2 left-1/2 -translate-x-1/2 transform animate-pulse cursor-pointer rounded-full border p-2 shadow-lg backdrop-blur-sm transition-colors hover:shadow-xl"
              @click="scrollTabs('up')"
            >
              <SvgArrowUpIcon class="text-foreground" />
            </div>
            <div
              v-if="!tabsArrivedState.bottom"
              class="bg-surface-background hover:bg-surface-background/90 border-surface-border pointer-events-auto absolute bottom-2 left-1/2 -translate-x-1/2 transform animate-pulse cursor-pointer rounded-full border p-2 shadow-lg backdrop-blur-sm transition-colors hover:shadow-xl"
              @click="scrollTabs('down')"
            >
              <SvgArrowDownIcon class="text-foreground" />
            </div>
          </div>

          <div
            v-else-if="isMobile && isHydrated"
            class="pointer-events-none absolute inset-0 z-10"
          >
            <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>
            <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
          id="tabs-container"
          ref="tabsListRef"
          :dir="locale === 'ar' ? 'rtl' : 'ltr'"
          class="rounded-ws-rounded ws-no-scrollbar flex h-auto w-full flex-row gap-3 overflow-x-auto overflow-y-visible bg-transparent transition-[mask] duration-300 will-change-scroll lg:grid lg:h-[29.5625rem] lg:grid-cols-1 lg:flex-col lg:gap-6 lg:overflow-x-visible lg:overflow-y-auto"
          :class="tabsScrollClasses"
        >
          <TabsTrigger
            v-for="tab in safeServices"
            :key="tab.value"
            :value="tab.value"
            :gradient="true"
            class="rounded-ws-rounded bg-surface-background border-surface-border w-full px-4 py-4 lg:py-6 transition-all duration-300"
          >
            <div class="text-center">
              <span class="text-base leading-6 font-medium">{{
                tab.title
              }}</span>
            </div>
          </TabsTrigger>
        </TabsList>
      </div>

      <div class="relative flex-1">
        <ClientOnly fallback-tag="div">
          <template #fallback>
            <!-- Fallback to prevent layout shift - reserve space for content scroll buttons -->
            <div class="pointer-events-none absolute inset-0 z-10">
              <div
                class="absolute top-2 left-1/2 h-10 w-10 -translate-x-1/2 transform rounded-full p-2 opacity-0"
              />
              <div
                class="absolute bottom-2 left-1/2 h-10 w-10 -translate-x-1/2 transform rounded-full p-2 opacity-0"
              />
            </div>
          </template>
          <div
            v-if="isHydrated"
            class="pointer-events-none absolute inset-0 z-10"
          >
            <div
              v-if="!contentArrivedState.top"
              class="bg-surface-background/90 hover:bg-surface-background border-surface-border pointer-events-auto absolute top-2 left-1/2 -translate-x-1/2 transform animate-pulse cursor-pointer rounded-full border p-2 shadow-md backdrop-blur-sm transition-colors hover:shadow-lg"
              @click="scrollContent('up')"
            >
              <SvgArrowUpIcon class="text-foreground/60" />
            </div>
            <div
              v-if="!contentArrivedState.bottom"
              class="bg-surface-background/90 hover:bg-surface-background border-surface-border pointer-events-auto absolute bottom-2 left-1/2 -translate-x-1/2 transform animate-pulse cursor-pointer rounded-full border p-2 shadow-md backdrop-blur-sm transition-colors hover:shadow-lg"
              @click="scrollContent('down')"
            >
              <SvgArrowDownIcon class="text-foreground/60" />
            </div>
          </div>
        </ClientOnly>

        <TabsContent
          v-for="tab in safeServices"
          :key="tab.value"
          :value="tab.value"
        >
          <Card
            :dir="locale === 'ar' ? 'rtl' : 'ltr'"
            class="border-surface-border bg-surface-background min-h-[29.5625rem] gap-0 lg:h-[29.5625rem]"
          >
            <CardHeader class="pb-6">
              <CardTitle class="text-2xl font-bold">
                {{ tab.content.title }}
              </CardTitle>
              <CardDescription class="mt-4 text-[1.125rem] leading-7">
                {{ tab.content.description }}
              </CardDescription>
            </CardHeader>
            <CardContent
              ref="currentTabContentRef"
              class="ws-scrollbar space-y-6 overflow-x-hidden overflow-y-auto transition-[mask] duration-300 will-change-scroll"
              :class="contentScrollClasses"
            >
              <div v-if="tab.content.features" class="space-y-6">
                <div
                  v-for="(feature, index) in tab.content.features"
                  :key="index"
                  class="flex items-center gap-4 pb-2"
                >
                  <span>
                    <SvgCheckMarkIcon />
                  </span>
                  <p class="leading-relaxed">
                    {{ feature.text }}
                  </p>
                </div>
              </div>
            </CardContent>
          </Card>
        </TabsContent>
      </div>
    </div>
  </Tabs>
</template>

<style scoped>
.scroll-fade-top {
  -webkit-mask: linear-gradient(180deg, transparent 0%, black 8%, black 100%);
  mask: linear-gradient(180deg, transparent 0%, black 8%, black 100%);
}

.scroll-fade-bottom {
  -webkit-mask: linear-gradient(180deg, black 0%, black 92%, transparent 100%);
  mask: linear-gradient(180deg, black 0%, black 92%, transparent 100%);
}

.scroll-fade-both {
  -webkit-mask: linear-gradient(
    180deg,
    transparent 0%,
    black 8%,
    black 92%,
    transparent 100%
  );
  mask: linear-gradient(
    180deg,
    transparent 0%,
    black 8%,
    black 92%,
    transparent 100%
  );
}

.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%
  );
}
</style>
