<template>
  <div class="daily-task-container">
      <div class="card-header">
        <img
          src="/icons/173746572831736.png"
          alt="每日任务图标"
          class="status-icon"
        >
        <div class="status-info">
          <h3>每日任务</h3>
          <p>每日任务完成进度</p>
        </div>
        <div class="header-actions">
          <button class="icon-button" @click="showTaskDetails = true" title="查看任务详情">
            <n-icon size="18"><Calendar /></n-icon>
          </button>
          <button class="icon-button" @click="showSettings = true" title="任务设置">
            <n-icon size="18"><Settings /></n-icon>
          </button>
          <div class="status-badge" :class="{ completed: isFull }">
            <div class="status-dot" :class="{ completed: isFull }" />
            <span>{{ isFull ? '已完成' : '进行中' }}</span>
          </div>
        </div>
      </div>
      <div class="card-content">
        <div class="progress-container">
          <n-progress
            type="line"
            :percentage="dailyPoint"
            :color="progressColor"
            :height="8"
            :border-radius="4"
            processing
          />
        </div>
        <div class="info-container">
          <p>当前活跃度: {{ dailyPoint }} / 100</p>
          <p v-if="isFull" style="color: var(--success-color); font-weight: 500;">
            ✅ 今日活跃度已满，可以领取活跃度奖励！
          </p>
        </div>
        <button
          class="action-button"
          :class="{ completed: isFull }"
          :disabled="busy || !isConnected || isFull"
          @click="runDailyFix"
        >
          <span v-if="busy" class="loading-text">
            <svg class="loading-icon" viewBox="0 0 24 24">
              <path fill="currentColor" d="M12 22c5.421 0 10-4.579 10-10h-2c0 4.337-3.663 8-8 8s-8-3.663-8-8c0-4.336 3.663-8 8-8V2C6.579 2 2 6.58 2 12c0 5.421 4.579 10 10 10z" />
            </svg>
            执行中...
          </span>
          <span v-else-if="!isConnected">连接中断</span>
          <span v-else-if="isFull">✅ 已完成</span>
          <span v-else>一键执行日常任务</span>
        </button>
      </div>

    <!-- 任务设置模态框 -->
    <n-modal
      v-model:show="showSettings"
      preset="card"
      title="任务设置"
      style="width: 400px"
    >
      <template #header>
        <div class="modal-header">
          <n-icon><Settings /></n-icon>
          <span>任务设置</span>
        </div>
      </template>

      <div class="settings-content">
        <div class="settings-grid">
          <!-- 竞技场设置 -->
          <div class="setting-item">
            <label class="setting-label">竞技场阵容</label>
            <n-select
              v-model:value="settings.arenaFormation"
              :options="formationOptions"
              size="small"
            />
          </div>

          <!-- BOSS设置 -->
          <div class="setting-item">
            <label class="setting-label">BOSS阵容</label>
            <n-select
              v-model:value="settings.bossFormation"
              :options="formationOptions"
              size="small"
            />
          </div>

          <!-- BOSS次数 -->
          <div class="setting-item">
            <label class="setting-label">BOSS次数</label>
            <n-select
              v-model:value="settings.bossTimes"
              :options="bossTimesOptions"
              size="small"
            />
          </div>

          <!-- 功能开关 -->
          <div class="setting-switches">
            <div class="switch-row">
              <span class="switch-label">领罐子</span>
              <n-switch
                v-model:value="settings.claimBottle"
              />
            </div>

            <div class="switch-row">
              <span class="switch-label">领挂机</span>
              <n-switch
                v-model:value="settings.claimHangUp"
              />
            </div>

            <div class="switch-row">
              <span class="switch-label">竞技场</span>
              <n-switch
                v-model:value="settings.arenaEnable"
              />
            </div>

            <div class="switch-row">
              <span class="switch-label">开宝箱</span>
              <n-switch
                v-model:value="settings.openBox"
              />
            </div>

            <div class="switch-row">
              <span class="switch-label">领取邮件奖励</span>
              <n-switch
                v-model:value="settings.claimEmail"
              />
            </div>
            <div class="switch-row">
              <span class="switch-label">黑市购买物品</span>
              <n-switch
                v-model:value="settings.blackMarketPurchase"
              />
            </div>

            <div class="switch-row">
              <span class="switch-label">付费招募</span>
              <n-switch
                v-model:value="settings.payRecruit"
              />
            </div>
          </div>
        </div>
      </div>
    </n-modal>

    <!-- 任务详情模态框 -->
    <n-modal
      v-model:show="showTaskDetails"
      preset="card"
      title="每日任务详情"
      style="width: 400px"
    >
      <template #header>
        <div class="modal-header">
          <n-icon><Calendar /></n-icon>
          <span>每日任务详情</span>
          <button
            class="refresh-button"
            :disabled="busy"
            @click="handleRefreshTaskStatus"
          >
            <n-icon><Refresh /></n-icon>
            刷新状态
          </button>
        </div>
      </template>

      <div class="task-list">
        <div
          v-for="task in tasks"
          :key="task.id"
          class="task-item"
        >
          <div class="task-item-left">
            <n-icon
              class="task-status-icon"
              :class="{ completed: task.completed }"
            >
              <CheckmarkCircle v-if="task.completed" />
              <EllipseOutline v-else />
            </n-icon>
            <span class="task-name">{{ task.name }}</span>
          </div>
          <n-tag
            :type="task.completed ? 'success' : 'default'"
            size="small"
          >
            {{ task.completed ? '已完成' : '未完成' }}
          </n-tag>
        </div>
      </div>
    </n-modal>

    <!-- 执行日志模态框 -->
    <n-modal
      v-model:show="showLog"
      preset="card"
      title="任务执行日志"
      style="width: 500px"
    >
      <template #header>
        <div class="modal-header">
          <n-icon><DocumentText /></n-icon>
          <span>任务执行日志</span>
        </div>
      </template>

      <div
        ref="logContainer"
        class="log-container"
      >
        <div
          v-for="logItem in logList"
          :key="logItem.time + logItem.message"
          class="log-item"
        >
          <span class="log-time">{{ logItem.time }}</span>
          <span
            class="log-message"
            :class="{
              error: logItem.type === 'error',
              success: logItem.type === 'success',
              warning: logItem.type === 'warning'
            }"
          >
            {{ logItem.message }}
          </span>
        </div>
      </div>
    </n-modal>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useTokenStore } from '@/stores/tokenStore'
