<template>
  <div class="promotion-page">
    <div class="promotion-container">
      <!-- 标题 -->
      <div class="page-title">
        <div class="title-bar"></div>
        <h2 class="title-text">推广拉新</h2>
      </div>
      
      <!-- 导航标签 -->
      <div class="promotion-tabs">
        <div 
          v-for="tab in tabs" 
          :key="tab.id"
          class="promotion-tab"
          :class="{ active: currentTab === tab.id }"
          @click="switchTab(tab.id)"
        >
          {{ tab.name }}
        </div>
      </div>
      
      <!-- 我的邀请内容 -->
      <div v-if="currentTab === 'invite'" class="invite-content">
        <!-- 邀请码区域 -->
        <div class="invite-section">
          <h3 class="section-subtitle">您的专属邀请码:</h3>
          <div class="input-group">
            <input 
              type="text" 
              :value="inviteCode" 
              readonly 
              class="invite-input"
              placeholder="点击生成邀请码"
            />
            <button 
              v-if="!inviteCode" 
              @click="generateCode" 
              :disabled="generating"
              class="generate-button"
            >
              {{ generating ? '生成中...' : '生成邀请码' }}
            </button>
            <button 
              v-else 
              @click="copyInviteCode" 
              class="copy-button"
            >
              复制邀请码
            </button>
          </div>
        </div>
        
        <!-- 推广链接区域 -->
        <div class="invite-section">
          <h3 class="section-subtitle">您的专属推广链接:</h3>
          <div class="input-group">
            <input 
              type="text" 
              :value="promotionLink" 
              readonly 
              class="invite-input"
              placeholder="生成邀请码后显示"
            />
            <button 
              v-if="promotionLink" 
              @click="copyPromotionLink" 
              class="copy-button"
            >
              复制链接
            </button>
            <button 
              v-else 
              disabled 
              class="copy-button disabled"
            >
              复制链接
            </button>
          </div>
        </div>
        
        <!-- 生成海报区域 -->
        <div class="poster-section">
          <h3 class="section-subtitle">推广海报:</h3>
          <div class="poster-actions">
            <button 
              @click="showPosterModal" 
              class="poster-button"
              :disabled="!promotionLink"
            >
              <el-icon class="poster-icon">
                <Brush />
              </el-icon>
              生成专属海报
            </button>
            <p class="poster-tips">生成包含您邀请码的精美推广海报，便于分享到朋友圈等社交平台</p>
          </div>
        </div>

      </div>
      
      <!-- 推广规则内容 -->
      <div v-if="currentTab === 'rules'" class="rules-content">
        <div v-if="loading" class="loading-state">
          <el-skeleton :rows="6" animated />
        </div>
        <div v-else-if="promotionRules" class="rules-info">

          
          <!-- 推广等级进度展示 -->
          <div class="promotion-progress-section">
            <h3 class="section-title">推广说明</h3>
            <div class="description-content">
              <p>{{ promotionRules.promotionDescription }}</p>
            </div>
            <div class="progress-cards">
              <div 
                v-for="level in promotionRules.promotionLevels" 
                :key="level.level"
                class="progress-card"
              >
                <div class="level-header">
                  <div class="level-info">
                    <h4 class="level-name">{{ level.levelName }}</h4>
                    <p class="level-desc">最少需要 {{ level.minFans }} 个付费用户</p> 
                  </div>
                  <div class="commission-info">
                      <span class="commission-rate">分成比例: {{level.commissionRate }}%</span>
                  </div>
                </div>
                
                <div class="progress-container">
                  <div class="progress-text">
                    <span>等级要求: {{ level.minFans }} 个付费用户</span>
                    <span v-if="promotionUserStatus" style="margin-left: 10px;" 
                          :style="{ color: getCurrentTotalFans() >= level.minFans ? '#52c41a' : '#333', fontWeight: '500' }">
                      <template v-if="level.minFans === 0">
                        (已完成)
                      </template>
                      <template v-else-if="getCurrentTotalFans() >= level.minFans">
                        (已达成 - {{ getCurrentTotalFans() }}/{{ level.minFans }} 个粉丝)
                      </template>
                      <template v-else>
                        (当前: {{ getCurrentTotalFans() }}/{{ level.minFans }} 个粉丝)
                      </template>
                    </span>
                  </div>
                  <div class="progress-segments">
                    <div 
                      v-for="segment in 10" 
                      :key="segment"
                      class="progress-segment"
                      :class="{ 
                        'filled': segment <= getFilledSegments(level.level)
                      }"
                    ></div>
                  </div>
                </div>
                
                <div class="level-description">
                  <p>{{ level.description }}</p>
                </div>
              </div>
            </div>
          </div>
          

        </div>
        <div v-else class="empty-state">
          <el-empty description="暂无推广规则信息" />
        </div>
      </div>
      
      <!-- 邀请列表内容 -->
      <div v-if="currentTab === 'fans'" class="fans-content">
        <!-- 统计信息 -->
        <div class="fans-stats">
          <div class="stat-item">
            <div class="stat-number">{{ fansStats.totalFansCount || 0 }}</div>
            <div class="stat-label">总粉丝数</div>
          </div>
          <div class="stat-item">
            <div class="stat-number">{{ fansStats.paidFansCount || 0 }}</div>
            <div class="stat-label">付费粉丝</div>
          </div>
          <div class="stat-item">
            <div class="stat-number">{{ fansStats.levelName || 'Lv0' }}</div>
            <div class="stat-label">推广等级</div>
          </div>
          <div class="stat-item">
            <div class="stat-number">{{fansStats.commissionRate*100}}%</div> 
            <div class="stat-label">分成比例</div>
          </div>
        </div>
        
        <!-- 过滤选项 -->
        <div class="fans-filter">
          <div class="filter-label">筛选状态:</div>
          <div class="filter-options">
            <el-radio-group v-model="currentStatus" @change="handleStatusChange">
              <el-radio-button label="all">全部</el-radio-button>
              <el-radio-button label="paid">付费粉丝</el-radio-button>
              <el-radio-button label="gift">赠送会员</el-radio-button>
              <el-radio-button label="exchange">兑换会员</el-radio-button>
              <el-radio-button label="none">非VIP</el-radio-button>
            </el-radio-group>
          </div>
        </div>
        
        <div v-if="loading" class="loading-state">
          <p>加载中...</p>
        </div>
        <div v-else-if="fans.length > 0" class="fans-table-container">
          <el-table :data="fans" class="fans-table" stripe>
            <el-table-column label="用户信息" min-width="200">
              <template #default="{ row }">
                <div class="user-info">
                  <div class="user-avatar">
                    <img v-if="row.avatarUrl" :src="row.avatarUrl" :alt="row.username" />
                    <div v-else class="default-avatar">{{ row.username.charAt(0) }}</div>
                  </div>
                  <div class="user-details">
                    <div class="username">{{ row.username }}</div>
                    <div class="phone">{{ maskPhone(row.phone) }}</div>
                  </div>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="会员状态" min-width="120">
              <template #default="{ row }">
                <el-tag 
                  :type="getMembershipTagType(row.membershipStatus)"
                  size="small"
                >
                  {{ row.membershipStatusText }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="邀请时间" min-width="120">
              <template #default="{ row }">
                <span>{{ formatDate(row.createTime) }}</span>
              </template>
            </el-table-column>
            <el-table-column label="会员到期时间" min-width="140">
              <template #default="{ row }">
                <span v-if="row.membershipExpiresAt">
                  {{ formatDate(row.membershipExpiresAt) }}
                </span>
                <span v-else class="no-expiry">-</span>
              </template>
            </el-table-column>
     
          </el-table>
        </div>
        <div v-else class="empty-state">
          <p class="empty-text">暂无粉丝</p>
          <p class="empty-subtext">分享您的邀请码，邀请更多朋友加入</p>
        </div>
        
        <!-- 分页组件 - 始终显示 -->
        <div v-if="currentTab === 'fans' && totalCount > 0" class="pagination-container">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[5, 10, 20, 50]"
            :total="totalCount"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            background
            :disabled="loading"
          />
        </div>
      </div>
    </div>
    
    <!-- 海报选择弹窗 -->
    <div v-if="posterModal.visible" class="poster-modal-overlay" @click.self="closePosterModal">
      <div class="poster-modal">
        <div class="modal-header">
          <h3>选择海报模板</h3>
          <button @click="closePosterModal" class="close-btn">
            <el-icon>
              <Close />
            </el-icon>
          </button>
        </div>
        <div class="modal-body">
          <!-- 海报加载状态 -->
          <div v-if="posterLoading" class="poster-loading">
            <el-skeleton :rows="3" animated />
            <p class="loading-text">正在加载海报模板...</p>
          </div>
          
          <!-- 海报模板列表 -->
          <div v-else-if="posterTemplates.length > 0" class="poster-templates">
            <div 
              v-for="(poster, index) in posterTemplates" 
              :key="poster.id || index"
              class="poster-template"
              :class="{ selected: selectedPosterIndex === index }"
              @click="selectPoster(index)"
            >
              <div class="template-preview">
                <div class="template-image-container">
                  <img :src="poster.preview" :alt="poster.name" />
                  <div class="template-overlay">
                    <div class="overlay-content">
                      <el-icon class="preview-icon">
                        <View />
                      </el-icon>
                      <span>预览</span>
                    </div>
                  </div>
                </div>
                <div class="template-info">
                  <h4 class="template-name">{{ poster.name }}</h4>
                  <p class="template-desc">{{ poster.description || '9:16 竖版海报' }}</p>
                </div>
                <div class="selection-indicator">
                  <div class="check-icon">
                    <el-icon>
                      <Check />
                    </el-icon>
                  </div>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 空状态 -->
          <div v-else class="poster-empty">
            <el-empty description="暂无海报模板">
              <el-button @click="fetchPromotionPosters" type="primary">重新加载</el-button>
            </el-empty>
          </div>
        </div>
        <div class="modal-footer">
          <button @click="closePosterModal" class="cancel-btn">取消</button>
          <button 
            @click="generatePoster" 
            :disabled="selectedPosterIndex === -1"
            class="confirm-btn"
          >
            生成海报
          </button>
        </div>
      </div>
    </div>
    
    <!-- 海报预览弹窗 -->
    <div v-if="posterPreview.visible" class="poster-preview-overlay" @click.self="closePosterPreview">
      <div class="poster-preview-modal">
        <div class="preview-header">
          <h3>海报预览</h3>
          <button @click="closePosterPreview" class="close-btn">
            <el-icon>
              <Close />
            </el-icon>
          </button>
        </div>
        <div class="preview-body">
          <div class="poster-canvas-container">
            <canvas ref="posterCanvas" class="poster-canvas"></canvas>
          </div>
        </div>
        <div class="preview-footer">
          <button @click="closePosterPreview" class="cancel-btn">关闭</button>
          <button @click="downloadPoster" class="download-btn">下载海报</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
import { ElMessage, ElSkeleton, ElTag, ElEmpty, ElTable, ElTableColumn, ElRadioGroup, ElRadioButton, ElPagination } from 'element-plus'
import { Brush, View, Check, Close } from '@element-plus/icons-vue'
import { getMyFans, generateInviteCode, getMyPromotionInfo, getPromotionRules, getPromotionPosters } from '../../api/user.js'
import { getPromotionRulesWithProgress } from '../../api/promotion.js'
import QRCode from 'qrcode'

// 当前选中的标签
const currentTab = ref('invite')

// 标签数据
const tabs = ref([
  { id: 'invite', name: '我的邀请' },
  { id: 'rules', name: '推广规则' },
  { id: 'fans', name: '邀请列表' }
])

// 加载状态
const loading = ref(false)

// 邀请码
const inviteCode = ref('')

// 推广链接
const promotionLink = ref('')

// 推广规则
const promotionRules = ref(null)

// 用户推广状态数据
const promotionUserStatus = ref(null)

// 推广统计信息
const promotionStats = ref({
  inviteCode: '',
  promotionLevel: 0,
  levelName: 'Lv0',
  paidFansCount: 0,
  totalFansCount: 0,
  commissionRate: 0,
  totalCommission: 0,
  points: 0,
  pointsExpiresAt: null,
  createTime: ''
})

// 粉丝列表
const fans = ref([])

// 粉丝统计信息
const fansStats = ref({
  totalFansCount: 0,
  paidFansCount: 0,
  promotionLevel: 0,
  levelName: 'Lv0',
  commissionRate: 0
})

// 当前筛选状态
const currentStatus = ref('all')

// 分页相关
const currentPage = ref(1)
const pageSize = ref(5)
const totalCount = ref(0)

// 海报相关
const posterModal = ref({
  visible: false
})

const posterPreview = ref({
  visible: false
})

const selectedPosterIndex = ref(-1)
const posterCanvas = ref(null)

// 海报模板数据
const posterTemplates = ref([])

// 海报加载状态
const posterLoading = ref(false)

// 生成状态
const generating = ref(false)

// 切换标签
const switchTab = (tabId) => {
  currentTab.value = tabId
  if (tabId === 'rules') {
    fetchPromotionRules()
    // 确保有推广统计信息
    if (!promotionStats.value.inviteCode) {
      fetchMyPromotionInfo()
    }
  } else if (tabId === 'fans') {
    // 重置分页状态并获取数据
    currentPage.value = 1
    pageSize.value = 5
    currentStatus.value = 'all'
    fetchMyFans('all', 1, 5)
    // 确保有推广统计信息用于计算收益
    if (!promotionStats.value.inviteCode) {
      fetchMyPromotionInfo()
    }
  }
}

// 复制邀请码
const copyInviteCode = async () => {
  if (!inviteCode.value) {
    ElMessage.warning('请先生成邀请码')
    return
  }
  
  try {
    await navigator.clipboard.writeText(inviteCode.value)
    ElMessage.success('邀请码已复制')
  } catch (err) {
    ElMessage.error('复制失败')
  }
}

// 复制推广链接
const copyPromotionLink = async () => {
  if (!promotionLink.value) {
    ElMessage.warning('请先生成邀请码')
    return
  }
  
  try {
    await navigator.clipboard.writeText(promotionLink.value)
    ElMessage.success('推广链接已复制')
  } catch (err) {
    ElMessage.error('复制失败')
  }
}



// 获取推广规则
const fetchPromotionRules = async () => {
  try {
    loading.value = true
    const response = await getPromotionRules()
    if (response.success) {
      // 去重处理
      const uniqueLevels = response.promotionLevels?.filter((level, index, self) => 
        index === self.findIndex(l => l.level === level.level)
      ) || []
      
      promotionRules.value = {
        ...response,
        promotionLevels: uniqueLevels
      }
    } else {
      ElMessage.error(response.message || '获取推广规则失败')
    }

    // 获取推广规则加实时进度数据
    try {
      const progressResponse = await getPromotionRulesWithProgress()
      console.log('推广规则加实时进度数据:', progressResponse)
      if (progressResponse && progressResponse.code === 200) {
        promotionUserStatus.value = progressResponse.data
      }
    } catch (progressErr) {
      console.error('获取推广规则实时进度失败:', progressErr)
    }
    
  } catch (err) {
    console.error('获取推广规则失败:', err)
    ElMessage.error('获取推广规则失败')
  } finally {
    loading.value = false
  }
}

// 获取推广海报列表
const fetchPromotionPosters = async () => {
  try {
    posterLoading.value = true
    const response = await getPromotionPosters()
    if (response.code === 200) {
      // 将接口返回的数据转换为组件需要的格式
      posterTemplates.value = response.data?.map(poster => ({
        id: poster.id,
        name: poster.title,
        description: poster.description,
        preview: poster.imageUrl,
        fullImage: poster.imageUrl,
        sortOrder: poster.sortOrder
      })) || []
      
      // 根据sortOrder排序
      posterTemplates.value.sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))
    } else {
      ElMessage.error(response.message || '获取海报模板失败')
      // 如果接口失败，使用默认海报模板作为兜底
      posterTemplates.value = [
        {
          id: 0,
          name: '默认海报',
          description: '默认推广海报',
          preview: '/poster/poster1.png',
          fullImage: '/poster/poster1.png',
          sortOrder: 1
        }
      ]
    }
  } catch (err) {
    console.error('获取海报模板失败:', err)
    ElMessage.error('获取海报模板失败')
    // 如果接口失败，使用默认海报模板作为兜底
    posterTemplates.value = [
      {
        id: 0,
        name: '默认海报',
        description: '默认推广海报',
        preview: '/poster/poster1.png',
        fullImage: '/poster/poster1.png',
        sortOrder: 1
      }
    ]
  } finally {
    posterLoading.value = false
  }
}

