<script setup>
import { useNamespace, useLocale } from "@yh-ui/hooks";
import { ref, computed } from "vue";
import {
  aiSourcesProps,
  aiSourcesEmits
} from "./ai-sources";
import { YhIcon } from "../../icon";
import { YhTooltip } from "../../tooltip";
import { YhDrawer } from "../../drawer";
import { useComponentTheme } from "@yh-ui/theme";
defineOptions({
  name: "YhAiSources"
});
const props = defineProps(aiSourcesProps);
const emit = defineEmits(aiSourcesEmits);
const ns = useNamespace("ai-sources");
const { t } = useLocale();
const { themeStyle } = useComponentTheme("ai-sources", props.themeOverrides);
const isExpanded = ref(false);
const drawerVisible = ref(false);
const activeSource = ref(null);
const highlightedSourceId = ref(null);
const sourceRefs = ref({});
const fileTypeIcons = {
  web: "globe",
  pdf: "file-pdf",
  doc: "file-word",
  xlsx: "file-excel",
  ppt: "presentation",
  txt: "file-txt",
  code: "code",
  default: "document"
};
const getFileIcon = (type) => fileTypeIcons[type ?? "default"] ?? fileTypeIcons.default;
const scoreColor = (score) => {
  if (!score) return "var(--yh-text-color-disabled)";
  if (score >= 0.8) return "var(--yh-color-success)";
  if (score >= 0.6) return "var(--yh-color-primary)";
  if (score >= 0.4) return "var(--yh-color-warning)";
  return "var(--yh-color-danger)";
};
const visibleSources = computed(() => {
  if (isExpanded.value || props.sources.length <= props.maxVisible) {
    return props.sources;
  }
  return props.sources.slice(0, props.maxVisible);
});
const handleClick = (source) => {
  emit("click", source);
  if (props.mode === "badge") {
    activeSource.value = source;
    drawerVisible.value = true;
  }
};
const handleOpen = (e, source) => {
  e.stopPropagation();
  emit("open", source);
  if (source.url) window.open(source.url, "_blank", "noopener");
};
const openDrawer = (source) => {
  activeSource.value = source;
  drawerVisible.value = true;
};
const scrollToSource = (id) => {
  highlightedSourceId.value = id;
  const el = sourceRefs.value[id];
  if (el) {
    el.scrollIntoView({ behavior: "smooth", block: "center" });
    el.classList.add(ns.is("highlighted", true));
    setTimeout(() => {
      el.classList.remove(ns.is("highlighted", true));
      highlightedSourceId.value = null;
    }, 2e3);
  }
};
defineExpose({
  scrollToSource
});
</script>

