export const TASK_STATUS = {
  PENDING_PAYMENT: 'pending_payment',
  PAID: 'paid',
  LINK_GENERATED: 'link_generated',
  CLAIMED: 'claimed',
  PENDING_BINDING_PREPARE: 'pending_binding_prepare',
  WAITING_BINDING: 'waiting_binding',
  ROLE_CONFIRMED: 'role_confirmed',
  REDEEMING: 'redeeming',
  DISPATCHED_PENDING_RETURN: 'dispatched_pending_return',
  COMPLETED: 'completed',
  REDEEMED: 'redeemed',
  RETRY_PENDING: 'retry_pending',
  MANUAL_REVIEW: 'manual_review',
  FAILED: 'failed',
  EXPIRED: 'expired',
  CLOSED: 'closed',
} as const

export type KnownTaskStatus = (typeof TASK_STATUS)[keyof typeof TASK_STATUS]
export type TaskStatus = KnownTaskStatus | (string & {})

const TASK_TRANSITIONS: Record<KnownTaskStatus, readonly KnownTaskStatus[]> = {
  [TASK_STATUS.PENDING_PAYMENT]: [
    TASK_STATUS.PAID,
    TASK_STATUS.PENDING_BINDING_PREPARE,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.PAID]: [
    TASK_STATUS.LINK_GENERATED,
    TASK_STATUS.PENDING_BINDING_PREPARE,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.LINK_GENERATED]: [
    TASK_STATUS.CLAIMED,
    TASK_STATUS.WAITING_BINDING,
    TASK_STATUS.ROLE_CONFIRMED,
    TASK_STATUS.RETRY_PENDING,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.EXPIRED,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.CLAIMED]: [
    TASK_STATUS.WAITING_BINDING,
    TASK_STATUS.ROLE_CONFIRMED,
    TASK_STATUS.RETRY_PENDING,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.EXPIRED,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.PENDING_BINDING_PREPARE]: [
    TASK_STATUS.WAITING_BINDING,
    TASK_STATUS.RETRY_PENDING,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.EXPIRED,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.WAITING_BINDING]: [
    TASK_STATUS.ROLE_CONFIRMED,
    TASK_STATUS.REDEEMING,
    TASK_STATUS.RETRY_PENDING,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.EXPIRED,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.ROLE_CONFIRMED]: [
    TASK_STATUS.WAITING_BINDING,
    TASK_STATUS.REDEEMING,
    TASK_STATUS.RETRY_PENDING,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.EXPIRED,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.REDEEMING]: [
    TASK_STATUS.DISPATCHED_PENDING_RETURN,
    TASK_STATUS.COMPLETED,
    TASK_STATUS.REDEEMED,
    TASK_STATUS.RETRY_PENDING,
    TASK_STATUS.MANUAL_REVIEW,
  ],
  [TASK_STATUS.DISPATCHED_PENDING_RETURN]: [
    TASK_STATUS.COMPLETED,
    TASK_STATUS.REDEEMED,
    TASK_STATUS.MANUAL_REVIEW,
  ],
  [TASK_STATUS.RETRY_PENDING]: [
    TASK_STATUS.PENDING_BINDING_PREPARE,
    TASK_STATUS.WAITING_BINDING,
    TASK_STATUS.ROLE_CONFIRMED,
    TASK_STATUS.REDEEMING,
    TASK_STATUS.MANUAL_REVIEW,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.MANUAL_REVIEW]: [
    TASK_STATUS.PENDING_BINDING_PREPARE,
    TASK_STATUS.WAITING_BINDING,
    TASK_STATUS.ROLE_CONFIRMED,
    TASK_STATUS.REDEEMING,
    TASK_STATUS.DISPATCHED_PENDING_RETURN,
    TASK_STATUS.COMPLETED,
    TASK_STATUS.REDEEMED,
    TASK_STATUS.CLOSED,
  ],
  [TASK_STATUS.FAILED]: [TASK_STATUS.RETRY_PENDING, TASK_STATUS.MANUAL_REVIEW, TASK_STATUS.CLOSED],
  [TASK_STATUS.COMPLETED]: [],
  [TASK_STATUS.REDEEMED]: [],
  [TASK_STATUS.EXPIRED]: [],
  [TASK_STATUS.CLOSED]: [],
}