// 获取我的粉丝
const fetchMyFans = async (status = 'all', page = 1, size = 5) => {
  try {
    loading.value = true
    const response = await getMyFans({
      page: page,
      size: size,
      status: status
    })
    if (response.code === 200) {
      fans.value = response.data?.fans || []
      totalCount.value = response.data?.totalFansCount || 0
      // 更新统计信息
      fansStats.value = {
        totalFansCount: response.data?.totalFansCount || 0,
        paidFansCount: response.data?.paidFansCount || 0,
        promotionLevel: response.data?.promotionLevel || 0,
        levelName: response.data?.levelName || 'Lv0',
        commissionRate: response.data?.commissionRate || 0
      }
    } else {
      ElMessage.error(response.message || '获取粉丝列表失败')
    }
  } catch (err) {
    console.error('获取粉丝列表失败:', err)
    ElMessage.error('获取粉丝列表失败')
  } finally {
    loading.value = false
  }
}

// 处理状态筛选变化
const handleStatusChange = (status) => {
  currentPage.value = 1 // 重置到第一页
  currentStatus.value = status
}

// 处理页码变化
const handleCurrentChange = (page) => {
  currentPage.value = page
}

// 处理每页大小变化
const handleSizeChange = (size) => {
  currentPage.value = 1 // 重置到第一页
  pageSize.value = size
}

