<template>
  <div class="profile-tag-pager">
    <div :key="activePageIndex" class="profile-tag-list">
      <article
        v-for="(tag, index) in visibleTags"
        :key="tag.code"
        :class="[
          'profile-tag-item',
          `profile-tag-item--${tag.tone}`,
          `profile-tag-item--accent-${resolveTagAccentIndex(tag, index)}`
        ]"
      >
        <div class="profile-tag-copy">
          <strong>{{ tag.displayLabel || tag.label }}</strong>
          <span>{{ tag.reason }}</span>
        </div>
        <ElTag class="profile-score-tag" :type="resolveProfileTagType(tag.tone)" effect="light">
          {{ tag.score }}
        </ElTag>
      </article>

      <article
        v-for="item in placeholderCount"
        :key="`placeholder-${activePageIndex}-${item}`"
        class="profile-tag-item profile-tag-item--placeholder"
        aria-hidden="true"
      ></article>
    </div>

    <div v-if="pageCount > 1" class="profile-tag-pagination" aria-label="画像标签分页">
      <ElButton
        class="profile-tag-page-btn"
        text
        :disabled="activePageIndex === 0"
        aria-label="上一页画像标签"
        @click="goPreviousPage"
      >
        <i class="mdi mdi-chevron-left"></i>
      </ElButton>

      <div class="profile-tag-page-dots">
        <button
          v-for="page in tagPages"
          :key="page"
          type="button"
          :class="['profile-tag-page-dot', { 'is-active': page === activePageIndex }]"
          :aria-label="`切换到第 ${page + 1} 页画像标签`"
          :aria-current="page === activePageIndex ? 'page' : undefined"
          @click="goToPage(page)"
        ></button>
      </div>

      <ElButton
        class="profile-tag-page-btn"
        text
        :disabled="activePageIndex >= pageCount - 1"
        aria-label="下一页画像标签"
        @click="goNextPage"
      >
        <i class="mdi mdi-chevron-right"></i>
      </ElButton>
    </div>

    <div v-else class="profile-tag-pagination profile-tag-pagination--single" aria-hidden="true">
      <span></span>
    </div>
  </div>
</template>

<script setup>
import { computed, ref, watch } from 'vue'
import { ElButton } from 'element-plus/es/components/button/index.mjs'
import { ElTag } from 'element-plus/es/components/tag/index.mjs'

const TAG_PAGE_SIZE = 5

const props = defineProps({
  tags: { type: Array, default: () => [] },
  visible: { type: Boolean, default: false }
})

const pageIndex = ref(0)

const pageCount = computed(() => Math.max(1, Math.ceil(props.tags.length / TAG_PAGE_SIZE)))
const activePageIndex = computed(() => Math.min(pageIndex.value, pageCount.value - 1))
const tagPages = computed(() => Array.from({ length: pageCount.value }, (_, index) => index))
const visibleTags = computed(() => {
  const start = activePageIndex.value * TAG_PAGE_SIZE
  return props.tags.slice(start, start + TAG_PAGE_SIZE)
})
const placeholderCount = computed(() => Math.max(0, TAG_PAGE_SIZE - visibleTags.value.length))
const tagIdentity = computed(() => props.tags.map((tag) => tag.code || tag.label).join('|'))

function resolveProfileTagType(tone) {
  const normalized = String(tone || '').trim()

  if (['warning', 'risk', 'amber'].includes(normalized)) {
    return 'warning'
  }
  if (['danger', 'high'].includes(normalized)) {
    return 'danger'
  }
  return 'primary'
}

function goToPage(nextPage) {
  pageIndex.value = Math.min(Math.max(Number(nextPage) || 0, 0), pageCount.value - 1)
}

function goPreviousPage() {
  goToPage(activePageIndex.value - 1)
}

function goNextPage() {
  goToPage(activePageIndex.value + 1)
}

function resolveTagAccentIndex(tag, index) {
  const explicitIndex = Number(tag?.colorIndex ?? tag?.color_index)
  if (Number.isFinite(explicitIndex)) {
    return Math.max(0, Math.round(explicitIndex)) % 8
  }
  return (activePageIndex.value * TAG_PAGE_SIZE + index) % 8
}

