<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { ArrowLeft, Loading } from '@element-plus/icons-vue'
import { getBet, getBetOptions, getBetEntries, placeBet, closeBet, subscribeBets } from '@/api/bets'
import { pb } from '@/api/pocketbase'
import { displayName } from '@/types'
import type { Bet, BetOption, BetEntry } from '@/types'
import BetEntryList from './BetEntryList.vue'
import SettleBetDialog from './SettleBetDialog.vue'

const props = defineProps<{
  betId: string
}>()

const emit = defineEmits<{
  back: []
}>()

// 数据
const bet = ref<Bet | null>(null)
const options = ref<BetOption[]>([])
const entries = ref<BetEntry[]>([])
const loading = ref(false)

// 下注表单
const selectedOption = ref('')
const stakeAmount = ref(1)

// 结算弹窗
const showSettle = ref(false)

// 实时订阅
let unsubscribeFn: (() => void) | null = null

// 计算属性
const creatorName = computed(() => displayName(bet.value?.expand?.creator))

const totalPool = computed(() => entries.value.reduce((sum, e) => sum + e.stake, 0))

// 各选项的下注总额和人数
const optionStats = computed(() => {
  const stats: Record<string, { totalStake: number; count: number }> = {}
  for (const opt of options.value) {
    stats[opt.id] = { totalStake: 0, count: 0 }
  }
  for (const e of entries.value) {
    if (!stats[e.option]) {
      stats[e.option] = { totalStake: 0, count: 0 }
    }
    stats[e.option].totalStake += e.stake
    stats[e.option].count += 1
  }
  return stats
})

// 当前用户
const currentUserId = computed(() => pb.authStore.model?.id)
const isCreator = computed(() => bet.value?.creator === currentUserId.value)

// 当前用户的下注记录
const currentUserEntry = computed(() =>
  entries.value.find((e) => e.user === currentUserId.value) || null
)

// 状态
const isOpen = computed(() => bet.value?.status === 'open')
const isClosed = computed(() => bet.value?.status === 'closed')
const isSettled = computed(() => bet.value?.status === 'settled')

// 结果选项ID
const resultOptionId = computed(() => bet.value?.resultOption || '')

// 加载数据
async function loadDetail() {
  loading.value = true
  try {
    const [betData, optionsData, entriesData] = await Promise.all([
      getBet(props.betId),
      getBetOptions(props.betId),
      getBetEntries(props.betId),
    ])
    bet.value = betData
    options.value = optionsData
    entries.value = entriesData
  } catch (error) {
    console.error('加载竞猜详情失败:', error)
  } finally {
    loading.value = false
  }
}

// 下注
async function handlePlaceBet() {
  if (!selectedOption.value) {
    ElMessage.warning('请选择一个选项')
    return
  }
  if (!stakeAmount.value || stakeAmount.value < 1) {
    ElMessage.warning('请输入有效的积分数')
    return
  }

  try {
    await placeBet(props.betId, selectedOption.value, stakeAmount.value)
    ElMessage.success('下注成功')
    await loadDetail()
  } catch (error: any) {
    ElMessage.error(error.message || '下注失败')
  }
}

// 关闭竞猜
async function handleClose() {
  try {
    await ElMessageBox.confirm('确定要关闭竞猜吗？关闭后将不能再下注。', '关闭竞猜', {
      confirmButtonText: '确定关闭',
      cancelButtonText: '取消',
      type: 'warning',
    })
    await closeBet(props.betId)
    ElMessage.success('竞猜已关闭')
    await loadDetail()
  } catch {
    // 用户取消
  }
}

// 实时订阅
async function startSubscription() {
  if (unsubscribeFn) {
    unsubscribeFn()
    unsubscribeFn = null
  }
  if (!bet.value) return
  const groupId = bet.value.group
  unsubscribeFn = await subscribeBets(groupId, () => {
    loadDetail()
  })
}

onMounted(async () => {
  await loadDetail()
  startSubscription()
})

onUnmounted(() => {
  if (unsubscribeFn) {
    unsubscribeFn()
    unsubscribeFn = null
  }
})
</script>

