function normalizeText(value) {
  return String(value || '').trim()
}

function resolveTrackedFieldKey(fieldKey = '') {
  const normalized = normalizeText(fieldKey)
  return normalized === 'time_return' ? 'time' : normalized
}

function resolveExistingChanges(preview = {}) {
  const feedback = preview?.aiDecisionFeedback
  return Array.isArray(feedback?.changedFields)
    ? feedback.changedFields.filter((item) => item && typeof item === 'object')
    : []
}

function resolveTrackedFieldKeys(fieldKeyOrKeys = '') {
  const fieldKeys = Array.isArray(fieldKeyOrKeys) ? fieldKeyOrKeys : [fieldKeyOrKeys]
  return [...new Set(fieldKeys.map(resolveTrackedFieldKey).filter(Boolean))]
}

function resolveFeedbackRevision(preview = {}) {
  const revision = Number(preview?.aiDecisionFeedback?.revision)
  return Number.isSafeInteger(revision) && revision >= 0 ? revision : 0
}

export function trackApplicationPreviewFieldEdit(
  previousPreview = {},
  nextPreview = {},
  fieldKeyOrKeys = ''
) {
  const trackedFieldKeys = resolveTrackedFieldKeys(fieldKeyOrKeys)
  if (!trackedFieldKeys.length) return nextPreview

  const existingChanges = resolveExistingChanges(previousPreview)
  const retainedChanges = existingChanges.filter(
    (item) => !trackedFieldKeys.includes(resolveTrackedFieldKey(item.fieldKey))
  )

  for (const trackedFieldKey of trackedFieldKeys) {
    const existingChange = existingChanges.find(
      (item) => resolveTrackedFieldKey(item.fieldKey) === trackedFieldKey
    )
    const suggestedValue = existingChange
      ? normalizeText(existingChange.suggestedValue)
      : normalizeText(previousPreview?.fields?.[trackedFieldKey])
    const finalValue = normalizeText(nextPreview?.fields?.[trackedFieldKey])
    if (suggestedValue !== finalValue) {
      retainedChanges.push({
        fieldKey: trackedFieldKey,
        suggestedValue,
        finalValue
      })
    }
  }

  return {
    ...nextPreview,
    aiDecisionFeedback: {
      schemaVersion: 1,
      revision: resolveFeedbackRevision(previousPreview) + 1,
      changedFields: retainedChanges.sort((left, right) => (
        normalizeText(left.fieldKey).localeCompare(normalizeText(right.fieldKey))
      ))
    }
  }
}