watch(pageCount, () => {
  goToPage(activePageIndex.value)
})

watch([() => props.visible, tagIdentity], ([visible]) => {
  if (visible) {
    goToPage(0)
  }
})
</script>

<style scoped>
.profile-tag-pager {
  height: 100%;
  min-height: 308px;
  display: grid;
  grid-template-rows: minmax(0, 1fr) 26px;
  gap: 10px;
}

.profile-tag-list {
  display: grid;
  grid-template-rows: repeat(5, minmax(48px, 1fr));
  align-content: stretch;
  gap: 8px;
  min-height: 0;
  animation: profileTagPageIn 180ms cubic-bezier(0.2, 0, 0, 1) both;
}

.profile-tag-item {
  --tag-accent-rgb: 58, 124, 165;
  --tag-accent-text: #235d7e;
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 0;
  padding: 7px 10px;
  border: 1px solid rgba(var(--tag-accent-rgb), 0.2);
  border-left: 3px solid rgb(var(--tag-accent-rgb));
  border-radius: 4px;
  background: rgba(var(--tag-accent-rgb), 0.045);
  transition:
    border-color 180ms var(--ease),
    background-color 180ms var(--ease);
}

.profile-tag-item:hover {
  border-color: rgba(var(--tag-accent-rgb), 0.34);
  background: rgba(var(--tag-accent-rgb), 0.075);
}

.profile-tag-item--placeholder {
  visibility: hidden;
  pointer-events: none;
}

.profile-tag-copy {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.profile-tag-copy strong {
  overflow: hidden;
  color: var(--tag-accent-text);
  font-size: 13px;
  font-weight: 850;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-tag-copy span {
  overflow: hidden;
  color: #64748b;
  font-size: 11.5px;
  line-height: 1.35;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-score-tag {
  border-color: rgba(var(--tag-accent-rgb), 0.28);
  background-color: rgba(var(--tag-accent-rgb), 0.1);
  color: var(--tag-accent-text);
  border-radius: 4px;
  font-weight: 800;
}

.profile-tag-item--accent-0 {
  --tag-accent-rgb: 58, 124, 165;
  --tag-accent-text: #235d7e;
}

.profile-tag-item--accent-1 {
  --tag-accent-rgb: 15, 159, 143;
  --tag-accent-text: #0f766e;
}

.profile-tag-item--accent-2 {
  --tag-accent-rgb: 245, 158, 11;
  --tag-accent-text: #92400e;
}

.profile-tag-item--accent-3 {
  --tag-accent-rgb: 124, 58, 237;
  --tag-accent-text: #5b21b6;
}

.profile-tag-item--accent-4 {
  --tag-accent-rgb: 220, 38, 38;
  --tag-accent-text: #991b1b;
}

.profile-tag-item--accent-5 {
  --tag-accent-rgb: 37, 99, 235;
  --tag-accent-text: #1d4ed8;
}

.profile-tag-item--accent-6 {
  --tag-accent-rgb: 22, 163, 74;
  --tag-accent-text: #15803d;
}

.profile-tag-item--accent-7 {
  --tag-accent-rgb: 219, 39, 119;
  --tag-accent-text: #be185d;
}

.profile-tag-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 26px;
}

.profile-tag-pagination--single {
  pointer-events: none;
}

.profile-tag-page-btn {
  width: 24px;
  height: 24px;
  min-height: 24px;
  padding: 0;
  border-radius: 4px;
  color: #475569;
}

.profile-tag-page-btn :deep(i) {
  font-size: 16px;
}

.profile-tag-page-dots {
  display: flex;
  align-items: center;
  gap: 6px;
}

.profile-tag-page-dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: #cbd5e1;
  cursor: pointer;
  transition:
    width 180ms var(--ease),
    background-color 180ms var(--ease);
}

.profile-tag-page-dot.is-active {
  width: 18px;
  background: #3a7ca5;
}

@keyframes profileTagPageIn {
  0% {
    opacity: 0;
    transform: translateY(4px);
  }

  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .profile-tag-list,
  .profile-tag-page-dot {
    animation-duration: 1ms !important;
    transition-duration: 1ms !important;
  }
}
</style>
