<script setup lang="ts">
import { computed, ref, watch, onUnmounted } from 'vue'
import { Search } from '@element-plus/icons-vue'
import { useTaskStore } from '@/stores/useTaskStore'
import { matchWithPinyin, highlightMatch } from '@/utils/pinyin'
import TaskCard from '@/components/TaskCard.vue'

const taskStore = useTaskStore()

const statusText = computed(() => {
  switch (taskStore.filters.status) {
    case 'active': return '进行中'
    case 'completed': return '已完成'
    default: return '全部任务'
  }
})

// 筛选条件的唯一标识，用于强制重新渲染列表
const filterKey = computed(() => {
  const { status, category_id, sort_by, sort_order, search } = taskStore.filters
  return `${status}-${category_id || 'all'}-${sort_by}-${sort_order}-${search || ''}`
})

// 搜索框
const searchInput = ref(taskStore.filters.search || '')

// 使用防抖更新搜索条件
let debounceTimer: ReturnType<typeof setTimeout> | null = null
watch(searchInput, (value) => {
  if (debounceTimer) clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => {
    taskStore.setFilters({ search: value })
  }, 300)
})

// 组件卸载时清理防抖计时器
onUnmounted(() => {
  if (debounceTimer) {
    clearTimeout(debounceTimer)
    debounceTimer = null
  }
})

// 清空搜索
const clearSearch = () => {
  searchInput.value = ''
}

// 生成搜索建议
const searchSuggestions = computed(() => {
  const suggestions: string[] = []
  const addedSet = new Set<string>()

  taskStore.activeTasks.forEach(task => {
    // 添加标题
    if (task.title && !addedSet.has(task.title.toLowerCase())) {
      suggestions.push(task.title)
      addedSet.add(task.title.toLowerCase())
    }

    // 添加标签
    task.tags?.forEach(tag => {
      if (!addedSet.has(tag.name.toLowerCase())) {
        suggestions.push(tag.name)
        addedSet.add(tag.name.toLowerCase())
      }
    })
  })

  return suggestions
})

// 查询建议
const querySearch = (queryString: string, cb: (results: { value: string }[]) => void) => {
  const results = queryString
    ? searchSuggestions.value
        .filter(item => matchWithPinyin(item, queryString))
        .slice(0, 8)
        .map(item => ({ value: item }))
    : searchSuggestions.value
        .slice(0, 8)
        .map(item => ({ value: item }))
  cb(results)
}

// 选中建议
const handleSelect = (item: { value: string }) => {
  searchInput.value = item.value
  taskStore.setFilters({ search: item.value })
}

// 高亮建议中的匹配文本
const suggestionHighlight = (item: { value: string }) => {
  return highlightMatch(item.value, searchInput.value)
}
</script>

<template>
  <div class="task-list">
    <div class="list-header">
      <h2 class="list-title">
        {{ statusText }}
        <span class="task-count">{{ taskStore.tasks.length }}</span>
      </h2>
    </div>

    <!-- 搜索框 -->
    <div class="search-box">
      <el-autocomplete
        v-model="searchInput"
        :fetch-suggestions="querySearch"
        placeholder="搜索任务标题、描述或标签..."
        clearable
        class="search-input"
        popper-class="search-suggestions"
        @clear="clearSearch"
        @select="handleSelect"
      >
        <template #prefix>
          <el-icon><Search /></el-icon>
        </template>
        <template #default="{ item }">
          <span class="suggestion-item" v-html="suggestionHighlight(item)" />
        </template>
      </el-autocomplete>
    </div>

    <div v-if="taskStore.loading" class="loading-state">
      <el-skeleton :rows="5" animated />
    </div>

    <div v-else-if="taskStore.tasks.length === 0" class="empty-state">
      <div class="empty-icon">✿</div>
      <p class="empty-text">
        {{ searchInput ? '没有找到匹配的任务呢～' : '还没有任务呢～' }}
      </p>
      <p v-if="!searchInput" class="empty-hint">点击右下角的按钮创建一个新任务吧</p>
      <p v-else class="empty-hint">试试换个关键词搜索吧</p>
    </div>

    <div v-else :key="filterKey" class="task-grid">
      <TaskCard
        v-for="(task, index) in taskStore.tasks"
        :key="task.id"
        :task="task"
        :style="{ animationDelay: `${index * 50}ms` }"
        class="task-item"
      />
    </div>
  </div>
</template>

<style scoped lang="scss">
.task-list {
  max-width: 900px;
  margin: 0 auto;
}

.list-header {
  margin-bottom: 16px;
}

.list-title {
  font-size: 24px;
  font-weight: 600;
  color: var(--text-primary);
  display: flex;
  align-items: center;
  gap: 12px;

  .task-count {
    font-size: 14px;
    font-weight: 500;
    padding: 4px 12px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--accent) 100%);
    color: white;
    border-radius: 20px;
  }
}

.search-box {
  margin-bottom: 24px;

  .search-input {
    width: 100%;

    :deep(.el-input__wrapper) {
      border-radius: 16px;
      box-shadow: var(--shadow-sm);
      border: 1px solid transparent;
      transition: all 0.2s ease;
      padding: 8px 16px;
      min-height: 48px;

      &:hover {
        border-color: var(--primary-light);
      }

      &.is-focus {
        border-color: var(--primary);
        box-shadow: 0 0 0 3px rgba(255, 183, 197, 0.2);
      }
    }

    :deep(.el-input__inner) {
      font-size: 16px;
    }

    :deep(.el-input__prefix) {
      color: var(--text-secondary);
      font-size: 18px;
    }

    :deep(.el-input__clear) {
      font-size: 16px;
    }
  }
}

.suggestion-item {
  font-size: 14px;

  :deep(.search-highlight) {
    background: linear-gradient(135deg, rgba(255, 183, 197, 0.4) 0%, rgba(255, 183, 197, 0.6) 100%);
    color: var(--primary-dark);
    padding: 0 2px;
    border-radius: 3px;
    font-weight: 500;
  }
}

.task-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}

.task-item {
  animation: fadeInUp 0.3s ease forwards;
  opacity: 0;
}

.loading-state {
  padding: 20px;
}

.empty-state {
  text-align: center;
  padding: 60px 20px;

  .empty-icon {
    font-size: 64px;
    color: var(--primary);
    margin-bottom: 16px;
    animation: twinkle 2s ease-in-out infinite;
  }

  .empty-text {
    font-size: 18px;
    color: var(--text-primary);
    margin-bottom: 8px;
  }

  .empty-hint {
    font-size: 14px;
    color: var(--text-secondary);
  }
}

// 列表项入场动画（筛选切换时整体淡入）
.task-grid {
  animation: filterFadeIn 0.2s ease;
}

@keyframes filterFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
</style>