// 监听分页状态变化，确保与接口查询状态同步
watch([currentPage, pageSize, currentStatus], ([newPage, newSize, newStatus], [oldPage, oldSize, oldStatus]) => {
  // 只有在真正需要更新时才调用接口
  if (newPage !== oldPage || newSize !== oldSize || newStatus !== oldStatus) {
    fetchMyFans(newStatus, newPage, newSize)
  }
}, { deep: true })

// 获取我的推广信息
const fetchMyPromotionInfo = async () => {
  try {
    const response = await getMyPromotionInfo()
    if (response.code === 200) {
      // 处理推广信息
      inviteCode.value = response.data?.inviteCode || ''
      if (inviteCode.value) {
        promotionLink.value = `https://www.1818AI.com/home?invite_code=${inviteCode.value}`
      }
      // 保存推广统计信息
      promotionStats.value = response.data || {}
    }
  } catch (err) {
    console.error('获取推广信息失败:', err)
  }
}

// 生成邀请码
const generateCode = async () => {
  generating.value = true
  try {
    const response = await generateInviteCode()
    if (response.code === 200) {
      inviteCode.value = response.data || ''
      // 生成推广链接
      promotionLink.value = `https://www.1818AI.com/home?invite_code=${inviteCode.value}`
      ElMessage.success('邀请码生成成功')
    } else {
      ElMessage.error(response.message || '生成邀请码失败')
    }
  } catch (err) {
    console.error('生成邀请码失败:', err)
    ElMessage.error('生成邀请码失败')
  } finally {
    generating.value = false
  }
}