<template>
  <div :class="[ns.b(), ns.m(mode)]" :style="themeStyle">
    <!-- ── badge 模式：仅显示角标 ── -->
    <template v-if="mode === 'badge'">
      <div :class="ns.e('badge-row')">
        <YhTooltip
          v-for="source in sources"
          :key="source.id"
          placement="top"
          effect="light"
          popper-class="yh-ai-sources__tooltip-popper"
        >
          <button :class="ns.e('badge')" @click="openDrawer(source)">
            <YhIcon v-if="showFileType" :name="getFileIcon(source.fileType)" />
            {{ source.id }}
          </button>

          <template #content>
            <div :class="ns.e('tooltip-content')">
              <div :class="ns.e('tooltip-header')">
                <div :class="ns.e('tooltip-title-wrap')">
                  <YhIcon :name="getFileIcon(source.fileType)" />
                  <span :class="ns.e('tooltip-title')">{{ source.title }}</span>
                </div>
              </div>
              <p v-if="source.excerpt" :class="ns.e('tooltip-excerpt')">{{ source.excerpt }}</p>
              <div v-if="source.source" :class="ns.e('tooltip-source')">
                <YhIcon name="globe" /> {{ source.source }}
              </div>
            </div>
          </template>
        </YhTooltip>
      </div>

      <!-- 抽屉：来源详情 -->
      <YhDrawer
        v-model="drawerVisible"
        :title="t('ai.sources.drawerTitle')"
        size="40%"
        :theme-overrides="themeOverrides"
      >
        <template #title>
          <div :class="ns.e('drawer-title-wrap')">
            <YhIcon name="document" />
            <span>{{ t("ai.sources.drawerTitle") }}</span>
          </div>
        </template>
        <div :class="ns.e('drawer-content')">
          <div
            v-for="source in sources"
            :key="source.id"
            :ref="el => sourceRefs[source.id] = el"
            :class="[ns.e('source-card'), ns.is('active', activeSource?.id === source.id), ns.is('highlighted', highlightedSourceId === source.id)]"
            @click="handleClick(source)"
          >
            <div :class="ns.e('card-header')">
              <div :class="ns.e('card-title-row')">
                <YhIcon :name="getFileIcon(source.fileType)" :class="ns.e('file-icon')" />
                <span :class="ns.e('card-title')">{{ source.title }}</span>
              </div>
              <div :class="ns.e('card-meta')">
                <span v-if="source.source" :class="ns.e('source-name')">{{ source.source }}</span>
                <span
                  v-if="showScore && source.score !== void 0"
                  :class="ns.e('score-badge')"
                  :style="{
  color: scoreColor(source.score)
}"
                >
                  {{ Math.round(source.score * 100) }}%
                  {{ t("ai.sources.relevant") }}
                </span>
              </div>
            </div>
            <p v-if="source.excerpt" :class="ns.e('excerpt')">{{ source.excerpt }}</p>
            <button v-if="source.url" :class="ns.e('open-btn')" @click="handleOpen($event, source)">
              <YhIcon name="arrow-right" />
              {{ t("ai.sources.viewOriginal") }}
            </button>
          </div>
        </div>
      </YhDrawer>
    </template>

    <!-- ── inline 模式：内联气泡列表 ── -->
    <template v-else-if="mode === 'inline'">
      <div :class="ns.e('inline-header')">
        <YhIcon name="document" />
        <span>{{ sources.length }} {{ t("ai.sources.references") }}</span>
      </div>
      <div :class="ns.e('inline-list')">
        <YhTooltip
          v-for="source in visibleSources"
          :key="source.id"
          placement="top"
          effect="light"
          :disabled="!source.excerpt"
          tabindex="-1"
          popper-class="yh-ai-sources__tooltip-popper"
        >
          <div
            :class="[ns.e('inline-item'), ns.is('highlighted', highlightedSourceId === source.id)]"
            :ref="el => sourceRefs[source.id] = el"
            @click="handleClick(source)"
          >
            <span :class="ns.e('inline-index')">{{ source.id }}</span>
            <YhIcon
              v-if="showFileType"
              :name="getFileIcon(source.fileType)"
              :class="ns.e('file-icon')"
            />
            <span :class="ns.e('inline-title')">{{ source.title }}</span>
            <span
              v-if="showScore && source.score !== void 0"
              :class="ns.e('inline-score')"
              :style="{
  color: scoreColor(source.score)
}"
            >
              {{ Math.round(source.score * 100) }}%
            </span>
            <button
              v-if="source.url"
              :class="ns.e('inline-open')"
              @click.stop="handleOpen($event, source)"
            >
              <YhIcon name="launch" />
            </button>
          </div>

          <template #content>
            <div :class="ns.e('tooltip-content')">
              <div :class="ns.e('tooltip-header')">
                <div :class="ns.e('tooltip-title-wrap')">
                  <YhIcon :name="getFileIcon(source.fileType)" />
                  <span :class="ns.e('tooltip-title')">{{ source.title }}</span>
                </div>
                <span
                  v-if="showScore && source.score !== void 0"
                  :class="ns.e('tooltip-score')"
                  :style="{
  color: scoreColor(source.score)
}"
                >
                  {{ Math.round(source.score * 100) }}%
                </span>
              </div>
              <p v-if="source.excerpt" :class="ns.e('tooltip-excerpt')">{{ source.excerpt }}</p>
              <div v-if="source.source" :class="ns.e('tooltip-source')">
                <YhIcon name="globe" /> {{ source.source }}
              </div>
            </div>
          </template>
        </YhTooltip>

        <!-- 展开更多 -->
        <button
          v-if="!isExpanded && sources.length > maxVisible"
          :class="ns.e('expand-btn')"
          @click="isExpanded = true"
        >
          +{{ sources.length - maxVisible }} {{ t("ai.sources.more") }}
          <YhIcon name="arrow-down" />
        </button>
      </div>
    </template>

    <!-- ── card 模式：完整卡片列表 ── -->
    <template v-else>
      <div :class="ns.e('card-list-header')">
        <YhIcon name="document" />
        <span>{{ t("ai.sources.referencedSources") }}</span>
        <span :class="ns.e('count-badge')">{{ sources.length }}</span>
      </div>
      <div :class="ns.e('card-list')">
        <div
          v-for="source in visibleSources"
          :key="source.id"
          :ref="el => sourceRefs[source.id] = el"
          :class="[ns.e('source-card'), ns.is('highlighted', highlightedSourceId === source.id)]"
          @click="handleClick(source)"
        >
          <div :class="ns.e('card-header')">
            <div :class="ns.e('card-title-row')">
              <YhIcon :name="getFileIcon(source.fileType)" :class="ns.e('file-icon')" />
              <span :class="ns.e('card-title')">{{ source.title }}</span>
            </div>
            <div :class="ns.e('card-meta')">
              <span v-if="source.source" :class="ns.e('source-name')">{{ source.source }}</span>
              <span
                v-if="showScore && source.score !== void 0"
                :class="ns.e('score-badge')"
                :style="{
  color: scoreColor(source.score)
}"
              >
                {{ Math.round(source.score * 100) }}% {{ t("ai.sources.relevant") }}
              </span>
            </div>
          </div>
          <p v-if="source.excerpt" :class="ns.e('excerpt')">{{ source.excerpt }}</p>
          <button v-if="source.url" :class="ns.e('open-btn')" @click="handleOpen($event, source)">
            <YhIcon name="arrow-right" />
            {{ t("ai.sources.viewOriginal") }}
          </button>
        </div>

        <button
          v-if="!isExpanded && sources.length > maxVisible"
          :class="ns.e('expand-btn')"
          @click="isExpanded = true"
        >
          {{ t("ai.sources.showAll") }} ({{ sources.length }})
          <YhIcon name="arrow-down" />
        </button>
      </div>
    </template>

    <!-- 额外插槽 -->
    <slot></slot>
  </div>