import { useMessage } from 'naive-ui'
import {
  Settings,
  Calendar,
  CheckmarkCircle,
  EllipseOutline,
  DocumentText,
  Refresh
} from '@vicons/ionicons5'

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

// 响应式数据
const showSettings = ref(false)
const showTaskDetails = ref(false)
const showLog = ref(false)
const busy = ref(false)
const logContainer = ref(null)

// 任务设置
const settings = reactive({
  arenaFormation: 1,
  bossFormation: 1,
  bossTimes: 4,
  claimBottle: true,
  payRecruit: true,
  openBox: true,
  arenaEnable: true,
  claimHangUp: true,
  claimEmail: true,
  blackMarketPurchase: true
})

// 每日任务列表
const tasks = ref([
  { id: 1, name: '登录一次游戏', completed: false, loading: false },
  { id: 2, name: '分享一次游戏', completed: false, loading: false },
  { id: 3, name: '赠送好友3次金币', completed: false, loading: false },
  { id: 4, name: '进行2次招募', completed: false, loading: false },
  { id: 5, name: '领取5次挂机奖励', completed: false, loading: false },
  { id: 6, name: '进行3次点金', completed: false, loading: false },
  { id: 7, name: '开启3次宝箱', completed: false, loading: false },
  { id: 12, name: '黑市购买1次物品（请设置采购清单）', completed: false, loading: false },
  { id: 13, name: '进行1场竞技场战斗', completed: false, loading: false },
  { id: 14, name: '收获1个任意盐罐', completed: false, loading: false }
])

// 选项配置
const formationOptions = [1,2,3,4].map(v => ({ label: `阵容${v}`, value: v }))
const bossTimesOptions = [0,1,2,3,4].map(v => ({ label: `${v}次`, value: v }))

// 计算属性
const roleInfo = computed(() => {
  return tokenStore.selectedTokenRoleInfo
})

const roleDailyPoint = computed(() => {
  return roleInfo.value?.role?.dailyTask?.dailyPoint ?? 0
})

const dailyPoint = computed(() => Math.min(roleDailyPoint.value, 100))
const isFull = computed(() => dailyPoint.value >= 100)
const progressColor = computed(() => isFull.value ? '#10b981' : '#3b82f6')

// WebSocket连接状态
const isConnected = computed(() => {
  if (!tokenStore.selectedToken) return false
  const status = tokenStore.getWebSocketStatus(tokenStore.selectedToken.id)
  return status === 'connected'
})

// 日志系统
const logList = ref([])
const LOG_MAX = 500

const log = (message, type = 'info') => {
  const time = new Date().toLocaleTimeString()
  logList.value.push({ time, message, type })

  if (logList.value.length > LOG_MAX) {
    logList.value.splice(0, logList.value.length - LOG_MAX)
  }

  nextTick(() => {
    if (logContainer.value) {
      logContainer.value.scrollTop = logContainer.value.scrollHeight
    }
  })
}