// 格式化日期
const formatDate = (dateStr) => {
  if (!dateStr) return ''
  const date = new Date(dateStr)
  return date.toLocaleString('zh-CN')
}

// 脱敏手机号
const maskPhone = (phone) => {
  if (!phone) return ''
  return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}

// 计算收益
const calculateRevenue = (fan) => {
  if (!fan.isPaidFan) return 0
  
  // 根据推广等级计算收益
  const commissionRate = fansStats.value.commissionRate || 0
  
  // 假设每个付费用户贡献100元，根据佣金率计算收益
  const baseAmount = 0
  const revenue = baseAmount * commissionRate
  
  return revenue.toFixed(0)
}

// 获取会员状态标签类型
const getMembershipTagType = (status) => {
  switch (status) {
    case 'paid':
      return 'success'
    case 'gift':
      return 'warning'
    case 'free':
      return 'info'
    case 'expired':
      return 'danger'
    default:
      return 'info'
  }
}

// 根据等级获取用户状态数据
const getUserLevelStatus = (level) => {
  if (!promotionUserStatus.value || !promotionUserStatus.value.promotionLevelsWithStatus) {
    return null
  }
  return promotionUserStatus.value.promotionLevelsWithStatus.find(item => item.level === level)
}

// 获取当前总粉丝数
const getCurrentTotalFans = () => {
  return promotionUserStatus.value?.totalFansCount || 0
}

// 根据等级计算应该填充的进度条段数
const getFilledSegments = (level) => {
  const levelStatus = getUserLevelStatus(level)
  if (!levelStatus || !promotionUserStatus.value) {
    return 0
  }
  
  const currentFans = getCurrentTotalFans()
  const requiredFans = levelStatus.minFans
  
  // 如果需要的粉丝数为0，则已完成
  if (requiredFans === 0) {
    return 10
  }
  
  // 如果当前粉丝数已达到或超过要求，显示满进度
  if (currentFans >= requiredFans) {
    return 10
  }
  
  // 计算进度比例 (当前粉丝数/所需粉丝数)
  const progressRatio = currentFans / requiredFans
  
  // 将进度比例转换为10个段中应该填充的段数，至少显示1段（如果有进度的话）
  return Math.max(Math.floor(progressRatio * 10), currentFans > 0 ? 1 : 0)
}

// 海报相关方法
const showPosterModal = async () => {
  if (!promotionLink.value) {
    ElMessage.warning('请先生成邀请链接')
    return
  }
  
  posterModal.value.visible = true
  
  // 如果海报模板为空，则加载海报数据
  if (posterTemplates.value.length === 0) {
    await fetchPromotionPosters()
  }
}

const closePosterModal = () => {
  posterModal.value.visible = false
  selectedPosterIndex.value = -1
}

const selectPoster = (index) => {
  selectedPosterIndex.value = index
}

const generatePoster = async () => {
  if (selectedPosterIndex.value === -1) {
    ElMessage.warning('请选择海报模板')
    return
  }
  
  try {
    const template = posterTemplates.value[selectedPosterIndex.value]
    posterModal.value.visible = false
    posterPreview.value.visible = true
    
    // 等待DOM更新
    await nextTick()
    
    await createPosterWithQR(template)
    
  } catch (error) {
    console.error('生成海报失败:', error)
    ElMessage.error('生成海报失败，请重试')
    posterPreview.value.visible = false
  }
}