const FINAL_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.COMPLETED,
  TASK_STATUS.REDEEMED,
  TASK_STATUS.EXPIRED,
  TASK_STATUS.CLOSED,
])

const OPEN_91_FAILED_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.FAILED,
  TASK_STATUS.MANUAL_REVIEW,
  TASK_STATUS.CLOSED,
])

const CLAIM_INACTIVE_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.COMPLETED,
  TASK_STATUS.REDEEMED,
  TASK_STATUS.MANUAL_REVIEW,
  TASK_STATUS.FAILED,
  TASK_STATUS.EXPIRED,
  TASK_STATUS.CLOSED,
])

const PAID_PREPARATION_STABLE_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.LINK_GENERATED,
  TASK_STATUS.CLAIMED,
  TASK_STATUS.ROLE_CONFIRMED,
  TASK_STATUS.REDEEMING,
  TASK_STATUS.DISPATCHED_PENDING_RETURN,
  TASK_STATUS.COMPLETED,
  TASK_STATUS.REDEEMED,
  TASK_STATUS.EXPIRED,
  TASK_STATUS.CLOSED,
])

const KUAISHOU_CLOUD_CLAIM_LINK_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.PENDING_BINDING_PREPARE,
  TASK_STATUS.WAITING_BINDING,
  TASK_STATUS.DISPATCHED_PENDING_RETURN,
  TASK_STATUS.COMPLETED,
  TASK_STATUS.MANUAL_REVIEW,
  TASK_STATUS.FAILED,
])

const KUAISHOU_CLOUD_ROLE_CONFIRM_SETTLED_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.ROLE_CONFIRMED,
  TASK_STATUS.REDEEMING,
  TASK_STATUS.DISPATCHED_PENDING_RETURN,
  TASK_STATUS.COMPLETED,
  TASK_STATUS.REDEEMED,
  TASK_STATUS.MANUAL_REVIEW,
])

const KUAISHOU_CLOUD_REDEEM_SETTLED_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.REDEEMING,
  TASK_STATUS.DISPATCHED_PENDING_RETURN,
  TASK_STATUS.COMPLETED,
  TASK_STATUS.REDEEMED,
  TASK_STATUS.MANUAL_REVIEW,
])

const CLAIM_LINK_REGENERATABLE_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.LINK_GENERATED,
  TASK_STATUS.CLAIMED,
  TASK_STATUS.ROLE_CONFIRMED,
  TASK_STATUS.RETRY_PENDING,
  TASK_STATUS.MANUAL_REVIEW,
])

const KUAISHOU_CLOUD_RESULT_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.DISPATCHED_PENDING_RETURN,
  TASK_STATUS.COMPLETED,
  TASK_STATUS.REDEEMED,
  TASK_STATUS.MANUAL_REVIEW,
  TASK_STATUS.FAILED,
])

const FULFILLMENT_COMPLETED_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.DISPATCHED_PENDING_RETURN,
  TASK_STATUS.COMPLETED,
  TASK_STATUS.REDEEMED,
])

const RETRYABLE_TASK_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.RETRY_PENDING,
  TASK_STATUS.MANUAL_REVIEW,
])

const KUAISHOU_CLOUD_PREPARABLE_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.PENDING_BINDING_PREPARE,
  TASK_STATUS.MANUAL_REVIEW,
  TASK_STATUS.FAILED,
])

const KUAISHOU_CLOUD_REBINDABLE_STATUSES = new Set<TaskStatus>([
  TASK_STATUS.WAITING_BINDING,
  TASK_STATUS.ROLE_CONFIRMED,
  TASK_STATUS.MANUAL_REVIEW,
  TASK_STATUS.RETRY_PENDING,
])

export function normalizeTaskStatus(value: unknown): TaskStatus {
  return String(value || '').trim() as TaskStatus
}

export function canTaskTransition(from: unknown, to: unknown): boolean {
  const current = normalizeTaskStatus(from) as KnownTaskStatus
  const next = normalizeTaskStatus(to) as KnownTaskStatus
  if (!current || !next || current === next) {
    return Boolean(current && next)
  }

  return Boolean(TASK_TRANSITIONS[current]?.includes(next))
}

