import { buildClaimUrl, createTaskClaimToken } from '../claim/claim-service.js'
import { maskCode as maskCodeValue, maskPhone as maskPhoneValue } from '../../utils/masking.js'

import type { TaskRow } from '../../types/repository/rows.js'

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 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()
}
