import { buildClaimUrl, createTaskClaimToken } from '../../claim/claim-service.js'
import { createHttpError } from '../../../utils/http.js'
import {
  maskCode as maskCodeValue,
  maskPhone as maskPhoneValue,
} from '../../../utils/masking.js'
import {
  canViewerConfirmAssistedRole,
  canViewerRedeemAssistedTask,
  isAssistedClaimTask,
  parseTaskContext,
} from '../admin-read-shared-helpers.js'

import type { AdminViewerContext } from '../admin-read-shared-helpers.js'
import type { TaskRow } from '../../../types/repository-rows.js'

type AssistedTaskAction = 'confirm' | 'redeem'

type TaskClaimLink = {
  token: string
  expiredAt: string | null
  claimUrl: string
}

type ErrorLike = {
  errorCode?: string
  code?: string
}

export function maskPhone(value: unknown): string {
  return maskPhoneValue(value)
}

export function maskCode(value: unknown): string {
  return maskCodeValue(value)
}

export function resolveTaskInventoryGroupCodes(task: TaskRow): string[] | null {
  const taskContext = parseTaskContext(task)
  const inventoryGroupCode = String(taskContext?.inventoryGroupCode || '').trim()
  return inventoryGroupCode ? [inventoryGroupCode] : null
}

export function ensureViewerCanOperateAssistedTask(
  task: TaskRow,
  viewerContext: AdminViewerContext,
  action: AssistedTaskAction,
): void {
  if (!viewerContext.canOperateAssistedTask || !isAssistedClaimTask(task)) {
    throw createHttpError('当前账号没有此操作权限', {
      statusCode: 403,
      errorCode: 'admin_task_assisted_permission_denied',
    })
  }

  if (action === 'confirm' && !canViewerConfirmAssistedRole(task, viewerContext)) {
    throw createHttpError('当前任务状态还不能确认角色', {
      statusCode: 409,
      errorCode: 'admin_task_assisted_confirm_not_allowed',
    })
  }

  if (action === 'redeem' && !canViewerRedeemAssistedTask(task, viewerContext)) {
    throw createHttpError('当前任务状态还不能开始兑换', {
      statusCode: 409,
      errorCode: 'admin_task_assisted_redeem_not_allowed',
    })
  }
}

export function isRecoverableTaskSessionCloseError(error: ErrorLike | null | undefined): boolean {
  const errorCode = String(error?.errorCode || error?.code || '').trim()
  return errorCode === 'session_not_found' || errorCode === 'session_closed'
}

export function normalizeManualDispatchOutcome(value: unknown): 'delivered' | 'failed' {
  const normalized = String(value || '').trim().toLowerCase()

  if (normalized === 'failed') {
    return 'failed'
  }

  return 'delivered'
}

export function getTaskClaimExpiresAt(task: Partial<TaskRow> | null | undefined): string | null {
  return task?.claim_expires_at || task?.primary_claim_expires_at || null
}

export async function ensureTaskClaimLink(task: TaskRow): Promise<TaskClaimLink> {
  const tokenStatus = String(task?.primary_claim_token_status || '').trim()
  const token = String(task?.primary_claim_token || task?.claim_token || '').trim()
  const expiredAt = getTaskClaimExpiresAt(task)

  if (tokenStatus === 'active' && token && !isClaimExpired(expiredAt)) {
    return {
      token,
      expiredAt,
      claimUrl: buildClaimUrl(token),
    }
  }

  const claimToken = await createTaskClaimToken(task.id)
  return {
    token: claimToken.token,
    expiredAt: claimToken.expired_at,
    claimUrl: claimToken.claimUrl,
  }
}

function isClaimExpired(expiredAt: string | null): boolean {
  if (!expiredAt) {
    return false
  }

  const timestamp = new Date(expiredAt).getTime()
  return Number.isFinite(timestamp) && timestamp <= Date.now()
}
