<template>
  <div class="faq-content">
    <div v-if="isLoading" class="flex justify-center py-12">
      <div class="animate-spin h-8 w-8 border-2 border-blue-400 border-t-transparent rounded-full"></div>
    </div>

    <div v-else class="p-8">
      <!-- 分类和搜索区域 -->
      <div class="mb-8 space-y-6">
        <!-- 分类选择 -->
        <div class="flex flex-wrap gap-2">
          <button
            v-for="category in categoriesList"
            :key="category"
            @click="handleCategoryFilter(category)"
            class="px-4 py-2 rounded-md text-sm font-medium transition-colors duration-200 border"
            :class="{
              'bg-blue-600 text-white border-blue-600': selectedCategory === category,
              'bg-gray-700 text-gray-300 border-gray-600 hover:bg-gray-600': selectedCategory !== category,
            }"
          >
            {{ category }}
          </button>
        </div>

        <!-- 搜索框 -->
        <div class="relative max-w-md">
          <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
            <svg class="h-5 w-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
            </svg>
          </div>
          <input
            v-model="searchTerm"
            type="search"
            :placeholder="t('faq.searchPlaceholder')"
            class="w-full pl-10 pr-10 py-3 border border-gray-600 rounded-md text-white bg-gray-700 placeholder-gray-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none"
          />
          <button
            v-if="searchTerm"
            @click="clearSearch"
            class="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-gray-300"
          >
            <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
            </svg>
          </button>
        </div>
      </div>

      <!-- FAQ列表 -->
      <div class="space-y-3">
        <div
          v-for="faq in filteredFaqs"
          :key="generateFaqKey(faq)"
          class="border border-gray-600 rounded-lg overflow-hidden"
        >
          <div
            class="flex items-center justify-between p-6 cursor-pointer hover:bg-gray-700 transition-colors duration-200"
            @click="toggleFaq(faq)"
          >
            <div class="text-white font-medium flex-1 text-left">
              <template
                v-for="(part, i) in highlightKeyword(faq.title)"
                :key="i"
              >
                <span v-if="typeof part === 'string'">{{ part }}</span>
                <component v-else :is="part"></component>
              </template>
            </div>
            <div
              class="text-gray-400 transition-transform duration-200 ml-4 flex-shrink-0"
              :class="{ 'rotate-180': isFaqExpanded(faq) }"
            >
              <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
              </svg>
            </div>
          </div>
          
          <div 
            v-if="isFaqExpanded(faq)" 
            class="px-6 pb-6 border-t border-gray-600 bg-gray-750"
          >
            <div class="pt-6">
              <ContentRenderer
                class="prose prose-invert prose-sm max-w-none"
                :value="{ body: faq.content }"
                v-highlight="searchTerm.trim()"
              />
            </div>
          </div>
        </div>

        <div
          v-if="filteredFaqs.length === 0"
          class="text-center text-gray-400 py-16"
        >
          <div class="mb-4">
            <svg class="mx-auto h-12 w-12 text-gray-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
            </svg>
          </div>
          <p class="text-lg font-medium text-white mb-2">{{ t("faq.noResults") }}</p>
          <p class="text-sm text-gray-500">尝试调整搜索条件或选择不同的分类</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * FAQ内容组件
 * 专业的常见问题解答展示组件
 */
import { useErrorHandler } from "~/composables/useErrorHandler";
import { queryCollection } from "#imports";

const { error, isLoading, wrapAsync } = useErrorHandler();
const { t, locale } = useI18n();

// FAQ数据接口
interface FAQ {
  category: string;
  title: string;
  content: any;
  sort: number;
  id?: string;
}

// 响应式数据
const faqs = ref<FAQ[]>([]);
const categoriesList = ref<string[]>([]);
const selectedCategory = ref("");
const expandedFaqKeys = ref<Set<string>>(new Set());
const searchTerm = ref("");

// 使用 queryCollection 加载FAQ数据
const { data: faqData } = await useAsyncData(
  "faqs",
  async () => {
    try {
      const content = await queryCollection("content")
        .where("path", "LIKE", `/faq/${locale.value}/%`)
        .all();

      if (!content || !Array.isArray(content)) {
        console.error("No FAQ content found or invalid format:", content);
        return [];
      }

      const faqItems = content.map((item: any) => {
        return {
          category: item.meta?.category || "",
          title: item.title || "",
          content: item.body || "",
          sort: item.meta?.sort || 0,
        };
      });

      return faqItems.sort((a, b) => a.sort - b.sort);
    } catch (error) {
      console.error("Error loading FAQ content:", error);
      return [];
    }
  },
  {
    server: true,
    lazy: false,
    immediate: true,
    watch: [locale],
  }
);

// 处理FAQ数据变化
watchEffect(() => {
  if (faqData.value) {
    isLoading.value = true;
    try {
      const allOption: string =
        locale.value === "en"
          ? "All"
          : locale.value === "zh"
          ? "全部"
          : "すべて";

      const uniqueCategories = [
        ...new Set(faqData.value.map((faq: FAQ) => faq.category)),
      ]
        .filter((category) => category)
        .sort();

      categoriesList.value = [allOption, ...uniqueCategories];
      selectedCategory.value = categoriesList.value[0];
    } catch (err) {
      console.error("Error processing FAQ data:", err);
      error.value = new Error(t("faq.processError"));
    } finally {
      isLoading.value = false;
    }
  }
});