export function getTaskNextStatuses(status: unknown): readonly KnownTaskStatus[] {
  return TASK_TRANSITIONS[normalizeTaskStatus(status) as KnownTaskStatus] || []
}

export function isTaskFinalStatus(status: unknown): boolean {
  return FINAL_STATUSES.has(normalizeTaskStatus(status))
}

export function isOpen91FailedTaskStatus(status: unknown): boolean {
  return OPEN_91_FAILED_STATUSES.has(normalizeTaskStatus(status))
}

export function isClaimInactiveTaskStatus(status: unknown): boolean {
  return CLAIM_INACTIVE_STATUSES.has(normalizeTaskStatus(status))
}

export function isPaidPreparationStableStatus(status: unknown): boolean {
  return PAID_PREPARATION_STABLE_STATUSES.has(normalizeTaskStatus(status))
}

export function shouldEnsureKuaishouCloudClaimLink(status: unknown): boolean {
  return KUAISHOU_CLOUD_CLAIM_LINK_STATUSES.has(normalizeTaskStatus(status))
}

export function isKuaishouCloudRoleConfirmSettledStatus(status: unknown): boolean {
  return KUAISHOU_CLOUD_ROLE_CONFIRM_SETTLED_STATUSES.has(normalizeTaskStatus(status))
}

export function isKuaishouCloudRedeemSettledStatus(status: unknown): boolean {
  return KUAISHOU_CLOUD_REDEEM_SETTLED_STATUSES.has(normalizeTaskStatus(status))
}

export function canRedeemKuaishouCloudClaimStatus(status: unknown): boolean {
  const normalized = normalizeTaskStatus(status)
  // 允许 WAITING_BINDING：UID 匹配后可一键确认+兑换
  return normalized === TASK_STATUS.ROLE_CONFIRMED || normalized === TASK_STATUS.WAITING_BINDING
}

export function canRegenerateClaimLinkStatus(status: unknown): boolean {
  return CLAIM_LINK_REGENERATABLE_STATUSES.has(normalizeTaskStatus(status))
}

export function hasKuaishouCloudRedeemResultStatus(status: unknown): boolean {
  return KUAISHOU_CLOUD_RESULT_STATUSES.has(normalizeTaskStatus(status))
}

export function isTaskFulfillmentCompletedStatus(status: unknown): boolean {
  return FULFILLMENT_COMPLETED_STATUSES.has(normalizeTaskStatus(status))
}

export function canRetryTaskStatus(status: unknown): boolean {
  return RETRYABLE_TASK_STATUSES.has(normalizeTaskStatus(status))
}

export function canMarkManualReviewTaskStatus(status: unknown): boolean {
  const normalized = normalizeTaskStatus(status)
  return normalized !== TASK_STATUS.MANUAL_REVIEW && !isTaskFinalStatus(normalized)
}

export function canCompleteManualDispatchTaskStatus(status: unknown): boolean {
  return !isTaskFinalStatus(status)
}

export function canPrepareKuaishouCloudFulfillmentStatus(status: unknown): boolean {
  return KUAISHOU_CLOUD_PREPARABLE_STATUSES.has(normalizeTaskStatus(status))
}

export function canRebindKuaishouCloudRoleStatus(status: unknown): boolean {
  return KUAISHOU_CLOUD_REBINDABLE_STATUSES.has(normalizeTaskStatus(status))
}

export function canDispatchKuaishouCloudFulfillmentStatus(status: unknown): boolean {
  return normalizeTaskStatus(status) === TASK_STATUS.WAITING_BINDING
}

export function canReturnKuaishouCloudFulfillmentStatus(status: unknown): boolean {
  return normalizeTaskStatus(status) === TASK_STATUS.DISPATCHED_PENDING_RETURN
}

export function resolveInitialPaidTaskStatus(
  profile:
    | {
        requires_claim?: boolean
        executor_key?: unknown
      }
    | null
    | undefined,
): TaskStatus {
  if (profile?.requires_claim) {
    return TASK_STATUS.PAID
  }

  if (String(profile?.executor_key || '').trim() === 'kuaishou_ct_assisted') {
    return TASK_STATUS.PENDING_BINDING_PREPARE
  }

  if (String(profile?.executor_key || '').trim() === 'manual_dispatch') {
    return TASK_STATUS.MANUAL_REVIEW
  }

  return TASK_STATUS.PAID
}
