<template>
  <div class="search-page">
    <div class="search-header">
      <h1 class="page-title">{{ $t('search.title') }}</h1>
      <div class="search-bar">
        <el-input
          v-model="keyword"
          class="search-input"
          :placeholder="$t('search-placeholder')"
          :prefix-icon="Search"
          clearable
          @keyup.enter="navigateToQuery(keyword)"
          @clear="handleClear"
        />
        <el-button
          type="primary"
          class="search-button"
          @click="navigateToQuery(keyword)"
        >
          {{ $t('search.search-button') }}
        </el-button>
      </div>
      <p v-if="hasResults" class="search-meta">
        {{ $t('search.results-for', { query: route.query?.query }) }}
      </p>
    </div>

    <div v-if="loading" class="search-state">
      <el-skeleton :rows="4" animated />
    </div>
    <div v-else-if="hasResults" class="search-results">
      <!-- <section -->
      <!--   v-for="section in filteredSections" -->
      <!--   :key="section.indexUid" -->
      <!--   class="search-section" -->
      <!-- > -->
      <!--   <header class="section-header"> -->
      <!--     <h2 class="section-title"> -->
      <!--       {{ getIndexLabel(section.indexUid) }} -->
      <!--       <span class="section-count">{{ -->
      <!--         $t('search.result-count', { count: section.estimatedTotalHits }) -->
      <!--       }}</span> -->
      <!--     </h2> -->
      <!--   </header> -->
      <!--   <div class="section-results"> -->
      <!--     <el-card -->
      <!--       v-for="(hit, hitIndex) in section.hits" -->
      <!--       :key="`${section.indexUid}-${getHitIdentifier(hit, hitIndex)}`" -->
      <!--       class="result-card" -->
      <!--     > -->
      <!--       <NuxtLink -->
      <!--         v-if="resolveHitLink(hit)" -->
      <!--         :to="resolveHitLink(hit) || ''" -->
      <!--         class="result-title" -->
      <!--       > -->
      <!--         {{ getHitTitle(hit) }} -->
      <!--       </NuxtLink> -->
      <!--       <h3 v-else class="result-title">{{ getHitTitle(hit) }}</h3> -->
      <!--       <p v-if="getHitSummary(hit)" class="result-summary"> -->
      <!--         {{ getHitSummary(hit) }} -->
      <!--       </p> -->
      <!--     </el-card> -->
      <!--   </div> -->
      <!-- </section> -->

      <div class="section-results">
        <el-card
          v-for="(hit, hitIndex) in paginatedHits"
          :key="`${getHitIdentifier(hit.content, hitIndex)}`"
          class="result-card"
        >
          <NuxtLink
            v-if="resolveHitLink(hit.content)"
            :to="resolveHitLink(hit.content) || ''"
            class="result-title"
          >
            {{ getHitTitle(hit.content) }}
          </NuxtLink>
          <h3 v-else class="result-title">{{ getHitTitle(hit.content) }}</h3>
          <p v-if="getHitSummary(hit.content)" class="result-summary">
            {{ getHitSummary(hit.content) }}
          </p>
          <p v-if="hit.type" class="result-type">
            <span>内容类型: </span>
            <span class="result-type-name">{{ getIndexLabel(hit.type) }}</span>
          </p>
        </el-card>
      </div>

      <!-- 分页组件 -->
      <div class="pagination-container text-align-center mt-12">
        <el-pagination
          class="justify-center"
          layout="prev, pager, next"
          :current-page="currentPage"
          :page-size="pageSize"
          :total="hits.length"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>
    <div v-else class="search-state">
      <el-empty
        :description="
          route.query.query
            ? $t('search.no-results', { query: route.query?.query })
            : $t('search.no-query')
        "
      />
    </div>
  </div>
</template>