<template>
  <div class="bet-detail">
    <!-- 顶部操作栏 -->
    <div class="bet-detail__header">
      <el-button text @click="emit('back')">
        <el-icon><ArrowLeft /></el-icon>
        返回
      </el-button>
      <div class="bet-detail__actions">
        <button
          v-if="isCreator && isOpen"
          class="action-btn action-btn--close"
          @click="handleClose"
        >
          关闭竞猜
        </button>
        <button
          v-if="isCreator && isClosed"
          class="action-btn action-btn--settle"
          @click="showSettle = true"
        >
          开奖
        </button>
      </div>
    </div>

    <!-- 加载中 -->
    <div v-if="loading" class="bet-detail__loading">
      <el-icon class="is-loading"><Loading /></el-icon>
      <span>加载中...</span>
    </div>

    <!-- 竞猜内容 -->
    <template v-else-if="bet">
      <!-- 标题区域 -->
      <div class="bet-detail__title-area">
        <h2 class="bet-detail__title">{{ bet.title }}</h2>
        <div class="bet-detail__meta">
          <span class="bet-detail__meta-item">
            <svg class="meta-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
              <circle cx="12" cy="7" r="4" />
            </svg>
            {{ creatorName }} 发起
          </span>
          <span class="bet-detail__meta-item">
            <svg class="meta-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
              <line x1="12" y1="1" x2="12" y2="23" />
              <path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6" />
            </svg>
            奖池 {{ totalPool }} 积分
          </span>
          <span class="bet-detail__meta-item">
            下注范围 {{ bet.minStake }}~{{ bet.maxStake }} 积分
          </span>
        </div>
      </div>

      <!-- 描述 -->
      <div v-if="bet.description" class="bet-detail__desc">
        {{ bet.description }}
      </div>

      <!-- 选项列表 -->
      <div class="bet-detail__options">
        <div
          v-for="option in options"
          :key="option.id"
          :class="[
            'bet-detail__option',
            {
              'bet-detail__option--winner': isSettled && resultOptionId === option.id,
              'bet-detail__option--loser': isSettled && resultOptionId !== option.id,
            },
          ]"
        >
          <div class="bet-detail__option-header">
            <span class="bet-detail__option-name">
              {{ option.content }}
              <span v-if="isSettled && resultOptionId === option.id" class="winner-badge">
                正确答案
              </span>
            </span>
            <div class="bet-detail__option-stats">
              <span class="bet-detail__option-count">
                {{ (optionStats[option.id]?.count || 0) }} 人
              </span>
              <span class="bet-detail__option-stake">
                {{ optionStats[option.id]?.totalStake || 0 }} 积分
              </span>
            </div>
          </div>
          <div class="bet-detail__option-bar">
            <div
              class="bet-detail__option-fill"
              :class="{ 'bet-detail__option-fill--winner': isSettled && resultOptionId === option.id }"
              :style="{
                width: totalPool > 0
                  ? ((optionStats[option.id]?.totalStake || 0) / totalPool * 100) + '%'
                  : '0%',
              }"
            />
          </div>
        </div>
      </div>

      <!-- 下注区域（状态 open 且未下注时） -->
      <div v-if="isOpen && !currentUserEntry" class="bet-detail__bet-area">
        <h4 class="bet-detail__bet-title">下注</h4>
        <div class="bet-detail__bet-form">
          <div class="bet-detail__bet-option">
            <label>选择选项</label>
            <div class="bet-detail__option-pick">
              <button
                v-for="option in options"
                :key="option.id"
                type="button"
                :class="['bet-detail__pick-card', { 'bet-detail__pick-card--active': selectedOption === option.id }]"
                @click="selectedOption = option.id"
              >
                {{ option.content }}
              </button>
            </div>
          </div>
          <div class="bet-detail__bet-stake">
            <label>下注积分</label>
            <el-input-number
              v-model="stakeAmount"
              :min="bet.minStake"
              :max="bet.maxStake"
              :step="1"
            />
          </div>
          <button
            class="bet-detail__bet-btn"
            :disabled="!selectedOption"
            @click="handlePlaceBet"
          >
            下注
          </button>
        </div>
      </div>

      <!-- 已下注提示 -->
      <div v-if="isOpen && currentUserEntry" class="bet-detail__already-bet">
        <svg class="bet-detail__already-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14" />
          <polyline points="22 4 12 14.01 9 11.01" />
        </svg>
        <span>
          你已下注 <strong>{{ currentUserEntry.stake }}</strong> 积分，选择「{{ currentUserEntry.expand?.option?.content || '未知' }}」
        </span>
      </div>

      <!-- 下注记录 -->
      <div class="bet-detail__entries">
        <h4 class="bet-detail__entries-title">下注记录</h4>
        <BetEntryList :entries="entries" :show-result="isSettled" />
      </div>
    </template>

    <!-- 开奖弹窗 -->
    <SettleBetDialog
      v-if="bet"
      v-model="showSettle"
      :bet-id="betId"
      :options="options"
      @settled="loadDetail"
    />
  </div>
</template>