const createPosterWithQR = async (template) => {
  const canvas = posterCanvas.value
  const ctx = canvas.getContext('2d')
  
  // 设置画布尺寸 (9:16比例)
  const canvasWidth = 720
  const canvasHeight = 1280
  canvas.width = canvasWidth
  canvas.height = canvasHeight
  
  return new Promise((resolve, reject) => {
    const backgroundImg = new Image()
    backgroundImg.crossOrigin = 'anonymous'
    
    backgroundImg.onload = async () => {
      try {
        // 绘制背景图片
        ctx.drawImage(backgroundImg, 0, 0, canvasWidth, canvasHeight)
        
        // 生成二维码
        const qrCodeDataURL = await QRCode.toDataURL(promotionLink.value, {
          width: 130,
          margin: 2,
          color: {
            dark: '#000000',
            light: '#FFFFFF'
          }
        })
        
        // 绘制二维码
        const qrImg = new Image()
        qrImg.onload = () => {
          // 在右下角绘制二维码，留一定边距
          const qrSize = 130
          const margin = 35
          const qrX = canvasWidth - qrSize - margin
          const qrY = canvasHeight - qrSize - margin
          
          // 绘制二维码背景（白色圆角矩形）
          ctx.fillStyle = 'rgba(255, 255, 255, 0.95)'
          const radius = 12
          ctx.beginPath()
          ctx.roundRect(qrX - 12, qrY - 12, qrSize + 24, qrSize + 24, radius)
          ctx.fill()
          
          // 绘制二维码
          ctx.drawImage(qrImg, qrX, qrY, qrSize, qrSize)
          
          resolve()
        }
        qrImg.onerror = () => reject(new Error('二维码加载失败'))
        qrImg.src = qrCodeDataURL
        
      } catch (error) {
        reject(error)
      }
    }
    
    backgroundImg.onerror = () => reject(new Error('背景图片加载失败'))
    backgroundImg.src = template.fullImage
  })
}

const closePosterPreview = () => {
  posterPreview.value.visible = false
}

const downloadPoster = () => {
  const canvas = posterCanvas.value
  const link = document.createElement('a')
  link.download = `1818AI推广海报_${inviteCode.value}_${Date.now()}.png`
  link.href = canvas.toDataURL('image/png', 0.9)
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  ElMessage.success('海报已下载到本地')
  
  // 下载完成后自动关闭预览弹窗
  closePosterPreview()
}

// 初始化数据
const initData = async () => {
  await fetchMyPromotionInfo()
  // 如果没有邀请码，自动生成
  if (!inviteCode.value) {
    await generateCode()
  }
  // 预加载海报数据
  await fetchPromotionPosters()
}

// 组件挂载时初始化
onMounted(() => {
  initData()
})
</script>

<style scoped>
.promotion-page {
  width: 100%;
  min-height: 800px;
  padding: 0;
  margin: 0;
  overflow: hidden;
  box-sizing: border-box;
}

.promotion-container {
  width: 100%;
  box-sizing: border-box;
}

.page-title {
  width: 312px;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 0;
  margin-bottom: 20px;
}

.title-bar {
  width: 4px;
  height: 24px;
  background: #333;
  border-radius: 2px;
}

.title-text {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 24px;
  line-height: 28px;
  letter-spacing: 0px;
  color: #333;
  margin: 0;
  text-align: left;
}

.promotion-tabs {
  display: flex;
  gap: 20px;
  margin-bottom: 40px;
  padding-bottom: 20px;
  border-bottom: 2px solid rgba(0, 0, 0, 0.1);
  flex-wrap: wrap;
  justify-content: flex-start;
  width: 100%;
}

.promotion-tab {
  width: 120px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  border: 1px solid #e0e0e0;
  border-radius: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 14px;
  font-weight: 500;
  color: #666;
  flex-shrink: 0;
}

.promotion-tab:hover {
  background: #f5f5f5;
  border-color: #d0d0d0;
}

.promotion-tab.active {
  background: #333;
  color: white;
  border-color: #333;
}

.invite-content {
  max-width: 800px;
}

.invite-section {
  margin-bottom: 30px;
}

.section-subtitle {
  font-family: Arial, sans-serif;
  font-weight: 500;
  font-size: 16px;
  color: #333;
  margin: 0 0 12px 0;
  text-align: left;
}

.input-group {
  display: flex;
  gap: 12px;
  align-items: center;
  width: 100%;
}

.invite-input {
  flex: 1;
  height: 48px;
  padding: 0 16px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  font-size: 14px;
  color: #333;
  background: white;
  outline: none;
  transition: border-color 0.3s ease;
  min-width: 0;
  box-sizing: border-box;
}

.invite-input:focus {
  border-color: #333;
}

.generate-button,
.copy-button {
  height: 48px;
  padding: 0 24px;
  background: linear-gradient(135deg, #333 0%, #555 100%);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
  min-width: 120px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  box-shadow: 0 2px 8px rgba(51, 51, 51, 0.2);
}

.generate-button:hover,
.copy-button:hover {
  background: linear-gradient(135deg, #444 0%, #666 100%);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(51, 51, 51, 0.3);
}

.generate-button:disabled {
  background: linear-gradient(135deg, #ccc 0%, #bbb 100%);
  cursor: not-allowed;
  color: #999;
  transform: none;
  box-shadow: none;
}

.copy-button.disabled {
  background: linear-gradient(135deg, #ccc 0%, #bbb 100%);
  cursor: not-allowed;
  color: #999;
  transform: none;
  box-shadow: none;
}

.poster-container {
  position: relative;
}

.poster-placeholder {
  width: 100%;
  height: 200px;
  background: #f8f9fa;
  border: 2px dashed #e0e0e0;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-bottom: 16px;
}


.poster-text {
  font-size: 16px;
  color: #999;
  margin: 0;
}

.download-button {
  position: absolute;
  bottom: 16px;
  right: 16px;
  height: 40px;
  padding: 0 20px;
  background: #333;
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.3s ease;
  white-space: nowrap;
  min-width: 100px;
}

.download-button:hover {
  background: #555;
}

.rules-content {
  max-width: 1000px;
}

.rules-info {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #f0f0f0;
}

.promotion-stats-section {
  margin-bottom: 40px;
}

.promotion-progress-section {
  margin-bottom: 40px;
}

.content-rewards-section {
  margin-bottom: 40px;
}

.content-rewards-section:last-of-type {
  margin-bottom: 30px;
}

.section-title {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 18px;
  color: #333;
  margin: 0 0 12px 0;
}

.progress-cards {
  display: grid;
  grid-template-columns: 1fr; /* 每个progress-card独占一行，宽度自适应 */
  gap: 24px;
}

.progress-card {
  background: white;
  border-radius: 12px;
  padding: 24px;
  border: 1px solid #f0f0f0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  display: flex;
  flex-direction: column;
  gap: 15px;
  transition: all 0.3s ease;
}

.progress-card:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  transform: translateY(-2px);
}

.level-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
}

.level-info {
  flex: 1;
  min-width: 0;
}

.level-name {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 16px;
  color: #333;
  margin: 0 0 4px 0;
}

.level-desc {
  font-size: 12px;
  color: #666;
  margin: 0;
  line-height: 1.4;
}

.commission-info {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
}

.commission-rate {
  font-size: 14px;
  color: #333;
  font-weight: 500;
  background: #f8f9fa;
  padding: 4px 8px;
  border-radius: 4px;
  border: 1px solid #e9ecef;
}

.progress-count {
  font-size: 14px;
  color: #333;
  font-weight: 500;
}

.progress-container {
  position: relative;
  margin-top: 15px;
}

.progress-text {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-bottom: 8px;
}

.progress-text span {
  font-size: 12px;
  color: #666;
  font-weight: 400;
}

.progress-segments {
  display: flex;
  gap: 1px;
  height: 16px;
  background: #f5f5f5;
  border-radius: 8px;
  padding: 1px;
}

.progress-segment {
  flex: 1;
  height: 100%;
  background: #e0e0e0;
  border-radius: 6px;
  transition: background-color 0.3s ease;
}

.progress-segment.filled {
  background: #333;
}

.custom-progress {
  display: none;
}

.level-description {
  margin-top: 10px;
}

.level-description p {
  font-size: 12px;
  color: #666;
  margin: 0;
  line-height: 1.4;
}

.rules-description,
.reward-description {
  margin-bottom: 30px;
}

.rules-description .section-title,
.reward-description .section-title {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 18px;
  color: #333;
  margin: 0 0 12px 0;
}

.rules-description p,
.reward-description p {
  font-size: 14px;
  line-height: 1.6;
  color: #666;
  margin: 0;
}

.levels-grid,
.rewards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
  margin-top: 20px;
}

.reward-card {
  transition: all 0.3s ease;
}

.reward-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}