// 同步服务器任务完成状态
const syncCompleteFromServer = (resp) => {
  if (!resp?.role?.dailyTask?.complete) {
    log('角色信息中无任务完成数据', 'warning')
    return
  }

  const complete = resp.role.dailyTask.complete
  const isDone = (v) => v === -1

  log('开始同步任务完成状态...')
  log(`服务器返回的任务完成数据: ${JSON.stringify(complete)}`)

  let syncedCount = 0
  let completedCount = 0

  // 先重置所有任务为未完成，然后根据服务器数据更新
  tasks.value.forEach(task => {
    task.completed = false
  })

  // 同步服务器返回的完成状态
  Object.keys(complete).forEach(k => {
    const id = Number(k)
    const idx = tasks.value.findIndex(t => t.id === id)

    if (idx >= 0) {
      const isCompleted = isDone(complete[k])
      tasks.value[idx].completed = isCompleted
      syncedCount++

      if (isCompleted) {
        completedCount++
      }

      log(`任务${id} "${tasks.value[idx].name}": ${isCompleted ? '已完成' : '未完成'}`,
          isCompleted ? 'success' : 'info')
    } else {
      log(`服务器返回未知任务ID: ${id} (完成值: ${complete[k]})`, 'warning')
    }
  })



  log(`任务状态同步完成: ${completedCount}/${syncedCount} 已完成`)
  log(`当前进度: ${roleDailyPoint.value}/100`)
}

// 刷新角色信息
const refreshRoleInfo = async () => {
  if (!tokenStore.selectedToken) {
    throw new Error('没有选中的Token')
  }

  const tokenId = tokenStore.selectedToken.id
  log('正在获取角色信息...')

  try {
    const response = await tokenStore.sendGetRoleInfo(tokenId)
    log('角色信息获取成功', 'success')

    // 同步任务状态
    if (response) {
      syncCompleteFromServer(response)
    }

    return response
  } catch (error) {
    log(`获取角色信息失败: ${error.message}`, 'error')
    throw error
  }
}

// 执行单个游戏指令的封装
const executeGameCommand = async (tokenId, cmd, params = {}, description = '', timeout = 200) => {
  try {
    if (description) log(`执行: ${description}`)

    const result = await tokenStore.sendMessageWithPromise(tokenId, cmd, params, timeout)

    if (description) log(`${description} - 成功`, 'success')
    return result
  } catch (error) {
    if (description) log(`${description} - 失败: ${error.message}`, 'error')
    throw error
  }
}

// 检查是否今日可用（简化版本）
const isTodayAvailable = (statisticsTime) => {
  if (!statisticsTime) return true

  // 如果有时间戳，检查是否为今天
  const today = new Date().toDateString()
  const recordDate = new Date(statisticsTime).toDateString()

  return today !== recordDate
}

// 获取今日BOSS ID
const getTodayBossId = () => {
  const DAY_BOSS_MAP = [9904, 9905, 9901, 9902, 9903, 9904, 9905] // 周日~周六
  const dayOfWeek = new Date().getDay()
  return DAY_BOSS_MAP[dayOfWeek]
}

// 智能阵容切换辅助函数
const switchToFormationIfNeeded = async (tokenId, targetFormation, formationName, logFn) => {
  try {
    // 首先尝试从本地缓存获取当前阵容信息
    const cachedTeamInfo = tokenStore.gameData?.presetTeam?.presetTeamInfo
    let currentFormation = cachedTeamInfo?.useTeamId

    if (currentFormation) {
      logFn(`从缓存获取当前阵容: ${currentFormation}`)
    } else {
      // 缓存中没有数据，从服务器获取
      logFn(`缓存中无阵容信息，从服务器获取...`)
      const teamInfo = await executeGameCommand(tokenId, 'presetteam_getinfo', {}, '获取阵容信息')
      currentFormation = teamInfo?.presetTeamInfo?.useTeamId
      logFn(`从服务器获取当前阵容: ${currentFormation}`)
    }

    if (currentFormation === targetFormation) {
      logFn(`当前已是${formationName}${targetFormation}，无需切换`, 'success')
      return false // 不需要切换
    }

    logFn(`当前阵容: ${currentFormation}, 目标阵容: ${targetFormation}，开始切换...`)
    await executeGameCommand(tokenId, 'presetteam_saveteam',
      { teamId: targetFormation }, `切换到${formationName}${targetFormation}`)

    logFn(`成功切换到${formationName}${targetFormation}`, 'success')
    return true // 已切换
  } catch (error) {
    logFn(`阵容检查失败，直接切换: ${error.message}`, 'warning')
    // 如果检查失败，还是执行切换操作
    try {
      await executeGameCommand(tokenId, 'presetteam_saveteam',
        { teamId: targetFormation }, `强制切换到${formationName}${targetFormation}`)
      return true
    } catch (fallbackError) {
      logFn(`强制切换也失败: ${fallbackError.message}`, 'error')
      throw fallbackError
    }
  }
}

