<template>
  <div class="status-card monthly-tasks">
    <div class="card-header">
      <img src="/icons/1736425783912140.png" alt="月度任务" class="status-icon">
      <div class="status-info">
        <h3>月度任务</h3>
        <p>进度与一键补齐</p>
      </div>
      <div class="status-badge" :class="{ active: monthHasData }">
        <div class="status-dot" />
        <span v-if="remainingDays > 0">剩余 {{ remainingDays }} 天</span>
        <span v-else>本月最后一天</span>
      </div>
    </div>
    
    <div class="card-content">
      <div class="monthly-row">
        <div class="row-title">钓鱼进度</div>
        <div class="row-value">{{ fishNum }} / {{ FISH_TARGET }}（{{ fishPercent }}%）</div>
      </div>
      
      <div class="monthly-row">
        <div class="row-title">竞技场进度</div>
        <div class="row-value">{{ arenaNum }} / {{ ARENA_TARGET }}（{{ arenaPercent }}%）</div>
      </div>
      
      <div class="action-row">
        <button 
          class="action-button secondary" 
          :disabled="monthLoading || fishToppingUp || arenaToppingUp" 
          @click="fetchMonthlyActivity"
        >
          {{ monthLoading ? '刷新中...' : '刷新进度' }}
        </button>

        <n-button-group>
          <n-button 
            class="action-button" 
            :disabled="monthLoading || fishToppingUp" 
            @click="topUpMonthly('fish')"
          >
            {{ fishToppingUp ? '补齐中...' : '钓鱼补齐' }}
          </n-button>
          <n-dropdown :options="fishMoreOptions" trigger="click" @select="onFishMoreSelect">
            <n-button :disabled="monthLoading || fishToppingUp">▾</n-button>
          </n-dropdown>
        </n-button-group>

        <n-button-group>
          <n-button 
            class="action-button" 
            :disabled="monthLoading || arenaToppingUp" 
            @click="topUpMonthly('arena')"
          >
            {{ arenaToppingUp ? '补齐中...' : '竞技场补齐' }}
          </n-button>
          <n-dropdown :options="arenaMoreOptions" trigger="click" @select="onArenaMoreSelect">
            <n-button :disabled="monthLoading || arenaToppingUp">▾</n-button>
          </n-dropdown>
        </n-button-group>
      </div>
      
      <p class="description muted">
        补齐规则：让"当前天数比例"和"完成比例"一致；若无剩余天数则按满额（{{FISH_TARGET}}/{{ARENA_TARGET}}）计算。
      </p>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useTokenStore } from '@/stores/tokenStore'
import { useBatchTaskStore } from '@/stores/batchTaskStore'
import { useMessage } from 'naive-ui'

const tokenStore = useTokenStore()
const batchTaskStore = useBatchTaskStore()
const message = useMessage()

// 月度任务日志控制函数
const monthLog = (...args) => {
  if (batchTaskStore.logConfig.monthlyTask) {
    console.log(...args)
  }
}

const monthWarn = (...args) => {
  if (batchTaskStore.logConfig.monthlyTask) {
    console.warn(...args)
  }
}

const monthError = (...args) => {
  if (batchTaskStore.logConfig.monthlyTask) {
    console.error(...args)
  }
}

// ==================== 月度任务系统 ====================
// 月度任务目标
const FISH_TARGET = 320      // 钓鱼月度目标
const ARENA_TARGET = 240     // 竞技场月度目标

// 月度任务状态
const monthLoading = ref(false)
const fishToppingUp = ref(false)
const arenaToppingUp = ref(false)
const monthActivity = ref(null)

// 时间计算
const now = new Date()
const daysInMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate()
const dayOfMonth = now.getDate()
const remainingDays = computed(() => Math.max(0, daysInMonth - dayOfMonth))
const monthProgress = computed(() => Math.min(1, Math.max(0, dayOfMonth / daysInMonth)))

// 月度任务数据
const monthHasData = computed(() => !!monthActivity.value)
const myMonthInfo = computed(() => monthActivity.value?.myMonthInfo || {})
const myArenaInfo = computed(() => monthActivity.value?.myArenaInfo || {})

