<script setup>
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from "vue";
import { useNamespace, useVirtualScroll } from "@yh-ui/hooks";
import { useComponentTheme } from "@yh-ui/theme";
import YhAiBubble from "../../ai-bubble/src/ai-bubble.vue";
import { aiBubbleListProps } from "./ai-bubble-list";
defineOptions({
  name: "YhAiBubbleList"
});
const props = defineProps(aiBubbleListProps);
const ns = useNamespace("ai-bubble-list");
const { themeStyle } = useComponentTheme(
  "ai-bubble-list",
  computed(() => props.themeOverrides)
);
const measuredHeight = ref(0);
let containerResizeObserver = null;
const resolvedContainerHeight = computed(() => {
  if (typeof props.height === "number") return props.height;
  if (typeof props.height === "string" && props.height.endsWith("px")) {
    return parseInt(props.height, 10);
  }
  return measuredHeight.value || 400;
});
const { visibleItems, totalHeight, offsetY, startIndex, onScroll, scrollToIndex, containerRef } = useVirtualScroll({
  items: computed(() => props.items),
  itemHeight: props.itemHeight,
  containerHeight: resolvedContainerHeight,
  overscan: 5
});
const scrollRef = containerRef;
const scrollToBottom = async () => {
  if (!props.autoScroll) return;
  await nextTick();
  if (props.virtualScroll) {
    scrollToIndex(props.items.length - 1);
  } else if (scrollRef.value) {
    scrollRef.value.scrollTop = scrollRef.value.scrollHeight;
  }
};
watch(
  () => props.items,
  () => {
    scrollToBottom();
  },
  { deep: true }
);
onMounted(() => {
  if (scrollRef.value) {
    measuredHeight.value = scrollRef.value.clientHeight;
    if (typeof window !== "undefined" && "ResizeObserver" in window) {
      containerResizeObserver = new ResizeObserver((entries) => {
        for (const entry of entries) {
          measuredHeight.value = entry.contentRect.height;
        }
      });
      containerResizeObserver.observe(scrollRef.value);
    }
  }
  if (props.items.length > 0) {
    scrollToBottom();
  }
});
onBeforeUnmount(() => {
  if (containerResizeObserver) {
    containerResizeObserver.disconnect();
    containerResizeObserver = null;
  }
});
defineExpose({
  scrollToBottom,
  scrollToIndex,
  scrollRef
});
</script>

<template>
  <div
    :class="[ns.b(), ns.is('virtual', virtualScroll)]"
    :style="[themeStyle, {
  height: typeof height === 'number' ? height + 'px' : height
}]"
    ref="scrollRef"
    @scroll="virtualScroll ? onScroll($event) : void 0"
  >
    <!-- 虚拟滚动模式 -->
    <template v-if="virtualScroll">
      <div :class="ns.e('virtual-phantom')" :style="{
  height: totalHeight + 'px'
}"></div>
      <div :class="ns.e('virtual-content')" :style="{
  transform: `translateY(${offsetY}px)`
}">
        <div
          v-for="(item, index) in visibleItems"
          :key="item.id || startIndex + index"
          :class="ns.e('item')"
        >
          <slot name="bubble" :item="item" :index="startIndex + index">
            <yh-ai-bubble v-bind="item" />
          </slot>
        </div>
      </div>
    </template>

    <!-- 普通滚动模式 -->
    <div v-else :class="ns.e('content')">
      <div
        v-for="(item, index) in items"
        :key="item.id || index"
        :class="ns.e('item')"
      >
        <slot name="bubble" :item="item" :index="index">
          <yh-ai-bubble v-bind="item" />
        </slot>
      </div>
    </div>

    <!-- 加载中状态 -->
    <div v-if="loading" :class="ns.e('loading')">
      <slot name="loading">
        <yh-ai-bubble role="assistant" loading variant="borderless" />
      </slot>
    </div>
  </div>
</template>

<style>
@charset "UTF-8";
/**
 * YH-UI Sass Variables
 * 原具体的 CSS 变量输出规则 (:root, html.dark 等) 已移至 root.scss，以防止各组件样式编译时产生重复的全局变量 CSS 冗余。
 */
.yh-ai-bubble-list {
  display: flex;
  flex-direction: column;
  width: 100%;
  overflow-y: auto;
  position: relative;
  scroll-behavior: smooth;
}
.yh-ai-bubble-list__content {
  display: flex;
  flex-direction: column;
  padding: var(--yh-spacing-md);
  gap: var(--yh-spacing-md);
}

.yh-ai-bubble-list__virtual-phantom {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  z-index: -1;
}

.yh-ai-bubble-list__virtual-content {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  padding: var(--yh-spacing-md);
  display: flex;
  flex-direction: column;
  gap: var(--yh-spacing-md);
}

.yh-ai-bubble-list__loading {
  display: flex;
  justify-content: center;
  padding: var(--yh-spacing-md) 0;
}
</style>