// 每日任务执行器
const executeDailyTasks = async (roleInfoResp, logFn, progressFn) => {
  const tokenId = tokenStore.selectedToken.id
  const roleData = roleInfoResp?.role

  if (!roleData) {
    throw new Error('角色数据不存在')
  }

  logFn('开始执行每日任务补差')

  // 不检查已完成的任务，所有任务都执行
  // const completedTasks = roleData.dailyTask?.complete ?? {}
  // const isTaskCompleted = (taskId) => completedTasks[taskId] === -1

  // 统计数据
  const statistics = roleData.statistics ?? {}
  const statisticsTime = roleData.statisticsTime ?? {}

  // 构建任务列表
  const taskList = []

  // 1. 基础任务（不再根据完成状态判断，全部执行）

  // 分享游戏 (任务ID: 2)
  taskList.push({
    name: '分享一次游戏',
    execute: () => executeGameCommand(tokenId, 'system_mysharecallback',
      { isSkipShareCard: true, type: 2 }, '分享游戏')
  })

  // 赠送好友金币 (任务ID: 3)
  taskList.push({
    name: '赠送好友金币',
    execute: () => executeGameCommand(tokenId, 'friend_batch', {}, '赠送好友金币')
  })

  // 招募 (任务ID: 4)
  taskList.push({
    name: '免费招募',
    execute: () => executeGameCommand(tokenId, 'hero_recruit',
      { recruitType: 3, recruitNumber: 1 }, '免费招募')
  })

  if (settings.payRecruit) {
    taskList.push({
      name: '付费招募',
      execute: () => executeGameCommand(tokenId, 'hero_recruit',
        { recruitType: 1, recruitNumber: 1 }, '付费招募')
    })
  }

  // 点金 (任务ID: 6)
  if (isTodayAvailable(statisticsTime['buy:gold'])) {
    for (let i = 0; i < 3; i++) {
      taskList.push({
        name: `免费点金 ${i + 1}/3`,
        execute: () => executeGameCommand(tokenId, 'system_buygold',
          { buyNum: 1 }, `免费点金 ${i + 1}`)
      })
    }
  }

  // 挂机奖励 (任务ID: 5)
  if (settings.claimHangUp) {
    // 先加钟4次
    for (let i = 0; i < 4; i++) {
      taskList.push({
        name: `挂机加钟 ${i + 1}/4`,
        execute: () => executeGameCommand(tokenId, 'system_mysharecallback',
          { isSkipShareCard: true, type: 2 }, `挂机加钟 ${i + 1}`)
      })
    }

    // 然后领取奖励
    taskList.push({
      name: '领取挂机奖励',
      execute: () => executeGameCommand(tokenId, 'system_claimhangupreward', {}, '领取挂机奖励')
    })

    // 最后再加1次钟
    taskList.push({
      name: '挂机加钟 5/5',
      execute: () => executeGameCommand(tokenId, 'system_mysharecallback',
        { isSkipShareCard: true, type: 2 }, '挂机加钟 5')
    })
  }

  // 开宝箱 (任务ID: 7)
  // 如果木制宝箱不够10个，则开青铜宝箱
  if (settings.openBox) {
    taskList.push({
      name: '开启宝箱',
      execute: async () => {
        try {
          // 先获取角色信息，检查宝箱数量
          logFn('检查宝箱数量...')
          const roleInfo = await tokenStore.sendMessageWithPromise(tokenId, 'role_getroleinfo', {}, 3000)
          const items = roleInfo?.role?.items || {}
          
          // 获取物品数量的通用函数（兼容数组和对象结构）
          const getItemCount = (items, id) => {
            if (!items) return 0
            // 数组结构：[{id/itemId, num/count/quantity}, ...]
            if (Array.isArray(items)) {
              const found = items.find((it) => Number(it.id ?? it.itemId) === id)
              if (!found) return 0
              return Number(found.num ?? found.count ?? found.quantity ?? 0)
            }
            // 对象结构：{ '2001': 3 } 或 { '2001': { num:3 } }
            const node = items[String(id)] ?? items[id]
            if (node == null) return 0
            if (typeof node === 'number') return node
            return Number(node.num ?? node.count ?? node.quantity ?? 0)
          }
          
          const woodenBoxCount = getItemCount(items, 2001) // 木制宝箱ID: 2001
          const bronzeBoxCount = getItemCount(items, 2002) // 青铜宝箱ID: 2002
          
          logFn(`📦 当前宝箱数量: 木制宝箱×${woodenBoxCount}, 青铜宝箱×${bronzeBoxCount}`)
          
          if (woodenBoxCount >= 10) {
            // 木制宝箱足够，开10个木制宝箱
            await executeGameCommand(tokenId, 'item_openbox',
              { itemId: 2001, number: 10 }, '开启木质宝箱×10')
            logFn('✅ 开启木质宝箱×10', 'success')
          } else if (bronzeBoxCount >= 10) {
            // 木制宝箱不够，但青铜宝箱够，开10个青铜宝箱
            await executeGameCommand(tokenId, 'item_openbox',
              { itemId: 2002, number: 10 }, '开启青铜宝箱×10')
            logFn('⚠️ 木制宝箱不足，改为开启青铜宝箱×10', 'warning')
          } else {
            // 两种宝箱都不够10个，尝试开启所有可用的宝箱
            if (woodenBoxCount > 0) {
              await executeGameCommand(tokenId, 'item_openbox',
                { itemId: 2001, number: woodenBoxCount }, `开启木质宝箱×${woodenBoxCount}`)
              logFn(`⚠️ 木制宝箱不足10个，开启现有的${woodenBoxCount}个`, 'warning')
            } else if (bronzeBoxCount > 0) {
              await executeGameCommand(tokenId, 'item_openbox',
                { itemId: 2002, number: bronzeBoxCount }, `开启青铜宝箱×${bronzeBoxCount}`)
              logFn(`⚠️ 木制宝箱不足，青铜宝箱也不足10个，开启现有的${bronzeBoxCount}个青铜宝箱`, 'warning')
            } else {
              // 没有任何宝箱可开
              logFn(`⚠️ 没有可用的宝箱（木制宝箱×${woodenBoxCount}, 青铜宝箱×${bronzeBoxCount}）`, 'warning')
            }
          }
        } catch (error) {
          logFn(`❌ 获取宝箱信息失败: ${error.message}，尝试开启默认木质宝箱`, 'error')
          // 失败时仍然尝试开10个木制宝箱（保持原有行为）
          await executeGameCommand(tokenId, 'item_openbox',
            { itemId: 2001, number: 10 }, '开启木质宝箱×10')
        }
      }
    })
  }

  // 盐罐 (任务ID: 14)
  if (settings.claimBottle) {
    taskList.push({
      name: '领取盐罐奖励',
      execute: () => executeGameCommand(tokenId, 'bottlehelper_claim', {}, '领取盐罐奖励')
    })
  }

  // 2. 竞技场 (任务ID: 13)
  if (settings.arenaEnable) {
    taskList.push({
      name: '竞技场战斗',
      execute: async () => {
        logFn('开始竞技场战斗流程')

        // 智能切换到竞技场阵容
        await switchToFormationIfNeeded(tokenId, settings.arenaFormation, '竞技场阵容', logFn)

        // 开始竞技场
        await executeGameCommand(tokenId, 'arena_startarea', {}, '开始竞技场')

        // 进行3场战斗
        for (let i = 1; i <= 3; i++) {
          logFn(`竞技场战斗 ${i}/3`)

          // 获取目标
          const targets = await executeGameCommand(tokenId, 'arena_getareatarget',
            { refresh: false }, `获取竞技场目标${i}`)

          const targetId = targets?.roleList?.[0]?.roleId
          if (targetId) {
            await executeGameCommand(tokenId, 'fight_startareaarena',
              { targetId }, `竞技场战斗${i}`, 10000)
          } else {
            logFn(`竞技场战斗${i} - 未找到目标`, 'warning')
          }

          // 战斗间隔
          await new Promise(resolve => setTimeout(resolve, 200))
        }
      }
    })
  }

  // 3. BOSS战斗
  if (settings.bossTimes > 0) {
    // 军团BOSS
    const alreadyLegionBoss = statistics['legion:boss'] ?? 0
    const remainingLegionBoss = Math.max(settings.bossTimes - alreadyLegionBoss, 0)

    if (remainingLegionBoss > 0) {
      // 为军团BOSS智能切换阵容
      taskList.push({
        name: '军团BOSS阵容检查',
        execute: () => switchToFormationIfNeeded(tokenId, settings.bossFormation, 'BOSS阵容', logFn)
      })

      for (let i = 0; i < remainingLegionBoss; i++) {
        taskList.push({
          name: `军团BOSS ${i + 1}/${remainingLegionBoss}`,
          execute: () => executeGameCommand(tokenId, 'fight_startlegionboss', {}, `军团BOSS ${i + 1}`, 200)
        })
      }
    }

    // 每日BOSS
    const todayBossId = getTodayBossId()
    if (remainingLegionBoss === 0) {
      // 如果没有军团BOSS，为每日BOSS切换阵容
      taskList.push({
        name: '每日BOSS阵容检查',
        execute: () => switchToFormationIfNeeded(tokenId, settings.bossFormation, 'BOSS阵容', logFn)
      })
    }

    for (let i = 0; i < 3; i++) {
      taskList.push({
        name: `每日BOSS ${i + 1}/3`,
        execute: () => executeGameCommand(tokenId, 'fight_startboss',
          { bossId: todayBossId }, `每日BOSS ${i + 1}`, 200)
      })
    }
  }

  // 4. 固定奖励领取
  const fixedRewards = [
    { name: '福利签到', cmd: 'system_signinreward' },
    { name: '俱乐部签到', cmd: 'legion_signin' },
    { name: '领取每日礼包', cmd: 'discount_claimreward' },
    { name: '领取免费礼包', cmd: 'card_claimreward' },
    { name: '领取永久卡礼包', cmd: 'card_claimreward', params: { cardId: 4003 } }
  ]

  if (settings.claimEmail) {
    fixedRewards.push({ name: '领取邮件奖励', cmd: 'mail_claimallattachment' })
  }

  fixedRewards.forEach(reward => {
    taskList.push({
      name: reward.name,
      execute: () => executeGameCommand(tokenId, reward.cmd, reward.params || {}, reward.name)
    })
  })

  // 5. 免费活动
  // 免费钓鱼
  if (isTodayAvailable(statisticsTime['artifact:normal:lottery:time'])) {
    for (let i = 0; i < 3; i++) {
      taskList.push({
        name: `免费钓鱼 ${i + 1}/3`,
        execute: () => executeGameCommand(tokenId, 'artifact_lottery',
          { lotteryNumber: 1, newFree: true, type: 1 }, `免费钓鱼 ${i + 1}`)
      })
    }
  }

  // 灯神免费扫荡
  const kingdoms = ['魏国', '蜀国', '吴国', '群雄']
  for (let gid = 1; gid <= 4; gid++) {
    if (isTodayAvailable(statisticsTime[`genie:daily:free:${gid}`])) {
      taskList.push({
        name: `${kingdoms[gid-1]}灯神免费扫荡`,
        execute: () => executeGameCommand(tokenId, 'genie_sweep',
          { genieId: gid }, `${kingdoms[gid-1]}灯神免费扫荡`)
      })
    }
  }

  // 灯神免费扫荡卷
  for (let i = 0; i < 3; i++) {
    taskList.push({
      name: `领取免费扫荡卷 ${i + 1}/3`,
      execute: () => executeGameCommand(tokenId, 'genie_buysweep', {}, `领取免费扫荡卷 ${i + 1}`)
    })
  }

  // 6. 黑市购买任务 (任务ID: 12)
  if (settings.blackMarketPurchase) {
    taskList.push({
      name: '黑市购买1次物品',
      execute: () => executeGameCommand(tokenId, 'store_purchase', { goodsId: 1 }, '黑市购买1次物品')
    })
  }

  // 7. 任务奖励领取
  for (let taskId = 1; taskId <= 10; taskId++) {
    taskList.push({
      name: `领取任务奖励${taskId}`,
      execute: () => executeGameCommand(tokenId, 'task_claimdailypoint',
        { taskId }, `领取任务奖励${taskId}`, 200)
    })
  }

  // 日常和周常奖励
  taskList.push(
    {
      name: '领取日常任务奖励',
      execute: () => executeGameCommand(tokenId, 'task_claimdailyreward', {}, '领取日常任务奖励')
    },
    {
      name: '领取周常任务奖励',
      execute: () => executeGameCommand(tokenId, 'task_claimweekreward', {}, '领取周常任务奖励')
    }
  )

  // 执行任务列表
  const totalTasks = taskList.length
  logFn(`共有 ${totalTasks} 个任务待执行`)

  for (let i = 0; i < taskList.length; i++) {
    const task = taskList[i]

    try {
      await task.execute()

      // 更新进度
      const progress = Math.floor(((i + 1) / totalTasks) * 100)
      if (progressFn) progressFn(tokenId, progress)

      // 任务间隔
      await new Promise(resolve => setTimeout(resolve, 200))

    } catch (error) {
      logFn(`任务执行失败: ${task.name} - ${error.message}`, 'error')
      // 继续执行下一个任务
    }
  }

  // 确保进度为100%
  if (progressFn) progressFn(tokenId, 100)
  logFn('所有任务执行完成', 'success')

  // 最后刷新一次角色信息
  await new Promise(resolve => setTimeout(resolve, 200))
  await refreshRoleInfo()
}