</template>

<style>
@charset "UTF-8";
/**
 * YH-UI Sass Variables
 * 原具体的 CSS 变量输出规则 (:root, html.dark 等) 已移至 root.scss，以防止各组件样式编译时产生重复的全局变量 CSS 冗余。
 */
.yh-ai-sources--badge .yh-ai-sources__badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.yh-ai-sources__badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 7px;
  border: 1px solid var(--yh-color-primary-light-5);
  border-radius: 100px;
  background: var(--yh-color-primary-light-9);
  color: var(--yh-color-primary);
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
}
.yh-ai-sources__badge .yh-icon {
  font-size: 11px;
}
.yh-ai-sources__badge:hover {
  background: var(--yh-color-primary);
  color: #fff;
  border-color: var(--yh-color-primary);
}

.yh-ai-sources__drawer {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: 380px;
  max-width: 90vw;
  background: var(--yh-bg-color);
  box-shadow: -4px 0 24px rgba(0, 0, 0, 0.12);
  z-index: 2001;
  display: flex;
  flex-direction: column;
}

.yh-ai-sources__drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--yh-border-color-light);
}

.yh-ai-sources__drawer-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  color: var(--yh-text-color-primary);
}

.yh-ai-sources__drawer-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  color: var(--yh-text-color-secondary);
  transition: all 0.15s;
}
.yh-ai-sources__drawer-close:hover {
  background: var(--yh-fill-color);
  color: var(--yh-text-color-primary);
}

.yh-ai-sources__drawer-content {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.yh-ai-sources__drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  z-index: 2000;
}

.yh-ai-sources--inline {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.yh-ai-sources__inline-header {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--yh-text-color-secondary);
  font-weight: 500;
}

.yh-ai-sources__inline-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.yh-ai-sources__inline-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 8px;
  cursor: pointer;
  position: relative;
  transition: background 0.15s;
}
.yh-ai-sources__inline-item:hover {
  background: var(--yh-fill-color-light);
}

.yh-ai-sources__inline-index {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 4px;
  background: var(--yh-color-primary-light-8);
  color: var(--yh-color-primary);
  font-size: 10px;
  font-weight: 700;
  flex-shrink: 0;
}

.yh-ai-sources__file-icon {
  font-size: 13px;
  color: var(--yh-text-color-secondary);
  flex-shrink: 0;
}