// 当前完成数量
const fishNum = computed(() => Number(myMonthInfo.value?.['2']?.num || 0))
const arenaNum = computed(() => Number(myArenaInfo.value?.num || 0))

// 完成百分比
const fishPercent = computed(() => Math.min(100, Math.round((fishNum.value / FISH_TARGET) * 100)))
const arenaPercent = computed(() => Math.min(100, Math.round((arenaNum.value / ARENA_TARGET) * 100)))

// 应该完成的数量
const fishShouldBe = computed(() => {
  if (remainingDays.value === 0) return FISH_TARGET
  return Math.min(FISH_TARGET, Math.ceil(monthProgress.value * FISH_TARGET))
})
const arenaShouldBe = computed(() => {
  if (remainingDays.value === 0) return ARENA_TARGET
  return Math.min(ARENA_TARGET, Math.ceil(monthProgress.value * ARENA_TARGET))
})

// 下拉菜单选项
const fishMoreOptions = [{ label: '一键完成', key: 'complete-fish' }]
const arenaMoreOptions = [{ label: '一键完成', key: 'complete-arena' }]

// 工具函数：延迟
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms))

// 刷新月度任务进度
const fetchMonthlyActivity = async () => {
  monthLog('🎯 [月度任务] fetchMonthlyActivity 被调用')
  
  if (!tokenStore.selectedToken) {
    monthWarn('⚠️ [月度任务] Token未选中')
    message.warning('请先选择Token')
    return
  }
  
  const status = tokenStore.getWebSocketStatus(tokenStore.selectedToken.id)
  
  if (status !== 'connected') {
    monthWarn('⚠️ [月度任务] WebSocket未连接')
    message.error('WebSocket未连接，请先建立连接')
    return
  }
  
  monthLoading.value = true
  try {
    const tokenId = tokenStore.selectedToken.id
    const result = await tokenStore.sendMessageWithPromise(tokenId, 'activity_get', {}, 10000)
    
    const act = result?.activity || result?.body?.activity || result
    monthActivity.value = act || null
    
    if (act) {
      monthLog('✅ [月度任务] 解析成功:', {
        钓鱼次数: act?.myMonthInfo?.['2']?.num,
        竞技场次数: act?.myArenaInfo?.num
      })
      message.success('月度任务进度已更新')
    }
  } catch (e) {
    monthError('❌ [月度任务] 获取失败:', e)
  } finally {
    monthLoading.value = false
  }
}

// 辅助：获取当日零点时间戳（秒）
const getTodayStartSec = () => {
  const d = new Date()
  d.setHours(0, 0, 0, 0)
  return Math.floor(d.getTime() / 1000)
}

// 判断今天是否可用（用于免费钓鱼）
const isTodayAvailable = (lastTimeSec) => {
  if (!lastTimeSec || typeof lastTimeSec !== 'number') return true
  const todayStart = getTodayStartSec()
  return lastTimeSec < todayStart
}

// 自动补齐钓鱼
const autoTopUpFish = async (need, shouldBe, target) => {
  if (!tokenStore.selectedToken) {
    message.warning('请先选择Token')
    return
  }
  
  fishToppingUp.value = true
  try {
    const tokenId = tokenStore.selectedToken.id

    // 检查免费次数
    let role = tokenStore.gameData?.roleInfo?.role
    if (!role) {
      try { await tokenStore.sendGetRoleInfo(tokenId) } catch {}
      role = tokenStore.gameData?.roleInfo?.role
    }

    let freeUsed = 0
    const lastFreeTime = Number(role?.statisticsTime?.['artifact:normal:lottery:time'] || 0)
    
    if (isTodayAvailable(lastFreeTime)) {
      message.info('检测到今日免费钓鱼次数，开始消耗 3 次')
      for (let i = 0; i < 3; i++) {
        try {
          await tokenStore.sendMessageWithPromise(tokenId, 'artifact_lottery', { lotteryNumber: 1, newFree: true, type: 1 }, 8000)
          freeUsed++
          await sleep(500)
        } catch (e) {
          break
        }
      }
      if (freeUsed > 0) {
        await fetchMonthlyActivity()
      }
    }

    // 计算剩余需要次数
    const currentAfterFree = fishNum.value
    let remaining = Math.max(0, shouldBe - currentAfterFree)
    if (remaining <= 0) {
      message.success('已通过免费次数完成当日目标')
      return
    }

    message.info(`开始付费钓鱼补齐：共需 ${remaining} 次（每次最多10）`)

    // 批量执行
    while (remaining > 0) {
      const batch = Math.min(10, remaining)
      try {
        await tokenStore.sendMessageWithPromise(tokenId, 'artifact_lottery', { lotteryNumber: batch, newFree: true, type: 1 }, 12000)
      } catch (e) {
        message.error(`钓鱼失败：${e.message}`)
        break
      }
      remaining -= batch
      await sleep(800)
    }

    await fetchMonthlyActivity()
    if (fishNum.value >= shouldBe || fishNum.value >= target) {
      message.success('钓鱼补齐完成')
    } else {
      message.warning('钓鱼补齐已停止，未达到目标')
    }
  } finally {
    fishToppingUp.value = false
  }
}