// 一键补差主函数
const runDailyFix = async () => {
  if (!tokenStore.selectedToken || busy.value) {
    message.warning('没有选中Token或正在执行中')
    return
  }

  if (!isConnected.value) {
    message.error('WebSocket连接未建立，请检查连接状态')
    return
  }

  busy.value = true
  showLog.value = true
  logList.value = []

  try {
    log('=== 开始执行一键补差任务 ===')


    // 1. 获取角色信息
    const roleInfo = await refreshRoleInfo()

    if (!roleInfo?.role) {
      throw new Error('获取角色信息失败或数据异常')
    }


    log(`当前每日任务进度: ${roleInfo.role.dailyTask?.dailyPoint || 0}/100`)

    // 2. 执行任务
    log('第二步: 开始执行每日任务...')
    await executeDailyTasks(roleInfo, log, (tokenId, progress) => {
      log(`任务进度: ${progress}%`)
    })

    log('=== 任务执行完成 ===', 'success')
    message.success('每日任务补差执行完成')

    // 3. 最终刷新角色信息
    setTimeout(async () => {
      try {
        await refreshRoleInfo()
        log('最终角色信息刷新完成', 'success')
      } catch (error) {
        log(`最终刷新失败: ${error.message}`, 'warning')
      }
    }, 200)

  } catch (error) {
    log(`任务执行失败: ${error.message}`, 'error')
    console.error('详细错误信息:', error)
    message.error(`任务执行失败: ${error.message}`)
  } finally {
    busy.value = false
  }
}

