;(() => {
  const root = global.cloudIslandBarnMission || {}
  const cfg = root.config || {}
  const pool = Array.isArray(root.pool) ? root.pool : []
  const rewardsByTask = root.rewardsByTask || {}

  const TASK_ID = String(cfg.rotationTaskId || '')
  if (!TASK_ID || TASK_ID === 'PUT_YOUR_BARN_ROTATION_TASK_ID_HERE') {
    console.info('[BarnMission] 未配置 rotationTaskId，跳过主控脚本。')
    return
  }

  if (!pool.length) {
    console.info('[BarnMission] 任务池为空，跳过主控脚本。')
    return
  }

  const SHOW_TARGET_COMMAND = String(cfg.showTargetCommand || 'barn_target').trim()
  const SUBMIT_COMMAND = String(cfg.submitCommand || 'barn_submit').trim()
  const COMPLETE_MESSAGE = String(cfg.completeMessage || '§a[谷仓日常] 任务完成！§r')
  const DEBUG = !!cfg.debug
  const DAILY_RESET_TIME = ((Math.floor(Number(cfg.dailyResetTime ?? 1000)) % 24000) + 24000) % 24000
  const CHECK_INTERVAL = Math.max(1, Number(cfg.checkIntervalTicks || 10))
  const NO_REPEAT = !!cfg.noRepeat

  const KEY = {
    activeKey: `barn_rot_active_${TASK_ID}`,
    round: `barn_rot_round_${TASK_ID}`,
    lastResetDay: `barn_rot_last_reset_day_${TASK_ID}`,
    completedLatched: `barn_rot_done_${TASK_ID}`,
    notified0Logic: `barn_rot_warn_logic_${TASK_ID}`,
  }

  function getPoolEntry(key) {
    const targetKey = String(key || '')
    return pool.find(t => String(t.key || '') === targetKey) || null
  }

  function resolveChecker(entry) {
    if (!entry || !entry.logicKey || typeof root.getLogic !== 'function') return null
    return root.getLogic(entry.logicKey)
  }

  function resolveSubmitter(entry) {
    if (!entry || !entry.logicKey || typeof root.getSubmit !== 'function') return null
    return root.getSubmit(entry.logicKey)
  }

  function randomEntry(lastKey) {
    if (pool.length <= 1 || !NO_REPEAT) return pool[Math.floor(Math.random() * pool.length)]
    const candidates = pool.filter(t => String(t.key || '') !== String(lastKey || ''))
    const arr = candidates.length ? candidates : pool
    return arr[Math.floor(Math.random() * arr.length)]
  }

  function assignNewTarget(player, server) {
    const data = player.persistentData
    const lastKey = String(data.getString(KEY.activeKey) || '')
    const next = randomEntry(lastKey)
    if (!next) return false

    data.putString(KEY.activeKey, String(next.key))
    data.putLong(KEY.round, data.getLong(KEY.round) + 1)
    data.putBoolean(KEY.completedLatched, false)
    data.putBoolean(KEY.notified0Logic, false)

    server.runCommandSilent(`ftbquests change_progress ${player.username} reset ${TASK_ID}`)
    return true
  }

  function announceCurrentTarget(player) {
    const entry = getPoolEntry(player.persistentData.getString(KEY.activeKey))
    if (!entry) return

    const name = String(entry.name || entry.key || '未命名目标')
    const content = String(entry.content || '无')
    player.tell(`§6[谷仓日常] 当前目标：§e${name}§r`)
    player.tell(`§7内容：§f${content}§r`)
  }

  function runRewardCommand(server, player, commandText) {
    if (!commandText) return
    const cmd = String(commandText).replace(/\{player\}/g, player.username)
    server.runCommandSilent(cmd)
  }

  function randInt(min, max) {
    const lo = Math.floor(Number(min))
    const hi = Math.floor(Number(max))
    if (!isFinite(lo) || !isFinite(hi)) return 1
    if (hi < lo) return lo
    return lo + Math.floor(Math.random() * (hi - lo + 1))
  }

  function grantRewards(player, server, entry) {
    if (!entry || !entry.key) return
    const list = rewardsByTask[String(entry.key)]
    if (!Array.isArray(list) || !list.length) return

    for (const rw of list) {
      if (!rw) continue
      const type = String(rw.type || '').toLowerCase()

      if (type === 'item') {
        const id = String(rw.id || '')
        const hasRange = rw.countMin !== undefined || rw.countMax !== undefined
        const count = hasRange
          ? Math.max(1, randInt(rw.countMin ?? rw.count ?? 1, rw.countMax ?? rw.count ?? 1))
          : Math.max(1, Math.floor(Number(rw.count || 1)))
        if (!id) continue
        runRewardCommand(server, player, `give ${player.username} ${id} ${count}`)
        continue
      }

      if (type === 'xp') {
        const points = Number(rw.points || 0)
        const levels = Number(rw.levels || 0)
        if (isFinite(points) && points > 0) {
          runRewardCommand(server, player, `xp add ${player.username} ${Math.floor(points)} points`)
        }
        if (isFinite(levels) && levels > 0) {
          runRewardCommand(server, player, `xp add ${player.username} ${Math.floor(levels)} levels`)
        }
        continue
      }

      if (type === 'command') {
        runRewardCommand(server, player, rw.command)
      }
    }
  }

  function getLevelDayTime(player) {
    const lv = player.level
    if (!lv) return -1
    try {
      if (typeof lv.getDayTime === 'function') return Number(lv.getDayTime())
    } catch (e) {}
    try {
      if (typeof lv.dayTime === 'function') return Number(lv.dayTime())
      if (lv.dayTime !== undefined && lv.dayTime !== null) return Number(lv.dayTime)
    } catch (e) {}
    try {
      if (typeof lv.getTimeOfDay === 'function') return Number(lv.getTimeOfDay(1))
    } catch (e) {}
    return -1
  }

  FTBQuestsEvents.customTask(TASK_ID, event => {
    event.maxProgress = 1

    event.setCheck((task, player) => {
      const server = player.server
      if (!server) {
        task.progress = 0
        return
      }

      const data = player.persistentData
      let entry = getPoolEntry(data.getString(KEY.activeKey))
      if (!entry) {
        assignNewTarget(player, server)
        entry = getPoolEntry(data.getString(KEY.activeKey))
        if (!entry) {
          task.progress = 0
          return
        }
      }

      const checker = resolveChecker(entry)
      if (typeof checker !== 'function') {
        task.progress = 0
        if (!data.getBoolean(KEY.notified0Logic)) {
          data.putBoolean(KEY.notified0Logic, true)
          player.tell(`§c[谷仓日常] 目标逻辑未注册：${entry.logicKey}§r`)
        }
        return
      }

      let ok = false
      try {
        ok = !!checker(player)
      } catch (e) {
        ok = false
      }

      if (!ok) {
        task.progress = 0
        return
      }

      task.progress = 1
      if (!data.getBoolean(KEY.completedLatched)) {
        data.putBoolean(KEY.completedLatched, true)
        grantRewards(player, server, entry)
        player.tell(COMPLETE_MESSAGE)
      }
    })
  })

  if (SHOW_TARGET_COMMAND || SUBMIT_COMMAND) {
    ServerEvents.commandRegistry(event => {
      const { commands: Commands } = event
      if (SHOW_TARGET_COMMAND) {
        event.register(
          Commands.literal(SHOW_TARGET_COMMAND).executes(ctx => {
            const player = ctx.source.playerOrException
            const server = player.server
            if (!server) return 0

            let active = getPoolEntry(player.persistentData.getString(KEY.activeKey))
            if (!active) {
              assignNewTarget(player, server)
              active = getPoolEntry(player.persistentData.getString(KEY.activeKey))
            }

            if (!active) {
              player.tell('§c[谷仓日常] 当前没有可用目标。§r')
              return 0
            }

            announceCurrentTarget(player)
            return 1
          })
        )
      }

      if (SUBMIT_COMMAND) {
        event.register(
          Commands.literal(SUBMIT_COMMAND).executes(ctx => {
            const player = ctx.source.playerOrException
            const server = player.server
            if (!server) return 0

            let active = getPoolEntry(player.persistentData.getString(KEY.activeKey))
            if (!active) {
              assignNewTarget(player, server)
              active = getPoolEntry(player.persistentData.getString(KEY.activeKey))
            }
            if (!active) {
              player.tell('§c[谷仓日常] 当前没有可用目标。§r')
              return 0
            }

            const submitter = resolveSubmitter(active)
            if (typeof submitter !== 'function') {
              player.tell('§e[谷仓日常] 当前目标不是提交类任务，无需提交。§r')
              return 0
            }
            if (DEBUG) {
              player.tell(`§8[BarnDebug] active=${active.key}, logic=${active.logicKey}§r`)
            }

            let result = 'failed'
            let submitRaw = null
            try {
              submitRaw = submitter(player)
              if (DEBUG) player.tell(`§8[BarnDebug] submit raw=${submitRaw}§r`)
              if (submitRaw === 'submitted' || submitRaw === 'failed') {
                result = submitRaw
              } else {
                result = submitRaw ? 'submitted' : 'failed'
              }
            } catch (e) {
              if (DEBUG) player.tell(`§8[BarnDebug] submit exception=${e}§r`)
              result = 'failed'
            }

            if (DEBUG) player.tell(`§8[BarnDebug] submit result=${result}§r`)
            if (result !== 'submitted') {
              player.tell('§c[谷仓日常] 提交失败：请检查物品数量是否满足要求或今日任务已完成。§r')
              return 0
            }

            player.tell('§a[谷仓日常] 提交成功。§r')
            return 1
          })
        )
      }
    })
  }

  PlayerEvents.tick(event => {
    const player = event.player
    if (player.level.isClientSide()) return

    const server = player.server
    if (!server) return
    if (server.tickCount % CHECK_INTERVAL !== 0) return

    const data = player.persistentData
    const active = getPoolEntry(data.getString(KEY.activeKey))
    if (!active) {
      assignNewTarget(player, server)
      return
    }

    const dayTime = getLevelDayTime(player)
    if (!isFinite(dayTime) || dayTime < 0) return

    const day = Math.floor(dayTime / 24000)
    const tod = ((Math.floor(dayTime) % 24000) + 24000) % 24000
    const lastResetDay = data.getLong(KEY.lastResetDay)

    // 每天到达早晨时间后，且当天尚未重置，就强制刷新目标并重置任务
    if (tod >= DAILY_RESET_TIME && lastResetDay !== day) {
      assignNewTarget(player, server)
      data.putLong(KEY.lastResetDay, day)
    }
  })
})()