// 自动补齐竞技场
const autoTopUpArena = async (need, shouldBe, target) => {
  if (!tokenStore.selectedToken) {
    message.warning('请先选择Token')
    return
  }
  
  arenaToppingUp.value = true
  try {
    const tokenId = tokenStore.selectedToken.id
    
    try {
      await tokenStore.sendMessageWithPromise(tokenId, 'arena_startarea', {}, 6000)
    } catch (e) {
      monthWarn('⚠️ [竞技场] arena_startarea 失败:', e.message)
    }

    let safetyCounter = 0
    const safetyMaxFights = 100
    let round = 1
    let remaining = need

    while (remaining > 0 && safetyCounter < safetyMaxFights) {
      const planFights = Math.ceil(remaining / 2)
      message.info(`竞技场补齐 第${round}轮：计划战斗 ${planFights} 场（估算每胜+2）`)

      for (let i = 0; i < planFights && safetyCounter < safetyMaxFights; i++) {
        let targets
        try {
          targets = await tokenStore.sendMessageWithPromise(tokenId, 'arena_getareatarget', { refresh: false }, 8000)
        } catch (e) {
          try {
            targets = await tokenStore.sendMessageWithPromise(tokenId, 'arena_getareatarget', { refresh: true }, 8000)
          } catch (e2) {
            message.error(`获取竞技场目标失败：${e2.message}`)
            break
          }
        }

        const targetId = targets?.roleList?.[0]?.roleId || targets?.targets?.[0]?.roleId || targets?.targets?.[0]?.id
        
        if (!targetId) {
          message.warning('未找到可用的竞技场目标，已停止此轮')
          break
        }

        try {
          await tokenStore.sendMessageWithPromise(tokenId, 'fight_startareaarena', { targetId }, 15000)
        } catch (e) {
          monthError(`❌ [竞技场] 战斗失败:`, e)
        }

        safetyCounter++
        await sleep(1200)
      }

      await fetchMonthlyActivity()
      const cur = arenaNum.value
      remaining = Math.max(0, shouldBe - cur)
      round++
    }

    if (arenaNum.value >= shouldBe || arenaNum.value >= target) {
      message.success('竞技场补齐完成')
    } else if (safetyCounter >= safetyMaxFights) {
      message.warning('达到安全上限，已停止竞技场补齐')
    } else {
      message.warning('竞技场补齐已停止，未达到目标')
    }
  } finally {
    arenaToppingUp.value = false
  }
}

// 补齐入口
const topUpMonthly = (type) => {
  const isFish = type === 'fish'
  const target = isFish ? FISH_TARGET : ARENA_TARGET
  const current = isFish ? fishNum.value : arenaNum.value
  const shouldBe = remainingDays.value === 0 ? target : Math.min(target, Math.ceil((monthProgress.value * target)))
  const need = Math.max(0, shouldBe - current)

  if (need <= 0) {
    message.success('当前进度已达标，无需补齐')
    return
  }
  if (isFish) {
    autoTopUpFish(need, shouldBe, target)
  } else {
    autoTopUpArena(need, shouldBe, target)
  }
}