// 刷新任务状态
const handleRefreshTaskStatus = async () => {
  if (!isConnected.value) {
    message.warning('WebSocket未连接，无法刷新任务状态')
    return
  }

  try {
    log('手动刷新任务状态...')
    await refreshRoleInfo()
    message.success('任务状态刷新成功')
  } catch (error) {
    log(`刷新失败: ${error.message}`, 'error')
    message.error(`刷新失败: ${error.message}`)
  }
}

// 辅助函数
const getCurrentRole = () => {
  return tokenStore.selectedToken ? { roleId: tokenStore.selectedToken.id } : null
}

const loadSettings = (roleId) => {
  try {
    const raw = localStorage.getItem(`daily-settings:${roleId}`)
    return raw ? JSON.parse(raw) : null
  } catch (error) {
    console.error('Failed to load settings:', error)
    return null
  }
}

const saveSettings = (roleId, s) => {
  try {
    localStorage.setItem(`daily-settings:${roleId}`, JSON.stringify(s))
  } catch (error) {
    console.error('Failed to save settings:', error)
  }
}

// 监听设置变化
watch(settings, (cur) => {
  const role = getCurrentRole()
  if (role) saveSettings(role.roleId, cur)
}, { deep: true })

// 监听token选择变化
watch(() => tokenStore.selectedToken, async (newToken, oldToken) => {
  if (newToken && newToken !== oldToken) {
    log(`切换到Token: ${newToken.name}`)

    // 加载新token的设置
    const saved = loadSettings(newToken.id)
    if (saved) Object.assign(settings, saved)

    // 如果WebSocket已连接，尝试获取最新角色信息
    if (isConnected.value) {
      try {
        await refreshRoleInfo()
      } catch (error) {
        console.warn('切换token后获取角色信息失败:', error.message)
      }
    }
  }
}, { immediate: true })

