<template>
  <div class="pn-list-container">
    <div v-if="loading" class="pn-loading-mask">
      <div class="pn-spinner"></div>
      <span class="pn-loading-text">加载中...</span>
    </div>
    <div class="pn-header">
      <div class="pn-header-left">
        <svg class="pn-header-icon" width="8" height="20" viewBox="0 0 8 20" fill="none">
          <rect width="8" height="20" rx="2" fill="rgba(5,95,194,1)" />
        </svg>
        <span class="pn-header-title">潜在提案举措分析</span>
      </div>
      <div class="pn-header-actions">
        <svg class="pn-action-icon" width="28" height="28" viewBox="0 0 28 28" fill="none">
          <rect x="13" y="7" width="2" height="6" rx="0.5" fill="rgba(132,136,142,1)" />
          <path d="M10 13l4 4 4-4" stroke="rgba(132,136,142,1)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none" />
          <path d="M7 19h14" stroke="rgba(132,136,142,1)" stroke-width="1.5" stroke-linecap="round" />
        </svg>
        <svg class="pn-action-icon" width="28" height="28" viewBox="0 0 28 28" fill="none">
          <path d="M14 6l2.47 5.01L22 11.76l-4 3.9.94 5.5L14 18.51l-4.94 2.65.94-5.5-4-3.9 5.53-.75L14 6z" stroke="rgba(132,136,142,1)" stroke-width="1.5" stroke-linejoin="round" fill="none" />
        </svg>
      </div>
    </div>

    <div class="pn-search-wrapper">
      <div class="pn-search">
        <input
          class="pn-search-input"
          v-model="searchText"
          placeholder="搜索提案"
          @input="handleSearch"
        />
        <svg class="pn-search-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" @click="handleSearch" style="cursor: pointer">
          <circle cx="7" cy="7" r="5.5" stroke="rgba(132,136,142,1)" stroke-width="1.2" fill="none" />
          <path d="M11 11L14 14" stroke="rgba(132,136,142,1)" stroke-width="1.2" stroke-linecap="round" />
        </svg>
      </div>
    </div>

    <div class="pn-rows" :class="{ 'pn-rows-loading': loading || newsList.length === 0 }">
      <el-empty v-if="!loading && newsList.length === 0" description="暂无数据" :image-size="80" />
      <div
        v-for="(item, index) in newsList"
        v-show="!loading"
        :key="item.tkid"
        :class="['pn-row', { 'pn-row-alt': index % 2 === 0 }]"
      >
        <div class="pn-row-num">
          <span class="pn-num-circle"></span>
          <span class="pn-num-text">{{ index + 1 + (currentPage - 1) * pageSize }}</span>
        </div>

        <p class="pn-row-title">{{ item.fynr }}</p>
      </div>
    </div>

    <div class="pn-footer" v-if="newsList.length > 0">
      <span class="pn-footer-total">共{{ total }}条</span>
      <div class="pn-pagination">
        <button
          class="pn-page-btn pn-page-prev"
          :disabled="currentPage <= 1"
          @click="$emit('page-change', currentPage - 1)"
        >
          <svg width="10" height="10" viewBox="0 0 10 10" fill="none">
            <path d="M6.5 1.5L3.5 5L6.5 8.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" />
          </svg>
        </button>
        <button
          v-for="page in displayedPages"
          :key="page"
          :class="['pn-page-num', { active: page === currentPage }]"
          @click="$emit('page-change', page)"
        >{{ page }}</button>
        <button
          class="pn-page-btn pn-page-next"
          :disabled="currentPage >= totalPages"
          @click="$emit('page-change', currentPage + 1)"
        >
          <svg width="10" height="10" viewBox="0 0 10 10" fill="none">
            <path d="M3.5 1.5L6.5 5L3.5 8.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" />
          </svg>
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, ref } from 'vue'
import TagBadge from './TagBadge.vue'

const tagColorMap = {
  blue: 'tag6',
  green: '',
}

const props = defineProps({
  newsList: { type: Array, default: () => [] },
  total: { type: Number, default: 0 },
  currentPage: { type: Number, default: 1 },
  pageSize: { type: Number, default: 10 },
  keyword: { type: String, default: '' },
  loading: { type: Boolean, default: false },
})

const searchText = ref(props.keyword)

const emit = defineEmits(['page-change', 'search'])

let debounceTimer = null
function handleSearch() {
  clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => {
    emit('search', searchText.value)
  }, 300)
}

const totalPages = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)))

const displayedPages = computed(() => {
  const pages = []
  const tp = totalPages.value
  const cp = props.currentPage
  const start = Math.max(1, cp - 2)
  const end = Math.min(tp, start + 4)
  for (let i = start; i <= end; i++) {
    pages.push(i)
  }
  return pages
})
</script>