.reward-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.reward-header h4 {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 16px;
  color: #333;
  margin: 0;
}

.reward-content p {
  font-size: 14px;
  color: #666;
  margin: 0 0 8px 0;
}

.reward-description {
  font-size: 12px;
  color: #999;
  margin-top: 8px;
}

.fans-content {
  max-width: 1000px;
}

.fans-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
  padding: 20px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  border: 1px solid #f0f0f0;
}

.stat-item {
  text-align: center;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
  border: 1px solid #e9ecef;
  transition: all 0.3s ease;
}

.stat-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.stat-number {
  font-family: Arial, sans-serif;
  font-weight: 700;
  font-size: 24px;
  color: #333;
  margin-bottom: 8px;
  line-height: 1;
}

.stat-label {
  font-size: 12px;
  color: #666;
  font-weight: 500;
}

.fans-filter {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
  padding: 16px 20px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  border: 1px solid #f0f0f0;
}

.filter-label {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 14px;
  color: #333;
  white-space: nowrap;
}

.filter-options {
  flex: 1;
}

.filter-options :deep(.el-radio-group) {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.filter-options :deep(.el-radio-button__inner) {
  border-radius: 20px;
  padding: 8px 16px;
  font-size: 12px;
  border: 1px solid #e0e0e0;
  background: white;
  color: #666;
  transition: all 0.3s ease;
}

.filter-options :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
  background: #333;
  border-color: #333;
  color: white;
}

.filter-options :deep(.el-radio-button__inner:hover) {
  background: #f5f5f5;
  border-color: #d0d0d0;
}

.pagination-container {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 24px;
  padding: 16px 0;
  background: white;
  border-radius: 8px;
  border: 1px solid #f0f0f0;
}

.pagination-container :deep(.el-pagination) {
  --el-pagination-bg-color: transparent;
  --el-pagination-text-color: #666;
  --el-pagination-border-radius: 6px;
  --el-pagination-button-color: #666;
  --el-pagination-button-bg-color: #f5f5f5;
  --el-pagination-button-disabled-color: #c0c4cc;
  --el-pagination-button-disabled-bg-color: #f5f5f5;
  --el-pagination-hover-color: #333;
  --el-pagination-hover-bg-color: #e6e6e6;
}

.pagination-container :deep(.el-pagination .el-pager li) {
  background: #f5f5f5;
  border: 1px solid #e0e0e0;
  color: #666;
  transition: all 0.3s ease;
}

.pagination-container :deep(.el-pagination .el-pager li:hover) {
  background: #e6e6e6;
  color: #333;
  border-color: #d0d0d0;
}

.pagination-container :deep(.el-pagination .el-pager li.is-active) {
  background: #333;
  color: white;
  border-color: #333;
}

.pagination-container :deep(.el-pagination .btn-prev),
.pagination-container :deep(.el-pagination .btn-next) {
  background: #f5f5f5;
  border: 1px solid #e0e0e0;
  color: #666;
  transition: all 0.3s ease;
}

.pagination-container :deep(.el-pagination .btn-prev:hover),
.pagination-container :deep(.el-pagination .btn-next:hover) {
  background: #e6e6e6;
  color: #333;
  border-color: #d0d0d0;
}

.pagination-container :deep(.el-pagination .el-pagination__sizes) {
  margin-right: 16px;
}

.pagination-container :deep(.el-pagination .el-pagination__total) {
  margin-right: 16px;
  color: #666;
  font-size: 14px;
}

.fans-table-container {
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  border: 1px solid #f0f0f0;
}

.fans-table {
  width: 100%;
}

.fans-table :deep(.el-table) {
  border: none;
  background: transparent;
}

.fans-table :deep(.el-table__header) {
  background-color: #f8f9fa;
}

.fans-table :deep(.el-table__header th) {
  background-color: #f8f9fa;
  border-bottom: 1px solid #e9ecef;
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 14px;
  color: #333;
  padding: 16px;
}

.fans-table :deep(.el-table__body td) {
  border-bottom: 1px solid #f0f0f0;
  padding: 16px;
  font-size: 14px;
  color: #666;
  vertical-align: middle;
}