// 监听角色信息变化，自动同步任务状态
watch(() => tokenStore.selectedTokenRoleInfo, (newRoleInfo) => {
  if (newRoleInfo?.role?.dailyTask?.complete) {
    log('角色信息更新，同步任务状态')
    syncCompleteFromServer(newRoleInfo)
  }
}, { immediate: true, deep: true })

// 生命周期
onMounted(async () => {
  log('组件初始化完成')

  // 首次拉取角色信息（如果有选中的token且已连接）
  if (tokenStore.selectedToken && isConnected.value) {
    try {
      await refreshRoleInfo()
    } catch (error) {
      console.warn('初始化时获取角色信息失败:', error.message)
    }
  }

  const role = getCurrentRole()
  if (role) {
    const saved = loadSettings(role.roleId)
    if (saved) Object.assign(settings, saved)
  }

  // 初始化时的任务状态同步会通过 watch selectedTokenRoleInfo 自动处理
})

onBeforeUnmount(() => {
  log('组件即将卸载')
})
</script>

<style scoped lang="scss">
.daily-task-container {
  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;
    }
  }
  
  // 添加主题色样式，与GameStatus组件保持一致
  .status-icon {
    background: linear-gradient(135deg, rgba(24, 160, 88, 0.15), rgba(54, 173, 106, 0.1));
    box-shadow: 0 4px 12px rgba(24, 160, 88, 0.2);
    
    &:hover {
      transform: scale(1.1);
      box-shadow: 0 8px 24px rgba(24, 160, 88, 0.3);
    }
  }
  
  .status-badge.completed {
    background: rgba(24, 160, 88, 0.15);
    color: #18a058;
    box-shadow: 0 0 12px rgba(24, 160, 88, 0.2);
  }
  
  .action-button {
    background: linear-gradient(135deg, #18a058, #36ad6a);
    box-shadow: 0 4px 12px rgba(24, 160, 88, 0.3);
    
    &:hover:not(:disabled) {
      background: linear-gradient(135deg, #16a058, #34bd6a);
      box-shadow: 0 6px 16px rgba(24, 160, 88, 0.4);
    }
    
    &.completed {
      background: var(--success-color);
      color: white;
      border: 1px solid rgba(34, 197, 94, 0.3);
      
      &:hover {
        background: var(--success-color);
        transform: none;
        cursor: default;
      }
      
      &:disabled {
        background: var(--success-color);
        color: white;
        opacity: 0.9;
      }
    }
  }
  
  // 确保在GameStatus容器中正确显示
  .game-status-container & {
    margin-bottom: 0;
  }
  
  // 添加与其他卡片相同的样式
  .card-content {
    .progress-container {
      margin-bottom: var(--spacing-md);
    }
    
    .info-container {
      color: var(--text-secondary);
      font-size: var(--font-size-sm);
      margin-bottom: var(--spacing-md);
      text-align: center;
    }
  }
}

.task-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: var(--spacing-lg);
}

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

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  margin-left: auto;
}

.icon-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-medium);
  background: var(--bg-primary);
  color: var(--text-secondary);
  cursor: pointer;
  transition: all var(--transition-fast);

  &:hover {
    background: var(--bg-tertiary);
    border-color: var(--primary-color);
    color: var(--primary-color);
    transform: translateY(-1px);
  }

  &:active {
    transform: translateY(0);
  }
}

.header-left {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
}

.task-icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
}

.status-icon {
  width: 32px;
  height: 32px;
  object-fit: contain;
  flex-shrink: 0;
  border-radius: var(--border-radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  background: linear-gradient(135deg, rgba(24, 160, 88, 0.15), rgba(54, 173, 106, 0.1));
  box-shadow: 0 4px 12px rgba(24, 160, 88, 0.2);
  transition: all 0.3s ease;
  
  &:hover {
    transform: scale(1.1);
    box-shadow: 0 8px 24px rgba(24, 160, 88, 0.3);
  }
}

.title-container {
  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-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;
  }
}