<style scoped>
.pn-list-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 10px;
  border: 1px solid rgba(234, 236, 238, 1);
  box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
  overflow: hidden;
  position: relative;
}
 
.pn-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  flex-shrink: 0;
}
.pn-header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}
.pn-header-title {
  font-size: 20px;
  font-weight: 700;
  line-height: 26px;
  color: rgba(5, 95, 194, 1);
  font-family: 'Source Han Sans CN', 'Noto Sans SC', sans-serif;
}
.pn-header-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pn-action-icon {
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s;
}
.pn-action-icon:hover {
  opacity: 1;
}
 
.pn-search-wrapper {
  padding: 0 24px 0 24px;
  flex-shrink: 0;
}
.pn-search {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 32px;
  padding: 0 12px;
  border: 1px solid rgba(230, 231, 232, 1);
  border-radius: 4px;
  background: #fff;
}
.pn-search-placeholder {
  font-size: 16px;
  line-height: 24px;
  color: rgba(132, 136, 142, 1);
  font-family: 'Source Han Sans CN', 'Noto Sans SC', sans-serif;
}
.pn-search-input {
  flex: 1;
  border: none;
  outline: none;
  font-size: 16px;
  line-height: 24px;
  color: rgba(59, 65, 75, 1);
  font-family: 'Source Han Sans CN', 'Noto Sans SC', sans-serif;
  background: transparent;
}
.pn-search-input::placeholder {
  color: rgba(132, 136, 142, 1);
}
.pn-search-icon {
  flex-shrink: 0;
} 
.pn-rows {
  flex: 1;
  overflow-y: auto;
  margin-top: 12px;
  position: relative;
}
.pn-rows-loading {
  display: flex;
  align-items: center;
  justify-content: center;
}
.pn-rows-spinner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.pn-spinner-icon {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(22, 119, 255, 0.2);
  border-top-color: rgba(22, 119, 255, 1);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
.pn-spinner-text {
  font-size: 14px;
  color: rgba(132, 136, 142, 1);
}
.pn-row {
  position: relative;
  height: 60px;
  display: flex;
  align-items: center;
  padding: 0 24px;
  border-top: 1px solid rgba(234, 236, 238, 1);
  background: #fff;
}
.pn-row-alt {
  background: rgba(247, 248, 249, 1);
}

.pn-row-num {
  position: relative;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  margin-right: 12px;
}
.pn-num-circle {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 40% 35%, rgba(5, 95, 194, 0.06) 0%, rgba(5, 95, 194, 0.12) 100%);
  border: 1px solid rgba(5, 95, 194, 0.15);
}
.pn-num-text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 400;
  line-height: 12px;
  color: rgba(5, 95, 194, 1);
  font-family: 'Microsoft YaHei', sans-serif;
}

.pn-row-title {
  flex: 1;
  min-width: 0;
  font-size: 16px;
  font-weight: 700;
  line-height: 30px;
  color: rgba(59, 65, 75, 1);
  font-family: 'Source Han Sans CN', 'Noto Sans SC', sans-serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pn-row-tags {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
  margin-left: 24px;
}
 
.pn-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 24px;
  border-top: 1px solid rgba(234, 236, 238, 1);
  flex-shrink: 0;
}
.pn-footer-total {
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  color: rgba(132, 136, 142, 1);
  font-family: 'Source Han Sans CN', 'Noto Sans SC', sans-serif;
}

.pn-pagination {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pn-page-btn {
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
  color: rgba(0, 0, 0, 0.65);
  transition: border-color 0.2s, color 0.2s;
}
.pn-page-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.pn-page-num {
  min-width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
  font-size: 14px;
  font-weight: 400;
  line-height: 22px;
  color: rgba(0, 0, 0, 0.88);
  font-family: 'Microsoft YaHei', sans-serif;
  padding: 0 4px;
  transition: border-color 0.2s, color 0.2s;
}
.pn-page-num.active {
  border-color: rgba(22, 119, 255, 1);
  color: rgba(22, 119, 255, 1);
}
.pn-page-num:hover:not(.active) {
  border-color: rgba(22, 119, 255, 0.5);
  color: rgba(22, 119, 255, 0.8);
}
 
.pn-loading-mask {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 100;
  backdrop-filter: blur(2px);
}

.pn-loading-text {
  margin-top: 8px;
  font-size: 14px;
  color: rgba(22, 119, 255, 1);
  font-family: 'Microsoft YaHei', sans-serif;
}

.pn-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid rgba(22, 119, 255, 0.2);
  border-top-color: rgba(22, 119, 255, 1);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
