<template>
  <section class="page source-store-page">
    <div class="store-hero">
      <div class="hero-copy">
        <p class="eyebrow">源码库 / Source Store</p>
        <h1>精选 Java 源码项目库</h1>
        <p class="muted">
          沉淀可交付、可运行、可二开的企业级源码项目，支持按行业场景和技术栈快速筛选。
        </p>
      </div>
      <div class="store-search">
        <el-input v-model="keyword" size="large" placeholder="搜索源码项目，例如 DMS、商城、OA">
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
      </div>
    </div>

    <div class="store-body">
      <aside class="category-panel">
        <h2>源码分类</h2>
        <button
          v-for="category in categories"
          :key="category.value"
          class="category-button"
          :class="{ active: activeCategory === category.value }"
          type="button"
          @click="activeCategory = category.value"
        >
          {{ category.label }}
        </button>
      </aside>

      <div class="project-area" v-loading="loading">
        <div class="project-toolbar">
          <div>
            <h2>源码项目</h2>
            <p class="muted">共 {{ filteredProjects.length }} 个可选项目</p>
          </div>
          <el-button :icon="RefreshRight" @click="resetFilters">重置筛选</el-button>
        </div>

        <div v-if="filteredProjects.length" class="source-grid">
          <article v-for="project in filteredProjects" :key="project.id" class="source-card">
            <div class="source-cover">
              <span>{{ project.coverText }}</span>
            </div>
            <div class="source-content">
              <div class="source-heading">
                <div>
                  <h3>{{ project.name }}</h3>
                  <!-- <p>{{ project.summary }}</p> -->
                </div>
                <strong>{{ project.price }}</strong>
              </div>

              <div class="source-tags">
                <el-tag v-for="tag in project.tags" :key="tag" effect="plain">{{ tag }}</el-tag>
              </div>

              <div class="source-meta">
                <span>{{ formatViews(project.views) }} 人浏览</span>
                <span>{{ project.updateTime }}</span>
              </div>

              <div class="source-actions">
                <el-button :icon="ArrowRight" type="primary" @click="router.push(`/source-store/${project.id}`)">
                  查看详情
                </el-button>
              </div>
            </div>
          </article>
        </div>

        <el-empty v-else-if="!loading" description="暂无匹配的源码项目">
          <el-button type="primary" @click="resetFilters">重置筛选</el-button>
        </el-empty>
      </div>
    </div>
  </section>
</template>

<script setup>
import { computed, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ArrowRight, RefreshRight, Search } from '@element-plus/icons-vue'
import { listSourceCategories, listSourceProjects } from '@/api/source'
import { buildSourceCategories } from '@/api/sourceAdapter'

const router = useRouter()
const keyword = ref('')
const activeCategory = ref('all')
const loading = ref(false)
const sourceProjects = ref([])
const sourceCategories = ref([])

const categories = computed(() => buildSourceCategories(sourceProjects.value, sourceCategories.value))

const filteredProjects = computed(() => {
  const normalizedKeyword = keyword.value.trim().toLowerCase()
  return sourceProjects.value.filter((project) => {
    const categoryMatched = activeCategory.value === 'all' || project.category === activeCategory.value
    if (!categoryMatched) return false
    if (!normalizedKeyword) return true

    const searchText = [
      project.name,
      project.summary,
      ...project.tags,
      ...project.modules,
      ...project.scenes
    ].join(' ').toLowerCase()
    return searchText.includes(normalizedKeyword)
  })
})

onMounted(loadProjects)

async function loadProjects() {
  loading.value = true
  try {
    const [projects, categories] = await Promise.all([
      listSourceProjects(),
      listSourceCategories().catch(() => [])
    ])
    sourceProjects.value = projects
    sourceCategories.value = categories
  } finally {
    loading.value = false
  }
}

function formatViews(views) {
  return Number(views || 0).toLocaleString('zh-CN')
}

function resetFilters() {
  keyword.value = ''
  activeCategory.value = 'all'
}
</script>

<style scoped lang="scss">
.source-store-page {
  display: grid;
  gap: 18px;
}

.store-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 420px);
  align-items: end;
  gap: 24px;
  padding: 28px;
  border: 1px solid #d9e0ea;
  border-radius: 8px;
  background: #ffffff;
}

.hero-copy {
  display: grid;
  gap: 10px;

  .eyebrow {
    margin: 0;
    color: #1d4ed8;
    font-weight: 700;
  }

  h1 {
    margin: 0;
    color: #101828;
    font-size: 32px;
    line-height: 1.2;
    letter-spacing: 0;
  }

  .muted {
    max-width: 620px;
    margin: 0;
    font-size: 15px;
  }
}

.store-body {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 18px;
}

.category-panel {
  align-self: start;
  display: grid;
  gap: 8px;
  padding: 18px;
  border: 1px solid #d9e0ea;
  border-radius: 8px;
  background: #ffffff;

  h2 {
    margin: 0 0 6px;
    color: #172033;
    font-size: 16px;
  }
}

.category-button {
  width: 100%;
  min-height: 38px;
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  color: #475467;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.category-button:hover,
.category-button.active {
  border-color: #bfdbfe;
  color: #1d4ed8;
  background: #eff6ff;
  font-weight: 700;
}

.project-area {
  display: grid;
  gap: 14px;
  min-height: 360px;
}

.project-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid #d9e0ea;
  border-radius: 8px;
  background: #ffffff;

  h2,
  p {
    margin: 0;
  }

  h2 {
    color: #172033;
    font-size: 18px;
  }
}

.source-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.source-card {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  min-height: 360px;
  overflow: hidden;
  border: 1px solid #d9e0ea;
  border-radius: 8px;
  background: #ffffff;
}

.source-cover {
  display: grid;
  min-height: 142px;
  place-items: center;
  background:
    linear-gradient(135deg, rgba(37, 99, 235, 0.16), rgba(20, 184, 166, 0.14)),
    #f8fafc;

  span {
    display: grid;
    width: 76px;
    height: 76px;
    place-items: center;
    border: 1px solid rgba(37, 99, 235, 0.2);
    border-radius: 8px;
    color: #1e3a8a;
    background: rgba(255, 255, 255, 0.72);
    font-size: 18px;
    font-weight: 800;
  }
}

.source-content {
  display: grid;
  gap: 14px;
  padding: 18px;
}

.source-heading {
  display: flex;
  justify-content: space-between;
  gap: 14px;

  h3 {
    margin: 0;
    color: #101828;
    font-size: 18px;
    line-height: 1.4;
  }

  strong {
    color: #dc2626;
    font-size: 18px;
    white-space: nowrap;
  }
}

.source-tags,
.source-meta,
.source-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.source-meta {
  justify-content: space-between;
  color: #475467;
  font-size: 14px;
}

.source-actions {
  justify-content: flex-end;
  align-self: end;
}

@media (max-width: 920px) {
  .store-hero,
  .store-body,
  .source-grid {
    grid-template-columns: 1fr;
  }
}
</style>
