type ReservationTranslator = (key: string, fallback?: string) => string

export interface ReservationTaskRouteLike {
  task_type?: string | null
  system_task_type?: string | null
  task_card_type?: string | null
  card_name?: string | null
  task_subtype?: string | null
  result_type?: string | null
  ai_task_type?: string | null
  route_code?: string | null
  system_process_category?: string | null
}

export function formatReservationTaskCard(
  t: ReservationTranslator,
  taskType: string | null | undefined,
  fallbackLabel?: string | null,
): string {
  return translateStableCode(t, 'cardType', taskType, 'common.unknownTaskType', fallbackLabel)
}

export function formatReservationTaskCardLabel(
  t: ReservationTranslator,
  input: ReservationTaskRouteLike,
  fallbackLabel?: string | null,
): string {
  if (isReservationAdapterContractErrorTask(input)) {
    return t('resultType.ADAPTER_CONTRACT_ERROR')
  }
  if (isReservationUnhandledIntentTask(input)) {
    return t('resultType.UNHANDLED_CURRENT_INTENT')
  }
  if (isReservationParentGroupCancelAllotmentTask(input)) {
    return formatReservationTaskCard(t, 'CANCEL_ALLOTMENT')
  }
  return formatReservationTaskCard(
    t,
    input.task_card_type ?? input.task_type ?? input.system_task_type,
    fallbackLabel ?? input.card_name,
  )
}

export function formatReservationTaskTypeSummary(
  t: ReservationTranslator,
  taskType: string | null | undefined,
  taskSubtype: string | null | undefined,
): string {
  const typeLabel = formatReservationTaskCard(t, taskType)
  const normalizedType = normalizeStableCode(taskType)
  const normalizedSubtype = normalizeStableCode(taskSubtype)
  if (!normalizedSubtype || normalizedSubtype === normalizedType) {
    return typeLabel
  }
  return `${typeLabel} / ${translateStableCode(t, 'taskSubtype', taskSubtype, 'common.unknownTaskSubtype')}`
}

export function isReservationSourceMessageOnlyTask(...codes: Array<string | null | undefined>): boolean {
  return codes.some((code) => normalizeStableCode(code) === 'SOURCE_MESSAGE_ONLY')
}

export function isReservationSourceMessageNotificationTask(input: ReservationTaskRouteLike | null | undefined): boolean {
  if (!input) {
    return false
  }
  const subtype = normalizeStableCode(input.task_subtype)
  const routeCode = normalizeStableCode(input.route_code)
  if (
    normalizeStableCode(input.result_type) === 'SOURCE_MESSAGE_REVIEW_NOTIFICATION' ||
    normalizeStableCode(input.system_process_category) === 'SOURCE_MESSAGE_NOTIFICATION' ||
    isReservationSourceMessageOnlyTask(input.task_type, input.system_task_type, input.task_card_type)
  ) {
    return true
  }

  const hasSourceMessageRouteCode = ['S10', 'S99', 'S000', 'S999'].includes(subtype) ||
    ['S10', 'S99', 'S000', 'S999'].includes(routeCode)
  const hasSourceMessageTaskContext = [
    input.task_type,
    input.system_task_type,
    input.task_card_type,
    input.ai_task_type,
  ].some((code) =>
    ['SOURCE_MESSAGE_ONLY', 'MESSAGE_NOTIFICATION', 'INFORMATIONAL_MESSAGE'].includes(normalizeStableCode(code)),
  )
  return hasSourceMessageRouteCode && hasSourceMessageTaskContext
}

export function isReservationAdapterContractErrorTask(input: ReservationTaskRouteLike | null | undefined): boolean {
  return (
    normalizeStableCode(input?.result_type) === 'ADAPTER_CONTRACT_ERROR' ||
    normalizeStableCode(input?.system_process_category) === 'ADAPTER_CONTRACT_ERROR'
  )
}

export function isReservationUnhandledIntentTask(input: ReservationTaskRouteLike | null | undefined): boolean {
  return (
    normalizeStableCode(input?.result_type) === 'UNHANDLED_CURRENT_INTENT' ||
    normalizeStableCode(input?.system_process_category) === 'UNHANDLED_CURRENT_INTENT'
  )
}

export function isReservationReadonlyDiagnosticTask(input: ReservationTaskRouteLike | null | undefined): boolean {
  return (
    isReservationSourceMessageNotificationTask(input) ||
    isReservationAdapterContractErrorTask(input) ||
    isReservationUnhandledIntentTask(input)
  )
}

export function isReservationParentGroupCancelAllotmentTask(input: ReservationTaskRouteLike | null | undefined): boolean {
  const routeCode = normalizeStableCode(input?.route_code)
  const taskSubtype = normalizeStableCode(input?.task_subtype)
  const taskCardType = normalizeStableCode(input?.task_card_type ?? input?.card_name)
  return (
    routeCode === 'R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL' ||
    routeCode === 'R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_REVIEW' ||
    taskSubtype === 'CANCEL_ALLOTMENT_CONTROL_BLOCK' ||
    taskCardType === 'CANCEL_ALLOTMENT'
  )
}