.header-right {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
}

.status-indicator {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: var(--spacing-xs) var(--spacing-sm);
  border-radius: var(--border-radius-full);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  cursor: pointer;
  font-size: var(--font-size-sm);
  transition: all var(--transition-fast);

  &:hover {
    background: var(--bg-secondary);
  }

  &.completed {
    background: rgba(16, 185, 129, 0.1);
    color: var(--success-color);
  }
}

.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);
  }

  &.weekly {
    background: rgba(59, 130, 246, 0.1);
    color: var(--info-color);
  }

  &.energy {
    background: rgba(245, 158, 11, 0.1);
    color: var(--warning-color);
  }

  &.completed {
    background: rgba(34, 197, 94, 0.15);
    color: var(--success-color);
    border: 1px solid rgba(34, 197, 94, 0.3);
  }
}

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

  &.completed {
    background: var(--success-color);
    box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.2);
  }
}

.settings-button {
  padding: var(--spacing-xs);
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  border-radius: var(--border-radius-medium);
  transition: background var(--transition-fast);

  &:hover {
    background: var(--bg-tertiary);
  }
}

.progress-container {
  margin-bottom: var(--spacing-md);
}

.info-container {
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  margin-bottom: var(--spacing-md);
  text-align: center;
}

.action-button {
  width: 100%;
  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;
  box-shadow: 0 4px 12px rgba(var(--primary-color-rgb, 24, 160, 88), 0.3);
  position: relative;
  overflow: hidden;
  
  &::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;
  }
  
  &:hover:not(:disabled) {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(var(--primary-color-rgb, 24, 160, 88), 0.4);
    
    &::before {
      left: 100%;
    }
  }
  
  &:active {
    transform: translateY(0);
    box-shadow: 0 2px 8px rgba(var(--primary-color-rgb, 24, 160, 88), 0.3);
  }
  
  &:disabled {
    background: var(--bg-tertiary);
    color: var(--text-tertiary);
    cursor: not-allowed;
    transform: none;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    
    &::before {
      display: none;
    }
  }

  &.secondary {
    background: var(--secondary-color);
    
    &:hover:not(:disabled) {
      background: var(--secondary-color-hover);
    }
  }

  &.active {
    background: var(--info-color);
    
    &:hover {
      background: var(--info-color-hover);
    }
  }

  &.completed {
    background: var(--success-color);
    color: white;
    border: 1px solid rgba(34, 197, 94, 0.3);
    
    &:hover {
      background: var(--success-color);
      transform: none;
      cursor: default;
    }
    
    &:disabled {
      background: var(--success-color);
      color: white;
      opacity: 0.9;
    }
  }
}

.loading-text {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-xs);
}

.loading-icon {
  width: 16px;
  height: 16px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

// 模态框样式
.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-sm);
  width: 100%;
}

.refresh-button {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  padding: var(--spacing-xs) var(--spacing-sm);
  border: 1px solid var(--border-light);
  border-radius: var(--border-radius-medium);
  background: var(--bg-primary);
  color: var(--text-secondary);
  font-size: var(--font-size-sm);
  cursor: pointer;
  transition: all var(--transition-fast);

  &:hover:not(:disabled) {
    background: var(--bg-tertiary);
    border-color: var(--primary-color);
    color: var(--primary-color);
  }

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
}

.settings-content {
  padding: var(--spacing-md) 0;
}

.settings-grid {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
}

.setting-item {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
}

.setting-label {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.setting-switches {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}

.switch-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--spacing-sm) 0;
  border-bottom: 1px solid var(--border-light);

  &:last-child {
    border-bottom: none;
  }
}

.switch-label {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.task-list {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
}

.task-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--spacing-sm) 0;
  border-bottom: 1px solid var(--border-light);

  &:last-child {
    border-bottom: none;
  }
}

.task-item-left {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.task-status-icon {
  width: 20px;
  height: 20px;
  color: var(--text-tertiary);

  &.completed {
    color: var(--success-color);
  }
}

.task-name {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.log-container {
  background: var(--bg-tertiary);
  border-radius: var(--border-radius-medium);
  padding: var(--spacing-md);
  max-height: 400px;
  overflow-y: auto;
}

.log-item {
  display: flex;
  gap: var(--spacing-sm);
  padding: var(--spacing-xs) 0;
  font-size: var(--font-size-sm);
}

.log-time {
  color: var(--text-tertiary);
  min-width: 80px;
  flex-shrink: 0;
}

.log-message {
  color: var(--text-secondary);

  &.error {
    color: var(--error-color);
  }

  &.success {
    color: var(--success-color);
  }

  &.warning {
    color: #f59e0b;
  }
}

// 响应式设计
@media (max-width: 768px) {
  .task-header {
    flex-direction: column;
    gap: var(--spacing-sm);
    text-align: center;
  }

  .header-right {
    justify-content: center;
  }
}
</style>