// 过滤后的FAQ列表
const filteredFaqs = computed(() => {
  if (!faqData.value) {
    return [];
  }

  let filtered = [...faqData.value];

  // 按分类过滤
  const allOption: string =
    locale.value === "en"
      ? "All"
      : locale.value === "zh"
      ? "全部"
      : "すべて";

  if (selectedCategory.value && selectedCategory.value !== allOption) {
    filtered = filtered.filter((faq) => faq.category === selectedCategory.value);
  }

  // 按搜索词过滤
  if (searchTerm.value.trim()) {
    const search = searchTerm.value.trim().toLowerCase();
    filtered = filtered.filter((faq) =>
      faq.title.toLowerCase().includes(search)
    );
  }

  return filtered;
});

/**
 * 生成FAQ的唯一标识
 */
const generateFaqKey = (faq: FAQ): string => {
  return `${faq.category}-${faq.title}-${faq.sort}`;
};

/**
 * 检查FAQ是否展开
 */
const isFaqExpanded = (faq: FAQ): boolean => {
  return expandedFaqKeys.value.has(generateFaqKey(faq));
};

/**
 * 切换FAQ展开状态
 */
const toggleFaq = (faq: FAQ): void => {
  const key = generateFaqKey(faq);
  if (expandedFaqKeys.value.has(key)) {
    expandedFaqKeys.value.delete(key);
  } else {
    expandedFaqKeys.value.add(key);
  }
};

/**
 * 处理分类过滤
 */
const handleCategoryFilter = (category: string): void => {
  selectedCategory.value = category;
  // 清空展开状态
  expandedFaqKeys.value.clear();
};

/**
 * 清除搜索
 */
const clearSearch = (): void => {
  searchTerm.value = "";
};

/**
 * 高亮关键词
 */
const highlightKeyword = (text: string) => {
  if (!searchTerm.value.trim()) {
    return [text];
  }

  const keyword = searchTerm.value.trim();
  const regex = new RegExp(`(${keyword})`, "gi");
  const parts = text.split(regex);

  return parts.map((part) => {
    if (part.toLowerCase() === keyword.toLowerCase()) {
      return h("mark", { class: "bg-yellow-500/30 text-yellow-200 px-1 rounded" }, part);
    }
    return part;
  });
};

// 自定义指令：高亮搜索结果
const vHighlight = {
  mounted(el: HTMLElement, binding: { value: string }) {
    highlightText(el, binding.value);
  },
  updated(el: HTMLElement, binding: { value: string }) {
    highlightText(el, binding.value);
  },
};

/**
 * 高亮文本中的关键词
 */
const highlightText = (el: HTMLElement, keyword: string): void => {
  if (!keyword || !keyword.trim()) {
    return;
  }

  const walker = document.createTreeWalker(
    el,
    NodeFilter.SHOW_TEXT,
    null
  );

  const nodes: Text[] = [];
  let node: Text | null;

  while ((node = walker.nextNode() as Text)) {
    nodes.push(node);
  }

  nodes.forEach((textNode) => {
    const parent = textNode.parentNode;
    if (!parent || parent.nodeName === "MARK") return;

    const text = textNode.textContent || "";
    const regex = new RegExp(`(${keyword.trim()})`, "gi");

    if (regex.test(text)) {
      const fragment = document.createDocumentFragment();
      const parts = text.split(regex);

      parts.forEach((part) => {
        if (part.toLowerCase() === keyword.trim().toLowerCase()) {
          const mark = document.createElement("mark");
          mark.className = "bg-yellow-500/30 text-yellow-200 px-1 rounded";
          mark.textContent = part;
          fragment.appendChild(mark);
        } else if (part) {
          fragment.appendChild(document.createTextNode(part));
        }
      });

      parent.replaceChild(fragment, textNode);
    }
  });
};
</script>

<style scoped>
/* 过渡效果 */
.transition-colors {
  transition-property: color, background-color, border-color;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

.transition-transform {
  transition-property: transform;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

.duration-200 {
  transition-duration: 200ms;
}

/* 悬停效果 */
.hover\:bg-gray-700:hover {
  background-color: #374151;
}

.hover\:bg-gray-600:hover {
  background-color: #4b5563;
}

.hover\:text-gray-300:hover {
  color: #d1d5db;
}

/* 焦点样式 */
input:focus {
  box-shadow: 0 0 0 1px #3b82f6;
}

/* 高亮样式 */
mark {
  background-color: rgba(234, 179, 8, 0.3);
  color: #fef3c7;
  padding: 2px 4px;
  border-radius: 4px;
}

/* Prose样式覆盖 - 深色主题 */
:deep(.prose) {
  color: #d1d5db;
  max-width: none;
}

:deep(.prose h1),
:deep(.prose h2),
:deep(.prose h3),
:deep(.prose h4),
:deep(.prose h5),
:deep(.prose h6) {
  color: #f9fafb;
  font-weight: 600;
}

:deep(.prose p) {
  margin-top: 1rem;
  margin-bottom: 1rem;
  line-height: 1.625;
  color: #d1d5db;
}

:deep(.prose ul),
:deep(.prose ol) {
  margin-top: 1rem;
  margin-bottom: 1rem;
}

:deep(.prose li) {
  margin-top: 0.5rem;
  margin-bottom: 0.5rem;
  color: #d1d5db;
}

:deep(.prose strong) {
  color: #f9fafb;
  font-weight: 600;
}

:deep(.prose code) {
  color: #f9fafb;
  background-color: #374151;
  padding: 0.125rem 0.25rem;
  border-radius: 0.25rem;
  font-size: 0.875em;
}

:deep(.prose a) {
  color: #60a5fa;
  text-decoration: underline;
}

:deep(.prose a:hover) {
  color: #93c5fd;
}

/* 自定义gray-750背景色 */
.bg-gray-750 {
  background-color: #2d3748;
}

/* 响应式优化 */
@media (max-width: 768px) {
  .flex-wrap {
    gap: 0.5rem;
  }
  
  .px-6 {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}
</style> 