<template>
  <div class="permission-mask-wrapper" ref="wrapperRef">
    <!-- 有权限时才渲染原始内容 -->
    <template v-if="hasAccess">
      <slot></slot>
    </template>

    <!-- 无权限时显示遮罩和占位内容 -->
    <template v-else>
      <!-- 占位背景 -->
      <div class="permission-placeholder">
        <img v-if="placeholderImage" :src="placeholderImage" alt="" class="placeholder-image" />
        <div v-else class="placeholder-pattern"></div>
      </div>

      <!-- 权限遮罩层 -->
      <div class="permission-mask" ref="maskRef" :data-permission-guard="guardKey">
        <!-- 上方：锁提示区域 -->
        <div class="mask-top">
          <div class="mask-content">
            <div class="lock-icon-wrapper">
              <svg class="lock-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M19 11H5C3.89543 11 3 11.8954 3 13V20C3 21.1046 3.89543 22 5 22H19C20.1046 22 21 21.1046 21 20V13C21 11.8954 20.1046 11 19 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                <path d="M7 11V7C7 5.67392 7.52678 4.40215 8.46447 3.46447C9.40215 2.52678 10.6739 2 12 2C13.3261 2 14.5979 2.52678 15.5355 3.46447C16.4732 4.40215 17 5.67392 17 7V11" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
              </svg>
            </div>
            <h3 class="mask-title">{{ title }}</h3>
            <p class="mask-description">{{ description }}</p>
            <div class="mask-hint">
              <span class="material-icons-round hint-icon">info</span>
              <span>请联系下方客服开通权限</span>
            </div>
          </div>
        </div>

        <!-- 下方：名片区域 -->
        <div v-if="contacts && contacts.length" class="cards-area">
          <div class="cards-header">
            <img :src="exchangeIcon" class="refresh-btn" @click="shuffleContacts" alt="换一批" />
          </div>
          <div class="cards-row">
            <div
              v-for="(contact, index) in visibleContacts"
              :key="index"
              class="contact-card"
            >
              <div class="card-avatar-wrapper">
                <img :src="contact.avatar" class="card-avatar" alt="" />
              </div>
              <img :src="cardBg" class="card-bg" alt="" />
              <div class="card-body">
                <div class="card-name">{{ contact.name }}</div>
                <div class="card-desc">{{ contact.desc }}</div>
                <img :src="contact.qrcode" class="card-qrcode" alt="二维码" />
                <div class="card-phone">
                  <img :src="phoneIcon" class="phone-icon" alt="" />
                  {{ contact.phone }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </template>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { getPermissions } from '@/utils/storage'
import cardBg from '@/assets/nav/card.png'
import phoneIcon from '@/assets/nav/phone.png'
import exchangeIcon from '@/assets/nav/exchange.png'

const props = defineProps({
  permissionKey: {
    type: String,
    required: true,
    validator: (value) => ['bigBrother', 'crawl', 'webAi'].includes(value)
  },
  title: {
    type: String,
    default: '功能未开通'
  },
  description: {
    type: String,
    default: '您当前没有使用此功能的权限'
  },
  placeholderImage: {
    type: String,
    default: ''
  },
  // 名片数据，每项: { avatar, name, desc, qrcode, phone }
  contacts: {
    type: Array,
    default: () => []
  }
})

const wrapperRef = ref(null)
const maskRef = ref(null)
const visibleIndices = ref([])
const visibleContacts = ref([])

const guardKey = computed(() => `guard_${props.permissionKey}_${Date.now()}`)

const permissionsData = ref(getPermissions())

const hasAccess = computed(() => {
  return permissionsData.value[props.permissionKey] === 1
})

const pickRandomIndices = (sourceIndices, count) => {
  const arr = [...sourceIndices]
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1))
    ;[arr[i], arr[j]] = [arr[j], arr[i]]
  }
  return arr.slice(0, count)
}

const updateVisibleContacts = (excludeCurrent = false) => {
  const total = props.contacts.length

  if (total === 0) {
    visibleIndices.value = []
    visibleContacts.value = []
    return
  }

  if (total <= 3) {
    const all = [...Array(total).keys()]
    visibleIndices.value = pickRandomIndices(all, total)
    visibleContacts.value = visibleIndices.value.map(i => props.contacts[i])
    return
  }

  const all = [...Array(total).keys()]
  let candidates = all

  if (excludeCurrent && visibleIndices.value.length) {
    const current = new Set(visibleIndices.value)
    candidates = all.filter(i => !current.has(i))
    if (candidates.length < 3) {
      candidates = all
    }
  }

  visibleIndices.value = pickRandomIndices(candidates, 3)
  visibleContacts.value = visibleIndices.value.map(i => props.contacts[i])
}

const shuffleContacts = () => {
  updateVisibleContacts(true)
}

let permissionCheckInterval = null

const refreshPermissions = () => {
  permissionsData.value = getPermissions()
}

let observer = null

