<template>
  <view class="page">
    <!-- 搜索栏 -->
    <view class="search-bar">
      <input
        v-model="searchQuery"
        class="search-input"
        placeholder="搜索音频..."
        @confirm="handleSearch"
      />
      <button class="search-btn" @click="handleSearch">搜索</button>
    </view>

    <!-- 骨架屏加载状态 -->
    <scroll-view scroll-y class="results" v-if="loading" :scroll-top="scrollTop">
      <SkeletonList layout="search-result" :count="5" />
    </scroll-view>

    <!-- 搜索结果 -->
    <scroll-view scroll-y class="results" v-else-if="searchResults.length > 0" :scroll-top="scrollTop">
      <view class="result-list">
        <view
          v-for="item in searchResults"
          :key="item.id"
          class="result-item"
          @click="playAudio(item)"
        >
          <view class="result-cover" :style="{ background: getCoverGradient(item.voiceId) }">
            <text class="cover-letter">{{ getTitleLetter(item.title) }}</text>
            <text class="cover-title-small">{{ item.title }}</text>
          </view>
          <view class="result-info">
            <text class="result-title" v-html="highlightText(item.title, searchQuery)"></text>
            <text class="result-desc" v-if="(item as any).description" v-html="highlightText((item as any).description.slice(0, 50) + '...', searchQuery)"></text>
            <text class="result-meta">{{ item.wordCount || 0 }}字</text>
          </view>
        </view>
      </view>
    </scroll-view>

    <!-- 无结果 -->
    <view v-else-if="hasSearched && searchResults.length === 0" class="no-result">
      <text class="no-result-icon">🔍</text>
      <text class="no-result-text">未找到相关音频</text>
    </view>

    <!-- 初始状态：搜索历史 + 热门推荐 -->
    <view v-else class="initial-state">
      <!-- 搜索历史 -->
      <view class="section" v-if="searchHistory.length > 0">
        <view class="section-header">
          <text class="section-title">搜索历史</text>
          <text class="clear-btn" @click="clearHistory">清空</text>
        </view>
        <view class="tag-list">
          <view
            v-for="(item, index) in searchHistory"
            :key="index"
            class="tag history-tag"
            @click="clickHistory(item.keyword)"
          >
            <text class="tag-text">{{ item.keyword }}</text>
            <text class="delete-icon" @click.stop="deleteHistoryItem(item.keyword)">×</text>
          </view>
        </view>
      </view>

      <!-- 热门推荐 -->
      <view class="section" v-if="hotSearches.length > 0">
        <view class="section-header">
          <text class="section-title">🔥 热门推荐</text>
        </view>
        <view class="tag-list">
          <view
            v-for="(item, index) in hotSearches"
            :key="item.id"
            class="tag hot-tag"
            @click="clickHotSearch(item.keyword)"
          >
            <text class="tag-rank">{{ index + 1 }}</text>
            <text class="tag-text">{{ item.keyword }}</text>
          </view>
        </view>
      </view>

      <!-- 空状态提示 -->
      <view v-if="searchHistory.length === 0 && hotSearches.length === 0" class="empty-hint">
        <text class="hint-text">输入关键词搜索音频</text>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { useAudioStore } from '../../store/audio';
import { get, post } from '../../utils/request';
import type { AudioItem } from '../../types';
import SkeletonList from '../../components/SkeletonList.vue';
import { getCoverGradient, getTitleLetter } from '../../composables/useCoverStyle';

// 缓存键名
const HOT_SEARCH_CACHE_KEY = 'hot_search_cache';

// scroll-top 用于避免 scrollTop 错误
const scrollTop = ref(0);

const audioStore = useAudioStore();

const searchQuery = ref('');
const searchResults = ref<AudioItem[]>([]);
const hasSearched = ref(false);
const loading = ref(false);
const searchHistory = ref<{ keyword: string }[]>([]);
const hotSearches = ref<{ id: number; keyword: string; count: number }[]>([]);


// 高亮搜索关键词
function highlightText(text: string, keyword: string): string {
  if (!keyword || !text) return text;
  const regex = new RegExp(`(${escapeRegExp(keyword)})`, 'gi');
  return text.replace(regex, '<span class="highlight">$1</span>');
}