.fans-table :deep(.el-table__row:hover) {
  background-color: #f8f9fa;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  overflow: hidden;
  background-color: #f0f0f0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

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

.default-avatar {
  font-size: 18px;
  color: #666;
  font-weight: bold;
}

.user-details {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.username {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 14px;
  color: #333;
  margin: 0 0 4px 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.phone {
  font-family: Arial, sans-serif;
  font-size: 12px;
  color: #999;
  margin: 0;
}

.revenue-amount {
  font-family: Arial, sans-serif;
  font-weight: 600;
  font-size: 14px;
  color: #f5222d;
  cursor: help;
  position: relative;
}

.revenue-amount::after {
  content: '?';
  position: absolute;
  top: -2px;
  right: -12px;
  font-size: 10px;
  color: #999;
  background: #f0f0f0;
  border-radius: 50%;
  width: 12px;
  height: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: normal;
}

.no-revenue {
  font-family: Arial, sans-serif;
  font-weight: 500;
  font-size: 14px;
  color: #999;
  cursor: help;
  position: relative;
}

.no-revenue::after {
  content: '?';
  position: absolute;
  top: -2px;
  right: -12px;
  font-size: 10px;
  color: #999;
  background: #f0f0f0;
  border-radius: 50%;
  width: 12px;
  height: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: normal;
}

.no-expiry {
  font-family: Arial, sans-serif;
  font-size: 12px;
  color: #999;
}

.loading-state {
  text-align: center;
  padding: 40px 20px;
  color: #666;
}

.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: #666;
}

.description-content {
  margin-bottom: 20px;
  padding: 16px 20px;
  background-color: #f8f9fa;
  border: 1px solid #e9ecef;
  border-radius: 8px;
  font-size: 14px;
  color: #666;
  line-height: 1.6;
  border-left: 4px solid #333;
}

.description-content p {
  margin: 0;
  font-weight: 400;
}

.description-card {
  border: none;
  box-shadow: none;
  padding: 0;
  margin-bottom: 20px;
}

.description-card p {
  font-size: 14px;
  line-height: 1.8;
  color: #666;
  margin: 0;
}

.promotion-stats {
  margin-top: 30px;
  padding-top: 20px;
  border-top: 1px solid #eee;
}

.promotion-stats h3 {
  margin-bottom: 15px;
}

.stat-card {
  height: 100%;
  text-align: center;
  transition: all 0.3s ease;
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}

.stat-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 20px 0;
}

.stat-icon {
  font-size: 32px;
  color: #333;
}

.stat-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* 海报相关样式 */
.poster-section {
  margin-bottom: 30px;
  padding: 24px;
  background: white;
  border-radius: 12px;
  border: 1px solid #f0f0f0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
}

.poster-section:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  transform: translateY(-1px);
}

.poster-actions {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-start;
}

.poster-button {
  height: 52px;
  padding: 0 32px;
  background: linear-gradient(135deg, #333 0%, #555 100%);
  color: white;
  border: none;
  border-radius: 26px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  box-shadow: 0 4px 15px rgba(51, 51, 51, 0.3);
  min-width: 200px;
  position: relative;
  overflow: hidden;
}

.poster-button::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
  transition: left 0.5s;
}

.poster-button:hover::before {
  left: 100%;
}

.poster-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(51, 51, 51, 0.4);
}

.poster-button:disabled {
  background: linear-gradient(135deg, #ccc 0%, #bbb 100%);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.poster-button:disabled::before {
  display: none;
}

.poster-icon {
  font-size: 20px;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.3));
}

.poster-icon .el-icon {
  font-size: inherit;
}

.poster-tips {
  font-size: 14px;
  color: #666;
  margin: 0;
  line-height: 1.6;
  padding: 8px 0;
}

/* 海报选择弹窗样式 */
.poster-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.65);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
  backdrop-filter: blur(8px);
  animation: overlayFadeIn 0.3s ease-out;
}

/* 海报加载状态 */
.poster-loading {
  text-align: center;
  padding: 40px 20px;
}

.loading-text {
  margin-top: 20px;
  font-size: 14px;
  color: #666;
}

/* 海报空状态 */
.poster-empty {
  text-align: center;
  padding: 40px 20px;
}

@keyframes overlayFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.poster-modal {
  background: white;
  border-radius: 20px;
  padding: 0;
  width: 90vw;
  max-width: 900px;
  max-height: calc(100vh - 120px);
  margin-top: 80px;
  overflow: hidden;
  box-shadow: 0 25px 80px rgba(0, 0, 0, 0.3);
  animation: modalSlideIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes modalSlideIn {
  from {
    opacity: 0;
    transform: translateY(-50px) scale(0.9);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px 32px;
  border-bottom: 1px solid #f0f0f0;
  background: linear-gradient(135deg, #333 0%, #555 100%);
  color: white;
}

.modal-header h3 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: white;
}

.close-btn {
  background: none;
  border: none;
  font-size: 28px;
  cursor: pointer;
  color: white;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: all 0.3s ease;
  font-weight: 300;
}

.close-btn .el-icon {
  font-size: inherit;
}

.close-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: scale(1.1);
}

.modal-body {
  padding: 32px;
  max-height: calc(60vh - 60px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: #ccc #f5f5f5;
}

.modal-body::-webkit-scrollbar {
  width: 8px;
}

.modal-body::-webkit-scrollbar-track {
  background: #f5f5f5;
  border-radius: 4px;
}

.modal-body::-webkit-scrollbar-thumb {
  background: #ccc;
  border-radius: 4px;
}

.modal-body::-webkit-scrollbar-thumb:hover {
  background: #999;
}

.poster-templates {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  max-width: 100%;
  padding: 8px;
}

.poster-template {
  cursor: pointer;
  position: relative;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  border-radius: 16px;
  overflow: hidden;
  background: white;
  border: 2px solid #e5e7eb;
}

.poster-template:hover {
  transform: translateY(-4px);
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
  border-color: #d1d5db;
}

.poster-template.selected {
  border-color: #333;
  box-shadow: 0 20px 40px rgba(51, 51, 51, 0.15);
}

.template-preview {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
}

.template-image-container {
  position: relative;
  width: 100%;
  aspect-ratio: 9/16;
  overflow: hidden;
  background: #f8fafc;
}

.template-image-container img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}

.template-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6));
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.poster-template:hover .template-overlay {
  opacity: 1;
}

