import { isClaimInactiveTaskStatus } from '@/domain/task-status'
import type { ClaimSnapshot } from './claim-snapshot'

/** 绑链准备中：略放缓，减少空转 */
export const BINDING_PREPARE_POLL_MS = 8_000
/** 角色快轮询：原 10s → 25s，降低 bind_info 压力 */
export const ROLE_FAST_POLL_MS = 25_000
export const ROLE_SLOW_POLL_MS = 45_000
export const ROLE_IDLE_POLL_MS = 90_000
/** 快轮询窗口：原 3 分钟 → 2 分钟 */
export const ROLE_FAST_WINDOW_MS = 2 * 60_000
export const ROLE_IDLE_WINDOW_MS = 10 * 60_000
export const FEIFEI_POLL_MS = 20_000

export function resolveRolePollDelayMs(
  nextSnapshot: ClaimSnapshot,
  baseline: { roleKey: string; at: number },
  now = Date.now(),
) {
  const nextRoleKey = [nextSnapshot.roleName, nextSnapshot.roleId].join('::')
  let baselineAt = baseline.at
  let baselineKey = baseline.roleKey

  if (nextRoleKey !== baselineKey) {
    baselineKey = nextRoleKey
    baselineAt = now
  }

  if (!baselineAt) {
    baselineAt = now
  }

  const elapsedMs = now - baselineAt
  let delay = ROLE_IDLE_POLL_MS
  if (elapsedMs < ROLE_FAST_WINDOW_MS) {
    delay = ROLE_FAST_POLL_MS
  } else if (elapsedMs < ROLE_IDLE_WINDOW_MS) {
    delay = ROLE_SLOW_POLL_MS
  }

  // 已拿到角色但未匹配：不必高频刷，稍放缓即可
  if (nextSnapshot.roleId && !nextSnapshot.isUidMatched) {
    delay = Math.max(delay, ROLE_SLOW_POLL_MS)
  }

  return {
    delay,
    baseline: { roleKey: baselineKey, at: baselineAt },
  }
}

export function resolveNextPollDelayMs(
  nextSnapshot: ClaimSnapshot,
  rolePollDelayMs: number,
): number {
  if (nextSnapshot.hasRedeemResult || isClaimInactiveTaskStatus(nextSnapshot.task?.status)) {
    return 0
  }

  if (!nextSnapshot.hasExpectedUid) {
    return 0
  }

  if (nextSnapshot.isFeifeiFlow) {
    return FEIFEI_POLL_MS
  }

  if (nextSnapshot.isAffiliateDashFlow) {
    if (!nextSnapshot.isAffiliateDashReadyToSubmit) {
      return BINDING_PREPARE_POLL_MS
    }
    return FEIFEI_POLL_MS
  }

  if (nextSnapshot.currentStep === 2) {
    if (!nextSnapshot.isBindingPrepared) {
      return BINDING_PREPARE_POLL_MS
    }
    return rolePollDelayMs
  }

  return 0
}