<script setup lang="ts">
  import { Search } from '@element-plus/icons-vue';
  import type { SearchHit, SearchSection } from '~/composables/useMeilisearch';

  const { t } = useI18n();
  const route = useRoute();
  const router = useRouter();
  const localePath = useLocalePath();

  const { getStrapiLocale } = useLocalizations();
  const strapiLocale = getStrapiLocale();

  const { search } = useMeilisearch();

  const loading = ref(true);
  const keyword = ref('');
  const currentPage = ref(1);
  const pageSize = ref(5);
  const sections = ref<SearchSection[]>([]);
  const localeSections = computed(() =>
    sections.value.map((section) => ({
      ...section,
      hits: section.hits.filter(
        (hit) =>
          !hit.locale ||
          String(hit.locale).toLowerCase() === strapiLocale.toLowerCase()
      ),
    }))
  );
  const filteredSections = computed(() =>
    localeSections.value.filter((section) => section.hits.length > 0)
  );
  const hits = computed(() =>
    filteredSections.value.flatMap((item) =>
      item.hits.map((content) => ({ content, type: item.indexUid }))
    )
  );
  const paginatedHits = computed(() => {
    const start = (currentPage.value - 1) * pageSize.value;
    const end = currentPage.value * pageSize.value;
    return hits.value.slice(start, end);
  });
  const activeRequestId = ref(0);

  const indexLabels = computed<Record<string, string>>(() => ({
    production: t('search.sections.production'),
    solution: t('search.sections.solution'),
    support: t('search.sections.support'),
    default: t('search.sections.default'),
  }));

  const getIndexLabel = (indexUid: string) =>
    indexLabels.value[indexUid] || indexLabels.value.default;

  const hasResults = computed(() =>
    localeSections.value.some((section) => section.hits.length > 0)
  );

  const getHitIdentifier = (hit: SearchHit, index: number) => {
    const candidate = [hit.objectID, hit.documentId, hit.id, hit.slug].find(
      (value) =>
        ['string', 'number'].includes(typeof value) && String(value).length > 0
    );
    return candidate != null ? String(candidate) : String(index);
  };

  const getHitTitle = (hit: SearchHit) => {
    const candidate = [
      hit.title,
      hit.name,
      hit.heading,
      hit.documentTitle,
    ].find((value) => typeof value === 'string' && value.trim().length > 0);
    return candidate ? String(candidate) : t('search.untitled');
  };

  const getHitSummary = (hit: SearchHit) => {
    const candidate = [
      hit.summary,
      hit.description,
      hit.snippet,
      hit.content,
      hit.text,
    ].find((value) => typeof value === 'string' && value.trim().length > 0);
    return candidate ? String(candidate) : '';
  };

  const resolveHitLink = (hit: SearchHit) => {
    if (typeof hit.route === 'string' && hit.route.trim().length > 0) {
      return localePath(hit.route);
    }

    const slugCandidate = [hit.slug, hit.documentId, hit.id, hit.objectID].find(
      (value) =>
        ['string', 'number'].includes(typeof value) && String(value).length > 0
    );

    if (!slugCandidate) {
      return null;
    }

    const slug = String(slugCandidate);

    if (hit.indexUid === 'production') {
      return localePath({ path: `/productions/${slug}` });
    }

    if (hit.indexUid === 'solution') {
      return localePath({ path: `/solutions/${slug}` });
    }

    return null;
  };

  const navigateToQuery = (value: string) => {
    const trimmed = value.trim();
    if (!trimmed) return;
    navigateTo({
      path: localePath('/search'),
      query: { query: trimmed },
    });
  };

  const performSearch = async (value: string) => {
    activeRequestId.value += 1;
    const requestId = activeRequestId.value;
    const trimmed = value.trim();
    if (!trimmed) {
      if (requestId === activeRequestId.value) {
        sections.value = [];
        loading.value = false;
      }
      return;
    }

    loading.value = true;
    try {
      const results = await search(trimmed, { limit: 12 });
      if (requestId === activeRequestId.value) {
        sections.value = results;
      }
      console.log('hits:', hits.value);
      console.log('paginatedHits:', paginatedHits.value);
    } catch (error) {
      console.error('Failed to perform search', error);
      if (requestId === activeRequestId.value) {
        sections.value = [];
      }
    } finally {
      if (requestId === activeRequestId.value) {
        loading.value = false;
      }
    }
  };

  function debounce<T extends (...args: never[]) => void>(
    fn: T,
    delay: number
  ): (...args: Parameters<T>) => void {
    let timer: ReturnType<typeof setTimeout> | null = null;

    return function (this: never, ...args: Parameters<T>) {
      if (timer) {
        clearTimeout(timer);
      }
      timer = setTimeout(() => {
        fn.apply(this, args);
      }, delay);
    };
  }

  const handleClear = () => {
    keyword.value = '';
    sections.value = [];
    router.replace(localePath({ path: '/search' }));
  };

  const handleCurrentChange = (page: number) => {
    currentPage.value = page;
  };

  watch(
    () => route.query.query,
    (newQuery) => {
      if (typeof newQuery === 'string' && newQuery.trim()) {
        keyword.value = newQuery;
        performSearch(newQuery);
      } else {
        loading.value = false;
      }
    }
  );

  onMounted(() => {
    if (typeof route.query.query === 'string' && route.query.query.trim()) {
      keyword.value = route.query.query;
      performSearch(route.query.query);
    } else {
      loading.value = false;
    }
  });

  useHead(() => ({
    title: t('search.head-title'),
  }));
</script>

<style scoped>
  .search-page {
    margin: 0 auto;
    max-width: 960px;
    padding: 2.5rem 1.5rem 3rem;
    min-height: 70vh;
  }

  .search-header {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 2rem;
  }

  .page-title {
    font-size: 2.25rem;
    font-weight: 600;
    color: var(--el-text-color-primary);
  }

  .search-bar {
    display: flex;
    gap: 1rem;
    align-items: center;
    font-size: 16px;
  }

  .search-input {
    flex: 1;
    height: 50px;
  }

  .search-button {
    height: 50px;
    width: 100px;
    font-size: 16px;
  }

  .search-meta {
    font-size: 0.9rem;
    color: var(--el-text-color-secondary);
  }

  .search-state {
    display: flex;
    justify-content: center;
    padding: 3rem 0;
  }

  .search-results {
    display: flex;
    flex-direction: column;
    gap: 2.5rem;
  }

  .search-section {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
  }

  .section-header {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
  }

  .section-title {
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--el-text-color-primary);
  }

  .section-count {
    font-size: 0.9rem;
    color: var(--el-text-color-secondary);
  }

  .section-results {
    display: grid;
    gap: 1.5rem;
  }

  .result-card {
    border-radius: 12px;
    transition: box-shadow 0.2s ease;
  }

  .result-card:hover {
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.06);
  }

  .result-title {
    font-size: 1.2rem;
    font-weight: 600;
    color: var(--el-color-primary);
    display: inline-block;
  }

  .result-summary {
    font-size: 0.95rem;
    color: var(--el-text-color-regular);
    margin-bottom: 0.5rem;
    line-height: 1.6;
  }

  .result-type {
    font-size: 0.8rem;
    color: var(--el-text-color-secondary);
  }

  .result-type-name {
    margin-left: 4px;
    color: var(--el-color-primary);
  }

  @media (max-width: 640px) {
    .search-page {
      padding: 2rem 1rem;
    }

    .search-bar {
      flex-direction: column;
      align-items: stretch;
    }

    .search-input {
      width: 100%;
    }
  }
</style>