// 转义正则特殊字符
function escapeRegExp(str: string): string {
  return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

// 缓存热词
function cacheHotSearches(hotList: { id: number; keyword: string; count: number }[]) {
  try {
    uni.setStorageSync(HOT_SEARCH_CACHE_KEY, hotList);
  } catch (e) {
    console.error('缓存热词失败:', e);
  }
}

// 读取缓存热词
function getCachedHotSearches(): { id: number; keyword: string; count: number }[] {
  try {
    return uni.getStorageSync(HOT_SEARCH_CACHE_KEY) || [];
  } catch (e) {
    console.error('读取热词缓存失败:', e);
    return [];
  }
}

// 加载搜索历史和热门推荐
async function loadSearchContext() {
  try {
    // 获取搜索历史（用户ID固定为1，用于开发阶段）
    const userId = 1;
    const [historyRes, hotRes] = await Promise.all([
      get<{ keyword: string }[]>('/search/history', { userId, limit: 5 }),
      get<{ id: number; keyword: string; count: number }[]>('/search/hot', { limit: 10 }),
    ]);
    searchHistory.value = historyRes || [];
    hotSearches.value = hotRes || [];

    // 更新热词缓存
    if (hotRes && hotRes.length > 0) {
      cacheHotSearches(hotRes);
    }
  } catch (error) {
    console.error('加载搜索上下文失败:', error);
    searchHistory.value = [];
    // 读取缓存热词
    hotSearches.value = getCachedHotSearches();
  }
}

// 点击历史标签
function clickHistory(keyword: string) {
  searchQuery.value = keyword;
  handleSearch();
}

// 点击热搜词
function clickHotSearch(keyword: string) {
  searchQuery.value = keyword;
  handleSearch();
}

// 删除单条历史
async function deleteHistoryItem(keyword: string) {
  try {
    const userId = 1;
    await get('/search/history', { userId, keyword } as any);
    await loadSearchContext();
  } catch (error) {
    console.error('删除历史失败:', error);
  }
}

// 清空历史
async function clearHistory() {
  try {
    const userId = 1;
    await get('/search/history/all', { userId } as any);
    searchHistory.value = [];
  } catch (error) {
    console.error('清空历史失败:', error);
  }
}

async function handleSearch() {
  if (!searchQuery.value.trim()) return;

  hasSearched.value = true;
  loading.value = true;
  try {
    // 保存搜索历史
    const userId = 1;
    await post('/search/history', { userId, keyword: searchQuery.value });

    const result = await get<AudioItem[]>('/search', { q: searchQuery.value });
    searchResults.value = result || [];

    // 更新热词缓存（搜索结果返回后更新）
    if (hotSearches.value.length > 0) {
      cacheHotSearches(hotSearches.value);
    }

    // 刷新历史记录
    await loadSearchContext();
  } catch (error) {
    console.error('搜索失败:', error);
    searchResults.value = [];
  } finally {
    loading.value = false;
  }
}

function playAudio(item: AudioItem) {
  // 搜索结果是书籍，跳转到书籍详情页（专辑页）
  uni.navigateTo({ url: `/pages/album/index?id=${item.id}` });
}

onMounted(() => {
  loadSearchContext();
});
</script>

<style scoped>
.page {
  min-height: 100vh;
  background: #f5f5f5;
  padding-top: 44rpx;
}

.search-bar {
  display: flex;
  gap: 16rpx;
  padding: 24rpx 32rpx;
  background: #ffffff;
}

.search-input {
  flex: 1;
  height: 72rpx;
  background: #f5f5f5;
  border-radius: 36rpx;
  padding: 0 32rpx;
  font-size: 28rpx;
}

.search-btn {
  width: 120rpx;
  height: 72rpx;
  background: #4f46e5;
  color: #ffffff;
  border-radius: 36rpx;
  font-size: 28rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.search-btn::after {
  border: none;
}

.results {
  height: calc(100vh - 140rpx);
}

.result-list {
  padding: 24rpx;
}

.result-item {
  display: flex;
  gap: 20rpx;
  padding: 20rpx;
  background: #ffffff;
  border-radius: 16rpx;
  margin-bottom: 16rpx;
}

.result-cover {
  width: 100rpx;
  height: 100rpx;
  border-radius: 12rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}

.cover-icon {
  font-size: 40rpx;
  opacity: 0.6;
}

/* 文字海报风格封面 */
.cover-letter {
  position: absolute;
  top: -8rpx;
  left: 6rpx;
  font-size: 70rpx;
  font-weight: 900;
  color: rgba(255, 255, 255, 0.14);
  line-height: 1;
  pointer-events: none;
}

.cover-title-small {
  position: absolute;
  bottom: 6rpx;
  left: 10rpx;
  right: 10rpx;
  font-size: 18rpx;
  color: rgba(255, 255, 255, 0.8);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.result-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.result-title {
  font-size: 28rpx;
  color: #1f2937;
  margin-bottom: 8rpx;
}

.result-meta {
  font-size: 24rpx;
  color: #9ca3af;
}

.result-desc {
  font-size: 24rpx;
  color: #6b7280;
  margin-bottom: 4rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:deep(.highlight) {
  background: linear-gradient(135deg, #fef08a 0%, #fde047 100%);
  color: #92400e;
  padding: 0 4rpx;
  border-radius: 4rpx;
}

.no-result {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 200rpx 0;
}

.no-result-icon {
  font-size: 80rpx;
  margin-bottom: 24rpx;
}

.no-result-text {
  font-size: 28rpx;
  color: #6b7280;
}

.initial-state {
  padding: 24rpx 32rpx;
}

.section {
  margin-bottom: 32rpx;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20rpx;
}

.section-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #1f2937;
}

.clear-btn {
  font-size: 24rpx;
  color: #9ca3af;
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 16rpx;
}

.tag {
  display: inline-flex;
  align-items: center;
  gap: 8rpx;
  padding: 12rpx 20rpx;
  background: #ffffff;
  border-radius: 32rpx;
  font-size: 26rpx;
}

.history-tag {
  color: #4b5563;
}

.delete-icon {
  font-size: 28rpx;
  color: #9ca3af;
  margin-left: 4rpx;
}

.hot-tag {
  background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
  color: #92400e;
}

.tag-rank {
  font-weight: 600;
  color: #dc2626;
  margin-right: 4rpx;
}

.tag-text {
  max-width: 300rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.empty-hint {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 200rpx 0;
}

.hint-text {
  font-size: 28rpx;
  color: #9ca3af;
}
</style>