<style scoped>
.bet-detail {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 顶部操作栏 */
.bet-detail__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.bet-detail__actions {
  display: flex;
  gap: 8px;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 6px 14px;
  border: none;
  border-radius: var(--gg-radius-sm);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: opacity 0.2s, border-color 0.2s, color 0.2s;
}

.action-btn--close {
  background: var(--gg-bg-card);
  border: 1px solid var(--gg-border);
  color: var(--gg-text-secondary);
}

.action-btn--close:hover {
  border-color: var(--gg-danger);
  color: var(--gg-danger);
}

.action-btn--settle {
  background: var(--gg-gradient);
  color: #fff;
}

.action-btn--settle:hover {
  opacity: 0.85;
}

/* 加载中 */
.bet-detail__loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 40px 0;
  color: var(--gg-text-secondary);
}

/* 标题区域 */
.bet-detail__title-area {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bet-detail__title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--gg-text);
}

.bet-detail__meta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.bet-detail__meta-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--gg-text-secondary);
}

.meta-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

/* 描述 */
.bet-detail__desc {
  font-size: 14px;
  color: var(--gg-text-secondary);
  line-height: 1.6;
  padding: 10px 14px;
  background: var(--gg-bg-elevated);
  border-radius: var(--gg-radius-sm);
}

/* 选项列表 */
.bet-detail__options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.bet-detail__option {
  padding: 12px 16px;
  border: 1px solid var(--gg-border);
  border-radius: 8px;
  transition: all 0.2s;
}

.bet-detail__option--winner {
  border-color: var(--gg-success);
  background: rgba(16, 185, 129, 0.06);
}

.bet-detail__option--loser {
  opacity: 0.5;
}

.bet-detail__option-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.bet-detail__option-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--gg-text);
  display: flex;
  align-items: center;
  gap: 6px;
}

.winner-badge {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(16, 185, 129, 0.12);
  color: var(--gg-success);
}

.bet-detail__option-stats {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.bet-detail__option-count {
  font-size: 12px;
  color: var(--gg-text-secondary);
}

.bet-detail__option-stake {
  font-size: 12px;
  font-weight: 600;
  color: var(--gg-primary);
}

.bet-detail__option-bar {
  height: 6px;
  background: var(--gg-bg-elevated);
  border-radius: 3px;
  overflow: hidden;
}

.bet-detail__option-fill {
  height: 100%;
  background: var(--gg-primary);
  border-radius: 3px;
  transition: width 0.3s ease;
}

.bet-detail__option-fill--winner {
  background: var(--gg-success);
}

/* 下注区域 */
.bet-detail__bet-area {
  padding: 16px;
  border: 1px solid var(--gg-border);
  border-radius: var(--gg-radius-md);
  background: var(--gg-bg-card);
}

.bet-detail__bet-title {
  margin: 0 0 12px;
  font-size: 15px;
  font-weight: 600;
  color: var(--gg-text);
}

.bet-detail__bet-form {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
}

.bet-detail__bet-option,
.bet-detail__bet-stake {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.bet-detail__bet-option label,
.bet-detail__bet-stake label {
  font-size: 13px;
  color: var(--gg-text-secondary);
}

.bet-detail__option-pick {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.bet-detail__pick-card {
  padding: 6px 16px;
  border: 1px solid var(--gg-border);
  border-radius: var(--gg-radius-sm);
  background: var(--gg-bg-card);
  font-size: 13px;
  color: var(--gg-text-secondary);
  cursor: pointer;
  transition: all 0.2s;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.bet-detail__pick-card:hover {
  border-color: var(--gg-primary);
  color: var(--gg-primary);
}

.bet-detail__pick-card--active {
  border-color: var(--gg-primary);
  background: rgba(5, 150, 105, 0.08);
  color: var(--gg-primary);
  font-weight: 500;
}

.bet-detail__bet-btn {
  padding: 8px 24px;
  border: none;
  border-radius: var(--gg-radius-sm);
  background: var(--gg-gradient);
  color: #fff;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: opacity 0.2s;
}

.bet-detail__bet-btn:hover {
  opacity: 0.85;
}

.bet-detail__bet-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 已下注提示 */
.bet-detail__already-bet {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: rgba(5, 150, 105, 0.06);
  border-radius: var(--gg-radius-sm);
  font-size: 14px;
  color: var(--gg-text-secondary);
}

.bet-detail__already-bet strong {
  color: var(--gg-primary);
}

.bet-detail__already-icon {
  width: 18px;
  height: 18px;
  color: var(--gg-success);
  flex-shrink: 0;
}

/* 下注记录 */
.bet-detail__entries {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.bet-detail__entries-title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--gg-text);
}

/* 响应式 */
@media (max-width: 640px) {
  .bet-detail__bet-form {
    flex-direction: column;
    align-items: stretch;
  }
}
</style>