.yh-ai-sources__inline-title {
  flex: 1;
  font-size: 13px;
  color: var(--yh-text-color-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.yh-ai-sources__inline-score {
  font-size: 11px;
  font-weight: 600;
  flex-shrink: 0;
}

.yh-ai-sources__inline-open {
  display: flex;
  align-items: center;
  padding: 2px 4px;
  border: none;
  background: transparent;
  color: var(--yh-text-color-secondary);
  cursor: pointer;
  border-radius: 4px;
  opacity: 0;
  transition: all 0.15s;
}
.yh-ai-sources__inline-item:hover .yh-ai-sources__inline-open {
  opacity: 1;
}
.yh-ai-sources__inline-open:hover {
  color: var(--yh-color-primary);
  background: var(--yh-color-primary-light-9);
}

.yh-ai-sources__tooltip-content {
  width: 280px;
  max-width: 90vw;
  /* Redundant styles removed to rely on YhTooltip base styles */
}

.yh-ai-sources__tooltip-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.yh-ai-sources__tooltip-title-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.yh-ai-sources__tooltip-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--yh-text-color-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.yh-ai-sources__tooltip-score {
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.yh-ai-sources__tooltip-excerpt {
  font-size: 12px;
  color: var(--yh-text-color-regular);
  line-height: 1.6;
  margin: 0 0 8px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
}

.yh-ai-sources__tooltip-source {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--yh-text-color-secondary);
}

.yh-ai-sources--card {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.yh-ai-sources__card-list-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--yh-text-color-primary);
  padding-bottom: 4px;
  border-bottom: 1px solid var(--yh-border-color-extra-light);
}

.yh-ai-sources__count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 10px;
  background: var(--yh-color-primary-light-8);
  color: var(--yh-color-primary);
  font-size: 11px;
  font-weight: 700;
}

.yh-ai-sources__card-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.yh-ai-sources__source-card {
  padding: 12px 14px;
  border: 1px solid var(--yh-border-color-extra-light);
  border-radius: 10px;
  background: var(--yh-bg-color);
  cursor: pointer;
  transition: all 0.2s;
}
.yh-ai-sources__source-card:hover {
  border-color: var(--yh-color-primary-light-5);
  background: var(--yh-color-primary-light-9);
}
.yh-ai-sources__source-card.is-active {
  border-color: var(--yh-color-primary-light-5);
  background: var(--yh-color-primary-light-9);
}
.yh-ai-sources__source-card.is-highlighted {
  border-color: var(--yh-color-primary) !important;
  background-color: var(--yh-color-primary-light-9) !important;
  box-shadow: 0 0 0 2px var(--yh-color-primary-light-8) !important;
  animation: yh-source-highlight-pulse 2s ease-in-out;
}

.yh-ai-sources__card-header {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 6px;
}

.yh-ai-sources__card-title-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.yh-ai-sources__card-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--yh-text-color-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.yh-ai-sources__card-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}

.yh-ai-sources__source-name {
  font-size: 11px;
  color: var(--yh-text-color-secondary);
}

.yh-ai-sources__score-badge {
  font-size: 11px;
  font-weight: 600;
}

.yh-ai-sources__excerpt {
  font-size: 12px;
  color: var(--yh-text-color-regular);
  line-height: 1.6;
  margin: 0 0 8px;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.yh-ai-sources__open-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border: none;
  border-radius: 5px;
  background: transparent;
  color: var(--yh-color-primary);
  font-size: 12px;
  cursor: pointer;
  transition: background 0.15s;
}
.yh-ai-sources__open-btn:hover {
  background: var(--yh-color-primary-light-8);
}

.yh-ai-sources__expand-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px;
  border: 1px dashed var(--yh-border-color);
  border-radius: 8px;
  background: transparent;
  color: var(--yh-text-color-secondary);
  font-size: 12px;
  cursor: pointer;
  transition: all 0.15s;
}
.yh-ai-sources__expand-btn:hover {
  border-color: var(--yh-color-primary);
  color: var(--yh-color-primary);
  background: var(--yh-color-primary-light-9);
}

@keyframes yh-source-highlight-pulse {
  0% {
    transform: scale(1);
  }
  10% {
    transform: scale(1.02);
  }
  20% {
    transform: scale(1);
  }
  30% {
    transform: scale(1.01);
  }
  40% {
    transform: scale(1);
  }
}
</style>