.overlay-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: white;
  text-align: center;
}

.preview-icon {
  font-size: 24px;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

.preview-icon .el-icon {
  font-size: inherit;
}

.overlay-content span {
  font-size: 14px;
  font-weight: 500;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.poster-template:hover .template-image-container img {
  transform: scale(1.05);
}

.template-info {
  padding: 16px;
  text-align: center;
  background: white;
}

.template-name {
  margin: 0 0 4px 0;
  font-size: 15px;
  font-weight: 600;
  color: #1f2937;
  line-height: 1.2;
}

.template-desc {
  margin: 0;
  font-size: 12px;
  color: #6b7280;
  font-weight: 400;
}

.selection-indicator {
  position: absolute;
  top: 12px;
  right: 12px;
  opacity: 0;
  transform: scale(0.8);
  transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.poster-template.selected .selection-indicator {
  opacity: 1;
  transform: scale(1);
}

.check-icon {
  width: 32px;
  height: 32px;
  background: #333;
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  border: 2px solid white;
}

.check-icon .el-icon {
  font-size: inherit;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 16px;
  padding: 24px 32px;
  border-top: 1px solid #f0f0f0;
  background: #fafbfc;
}

.cancel-btn,
.confirm-btn {
  height: 48px;
  padding: 0 28px;
  border: none;
  border-radius: 24px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 100px;
}

.cancel-btn {
  background: #f5f5f5;
  color: #666;
  border: 2px solid #e0e0e0;
}

.cancel-btn:hover {
  background: #e0e0e0;
  border-color: #d0d0d0;
  transform: translateY(-1px);
}

.confirm-btn {
  background: linear-gradient(135deg, #333 0%, #555 100%);
  color: white;
  box-shadow: 0 4px 15px rgba(51, 51, 51, 0.3);
}

.confirm-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(51, 51, 51, 0.4);
}

.confirm-btn:disabled {
  background: linear-gradient(135deg, #ccc 0%, #bbb 100%);
  cursor: not-allowed;
  box-shadow: none;
}

/* 海报预览弹窗样式 */
.poster-preview-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2001;
  backdrop-filter: blur(10px);
  animation: overlayFadeIn 0.3s ease-out;
}

.poster-preview-modal {
  background: white;
  border-radius: 20px;
  padding: 0;
  max-width: 95vw;
  max-height: calc(100vh - 100px);
  margin-top: 60px;
  overflow: hidden;
  box-shadow: 0 30px 100px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  animation: modalSlideIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 28px;
  border-bottom: 1px solid #f0f0f0;
  background: #333;
  color: white;
}

.preview-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: white;
}

.preview-body {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  background: #f8f9fa;
  min-height: 500px;
}

.poster-canvas-container {
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  max-height: 100%;
}

.poster-canvas {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
  border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
  transition: transform 0.3s ease;
}

.poster-canvas:hover {
  transform: scale(1.02);
}

.preview-footer {
  display: flex;
  justify-content: flex-end;
  gap: 16px;
  padding: 24px 28px;
  border-top: 1px solid #f0f0f0;
  background: white;
}

.download-btn {
  height: 48px;
  padding: 0 28px;
  background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
  color: white;
  border: none;
  border-radius: 24px;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(82, 196, 26, 0.3);
  min-width: 120px;
}

.download-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(82, 196, 26, 0.4);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .poster-templates {
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    padding: 6px;
  }
  
  .template-info {
    padding: 12px;
  }
  
  .template-name {
    font-size: 14px;
  }
  
  .template-desc {
    font-size: 11px;
  }
  
  .check-icon {
    width: 28px;
    height: 28px;
    font-size: 14px;
  }
  
  .preview-icon {
    font-size: 20px;
  }
  
  .preview-icon .el-icon {
    font-size: inherit;
  }
  
  .overlay-content span {
    font-size: 12px;
  }
  
  .poster-modal {
    margin: 20px;
    width: calc(100vw - 40px);
    max-width: none;
    max-height: calc(100vh - 140px);
    margin-top: 100px;
  }
  
  .modal-header,
  .modal-footer {
    padding: 20px 24px;
  }
  
  .modal-body {
    padding: 20px;
    max-height: calc(50vh - 60px);
  }
  
  .poster-canvas {
    max-height: 60vh;
  }
  
  .poster-button {
    width: 100%;
    justify-content: center;
  }
}

@media (max-width: 600px) {
  .poster-templates {
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
  }
}

@media (max-width: 480px) {
  .poster-templates {
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    padding: 4px;
  }
  
  .template-info {
    padding: 10px;
  }
  
  .template-name {
    font-size: 13px;
  }
  
  .template-desc {
    font-size: 10px;
  }
  
  .check-icon {
    width: 26px;
    height: 26px;
    font-size: 13px;
    top: 8px;
    right: 8px;
  }
  
  .selection-indicator {
    top: 8px;
    right: 8px;
  }
  
  .preview-icon {
    font-size: 18px;
  }
  
  .preview-icon .el-icon {
    font-size: inherit;
  }
  
  .overlay-content span {
    font-size: 11px;
  }
  
  .modal-header h3 {
    font-size: 18px;
  }
  
  .cancel-btn,
  .confirm-btn {
    height: 44px;
    padding: 0 20px;
    font-size: 14px;
  }
  
  .modal-body {
    padding: 16px;
    max-height: calc(45vh - 50px);
  }
}

@media (max-width: 360px) {
  .poster-templates {
    grid-template-columns: 1fr;
    gap: 16px;
  }
  
  .template-image-container {
    aspect-ratio: 3/4;
  }
}

</style>