const setupDOMProtection = () => {
  if (hasAccess.value || !wrapperRef.value) return

  observer = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
      if (mutation.type === 'childList') {
        const maskExists = wrapperRef.value?.querySelector('.permission-mask')
        if (!maskExists && !hasAccess.value) {
          console.warn('[PermissionMask] 检测到权限遮罩被非法移除，正在重载页面...')
          window.location.reload()
        }
      }
      if (mutation.type === 'attributes' && mutation.target.classList?.contains('permission-mask')) {
        const mask = mutation.target
        const style = window.getComputedStyle(mask)
        if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') {
          console.warn('[PermissionMask] 检测到权限遮罩样式被非法修改，正在重载页面...')
          window.location.reload()
        }
      }
    }
  })

  observer.observe(wrapperRef.value, {
    childList: true,
    subtree: true,
    attributes: true,
    attributeFilter: ['style', 'class']
  })
}

onMounted(() => {
  updateVisibleContacts(false)
  permissionCheckInterval = setInterval(refreshPermissions, 2000)
  setTimeout(setupDOMProtection, 100)
})

onUnmounted(() => {
  if (permissionCheckInterval) clearInterval(permissionCheckInterval)
  if (observer) observer.disconnect()
})

watch(
  () => props.contacts,
  () => {
    updateVisibleContacts(false)
  },
  { deep: true }
)

watch(hasAccess, (newVal) => {
  if (observer) observer.disconnect()
  if (!newVal) setTimeout(setupDOMProtection, 100)
})
</script>

<style scoped>
.permission-mask-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}

.permission-placeholder {
  position: absolute;
  inset: 0;
  background: #f8fafc;
  z-index: 99;
  overflow: hidden;
}

.placeholder-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
  pointer-events: none;
  user-select: none;
}

.placeholder-pattern {
  width: 100%;
  height: 100%;
  background-image:
    linear-gradient(45deg, #e2e8f0 25%, transparent 25%),
    linear-gradient(-45deg, #e2e8f0 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #e2e8f0 75%),
    linear-gradient(-45deg, transparent 75%, #e2e8f0 75%);
  background-size: 20px 20px;
  background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
  opacity: 0.5;
}

.permission-mask {
  position: absolute;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  background: rgba(15, 23, 42, 0.75);
  backdrop-filter: blur(1px);
  -webkit-backdrop-filter: blur(8px);
  overflow-y: auto;
}

/* 上方锁提示区域 */
.mask-top {
  display: flex;
  justify-content: center;
  padding-top: 6vh;
  width: 100%;
}

.mask-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 2.5rem;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 1.5rem;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
  max-width: 360px;
  animation: slideUp 0.4s ease-out;
}

@keyframes slideUp {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

.lock-icon-wrapper {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.5rem;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

.lock-icon {
  width: 40px;
  height: 40px;
  color: #64748b;
}

.mask-title {
  font-size: 1.375rem;
  font-weight: 700;
  color: #1e293b;
  margin: 0 0 0.5rem 0;
}

.mask-description {
  font-size: 0.9375rem;
  color: #64748b;
  margin: 0 0 1.5rem 0;
  line-height: 1.5;
}

.mask-hint {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
  border-radius: 9999px;
  color: #3b82f6;
  font-size: 0.875rem;
  font-weight: 500;
}

.hint-icon {
  font-size: 1.125rem;
}

/* 名片区域 */
.cards-area {
  width: 100%;
  padding: 3vh 0 2rem;
  animation: slideUp 0.4s ease-out 0.1s both;
}

.cards-header {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 1rem;
  padding-right: 10%;
}

.refresh-btn {
  height: 2.2vw;
  cursor: pointer;
  display: block;
  transition: opacity 0.2s;
}

.refresh-btn:hover {
  opacity: 0.8;
}

.cards-row {
  display: flex;
  justify-content: space-evenly;
}

/* 单张名片 */
.contact-card {
  width: 17%;
  flex: none;
  max-width: unset;
  aspect-ratio: 2 / 3;
  background: transparent;
  border-radius: 1.25rem;
  padding-top: 0;
  position: relative;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.contact-card::before {
  display: none;
}

.card-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
  border-radius: 1.25rem;
  z-index: 0;
  pointer-events: none;
}

.card-avatar-wrapper {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 40%;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 3px solid #fff;
  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
  overflow: hidden;
  background: #e2e8f0;
  z-index: 2;
}

.card-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 50% 8% 6%;
  width: 100%;
  height: 100%;
  position: relative;
  z-index: 1;
  justify-content: flex-start;
  box-sizing: border-box;
}

.card-name {
  font-size: 1.1vw;
  font-weight: 700;
  color: #1e293b;
  margin-bottom: 0.3vw;
  text-align: center;
}

.card-desc {
  font-size: 0.8vw;
  color: #64748b;
  text-align: center;
  margin-bottom: 0.5vw;
  line-height: 1.4;
}

.card-qrcode {
  width: 60%;
  aspect-ratio: 1;
  object-fit: contain;
  margin-bottom: 0.5vw;
}

.card-phone {
  display: flex;
  align-items: center;
  gap: 0.3vw;
  font-size: 0.85vw;
  color: #2563eb;
  font-weight: 500;
}

.phone-icon {
  width: 0.9vw;
  height: 0.9vw;
  object-fit: contain;
}
</style>