export function isReservationTypeKnownManualReviewTask(input: ReservationTaskRouteLike | null | undefined): boolean {
  if (normalizeStableCode(input?.result_type) !== 'MANUAL_REVIEW') {
    return false
  }
  const systemTaskType = normalizeStableCode(input?.system_task_type)
  const cardType = normalizeStableCode(input?.task_card_type)
  return !['MANUAL_REVIEW', 'FALLBACK', 'FALLBACK_REVIEW'].includes(systemTaskType) &&
    !['MANUAL_REVIEW', 'FALLBACK', 'FALLBACK_REVIEW'].includes(cardType)
}

export function isReservationFallbackManualReviewTask(input: ReservationTaskRouteLike | null | undefined): boolean {
  const codes = [
    input?.system_task_type,
    input?.task_card_type,
    input?.task_type,
    input?.ai_task_type,
    input?.task_subtype,
  ]
  return codes.some((code) => ['MANUAL_REVIEW', 'FALLBACK', 'FALLBACK_REVIEW'].includes(normalizeStableCode(code)))
}

export function formatReservationTaskRouteSummary(
  t: ReservationTranslator,
  input: ReservationTaskRouteLike,
  fallbackLabel?: string | null,
): string {
  if (isReservationSourceMessageNotificationTask(input)) {
    return `${t('cardType.SOURCE_MESSAGE_ONLY')} / ${formatReservationRouteCode(t, input.route_code ?? input.task_subtype)}`
  }
  if (isReservationAdapterContractErrorTask(input)) {
    return t('resultType.ADAPTER_CONTRACT_ERROR')
  }
  if (isReservationUnhandledIntentTask(input)) {
    return t('resultType.UNHANDLED_CURRENT_INTENT')
  }
  if (isReservationParentGroupCancelAllotmentTask(input)) {
    return [
      t('task.parentGroup'),
      formatReservationTaskCard(t, 'CANCEL_ALLOTMENT'),
      formatReservationRouteCode(t, 'cancel_allotment_control_block'),
    ].join(' / ')
  }
  return formatReservationTaskTypeSummary(
    t,
    input.task_type ?? input.system_task_type ?? input.task_card_type,
    input.task_subtype,
  ) || fallbackLabel || t('common.unknownTaskType')
}

export function formatReservationResultType(t: ReservationTranslator, resultType: string | null | undefined): string {
  return translateStableCode(t, 'resultType', resultType, 'common.unknownTaskType')
}

export function formatReservationSystemProcessCategory(
  t: ReservationTranslator,
  category: string | null | undefined,
): string {
  return translateStableCode(t, 'systemProcessCategory', category, 'common.unknownTaskType')
}

export function formatReservationRouteCode(t: ReservationTranslator, routeCode: string | null | undefined): string {
  const normalizedCode = normalizeStableCode(routeCode)
  if (['S10', 'S99', 'S000', 'S999'].includes(normalizedCode)) {
    return translateStableCode(t, 'taskSubtype', routeCode, 'common.unknownTaskSubtype')
  }
  return translateStableCode(t, 'taskSubtype', routeCode, 'common.unknownTaskSubtype', routeCode)
}

export function formatReservationReadonlyReason(
  t: ReservationTranslator,
  reasonCode: string | null | undefined,
): string {
  return translateStableCode(t, 'readonlyReason', reasonCode, 'common.unknownReadonlyReason')
}

export function formatReservationMaybeStableReason(
  t: ReservationTranslator,
  reason: string | null | undefined,
  fallbackKey: string,
): string {
  if (!reason) {
    return t(fallbackKey)
  }
  if (isStableCode(reason)) {
    return formatReservationReadonlyReason(t, reason)
  }
  return reason
}

export function formatReservationActorType(t: ReservationTranslator, actorType: string): string {
  return translateStableCode(t, 'actorType', actorType, 'common.unknownActorType')
}

export function formatReservationAuditAction(t: ReservationTranslator, action: string): string {
  return translateStableCode(t, 'auditAction', action, 'common.unknownAuditAction')
}

export function formatReservationOperaOperation(
  t: ReservationTranslator,
  operationCode: string | null | undefined,
  fallbackLabel?: string | null,
): string {
  return translateStableCode(t, 'operaOperation', operationCode, 'common.unknownOperation', fallbackLabel)
}

function translateStableCode(
  t: ReservationTranslator,
  namespace: string,
  code: string | null | undefined,
  fallbackKey: string,
  fallbackLabel?: string | null,
): string {
  const normalizedCode = normalizeStableCode(code)
  if (!normalizedCode) {
    return fallbackLabel || t(fallbackKey)
  }
  return t(`${namespace}.${normalizedCode}`, fallbackLabel || t(fallbackKey))
}

export function normalizeStableCode(code: string | null | undefined): string {
  if (!code) {
    return ''
  }
  return code.trim().replace(/[\s-]+/g, '_').toUpperCase()
}

function isStableCode(value: string): boolean {
  return /^[A-Z0-9_ -]+$/.test(value.trim())
}