// 完成本项任务
const completeMonthly = (type) => {
  const isFish = type === 'fish'
  const target = isFish ? FISH_TARGET : ARENA_TARGET
  const current = isFish ? fishNum.value : arenaNum.value
  const need = Math.max(0, target - current)

  if (need <= 0) {
    message.success('已满额，无需完成')
    return
  }
  if (isFish) {
    autoTopUpFish(need, target, target)
  } else {
    autoTopUpArena(need, target, target)
  }
}

// 下拉菜单选择处理
const onFishMoreSelect = (key) => {
  if (key === 'complete-fish') completeMonthly('fish')
}
const onArenaMoreSelect = (key) => {
  if (key === 'complete-arena') completeMonthly('arena')
}

// 生命周期
onMounted(() => {
  // 监听 WebSocket 状态变化
  if (tokenStore.selectedToken) {
    const tokenId = tokenStore.selectedToken.id
    let monthTaskFetched = false
    
    const checkAndFetchMonthly = () => {
      const status = tokenStore.getWebSocketStatus(tokenId)
      if (status === 'connected' && !monthTaskFetched) {
        monthTaskFetched = true
        setTimeout(() => {
          fetchMonthlyActivity()
        }, 1000)
      }
    }
    
    checkAndFetchMonthly()
    
    let checkCount = 0
    const checkInterval = setInterval(() => {
      checkCount++
      if (checkCount >= 5) {
        clearInterval(checkInterval)
      } else if (tokenStore.getWebSocketStatus(tokenId) === 'connected' && !monthTaskFetched) {
        clearInterval(checkInterval)
        checkAndFetchMonthly()
      }
    }, 1000)
    
    onUnmounted(() => {
      clearInterval(checkInterval)
    })
  }
})
</script>

<style scoped lang="scss">
.status-card {
  background: var(--bg-primary);
  border-radius: var(--border-radius-xl);
  padding: var(--spacing-lg);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.02);
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  position: relative;
  overflow: hidden;
  
  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--primary-color), var(--primary-color-light));
    opacity: 0.8;
    transition: opacity 0.3s ease;
  }
  
  &:hover {
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.04);
    transform: translateY(-4px);
    
    &::before {
      opacity: 1;
    }
  }
}

.card-header {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-lg);
  position: relative;
}

.status-icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
  flex-shrink: 0;
}

.status-info {
  flex: 1;

  h3 {
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin: 0 0 var(--spacing-xs) 0;
  }

  p {
    font-size: var(--font-size-sm);
    color: var(--text-secondary);
    margin: 0;
  }
}

.status-badge {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  padding: var(--spacing-xs) var(--spacing-sm);
  border-radius: var(--border-radius-full);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  background: rgba(156, 163, 175, 0.1);
  color: var(--text-secondary);

  &.active {
    background: rgba(34, 197, 94, 0.1);
    color: var(--success-color);
  }
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
}

.monthly-tasks {
  .monthly-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--spacing-sm) 0;
    border-bottom: 1px solid var(--border-light);
    
    .row-title {
      color: var(--text-secondary);
      font-size: var(--font-size-sm);
    }
    
    .row-value {
      font-weight: var(--font-weight-semibold);
      color: var(--text-primary);
    }
  }
  
  .action-row {
    display: flex;
    gap: var(--spacing-sm);
    margin-top: var(--spacing-md);
    flex-wrap: wrap;
  }
  
  .description.muted {
    margin-top: var(--spacing-sm);
    font-size: var(--font-size-xs);
    color: var(--text-tertiary);
    line-height: 1.5;
  }
}

.action-button {
  padding: var(--spacing-sm) var(--spacing-md);
  border: none;
  border-radius: var(--border-radius-medium);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
  background: linear-gradient(135deg, var(--primary-color), var(--primary-color-light));
  color: white;
  
  &.secondary {
    background: linear-gradient(135deg, #8b5cf6, #a78bfa);
  }
  
  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}

@media (max-width: 768px) {
  .status-card {
    padding: var(--spacing-md);
  }

  .card-header {
    flex-direction: column;
    text-align: center;
    gap: var(--spacing-sm);
  }
}
</style>

