import {
  formatAmount,
  formatDate,
  getLatestEvent,
  getRiskFlags,
  normalizeText,
  parseNumber
} from './requestShared.js'

function normalizeApplicationHandoffDetail(flag = {}) {
  const detail = flag?.application_detail || flag?.applicationDetail || {}
  const reviewValues = flag?.review_form_values || flag?.reviewFormValues || {}
  const sceneSelection = flag?.expense_scene_selection || flag?.expenseSceneSelection || {}
  return [sceneSelection, reviewValues, detail]
    .filter((item) => item && typeof item === 'object')
    .reduce((acc, item) => ({ ...acc, ...item }), {})
}

function resolveApplicationField(flag = {}, detail = {}, snakeKey, camelKey = '') {
  return normalizeText(
    flag?.[snakeKey]
    || (camelKey ? flag?.[camelKey] : '')
    || detail?.[snakeKey]
    || (camelKey ? detail?.[camelKey] : '')
  )
}

function resolveApplicationValue(flag = {}, detail = {}, keys = []) {
  for (const key of keys) {
    const detailValue = normalizeText(detail?.[key])
    if (detailValue) {
      return detailValue
    }
    const flagValue = normalizeText(flag?.[key])
    if (flagValue) {
      return flagValue
    }
  }

  return ''
}

function extractDateRange(value) {
  const dates = normalizeText(value).match(/\d{4}-\d{2}-\d{2}/g) || []
  if (!dates.length) {
    return { startDate: '', endDate: '' }
  }

  return {
    startDate: dates[0],
    endDate: dates[dates.length - 1]
  }
}

function resolveRelatedApplicationClaimNo(flag = {}) {
  const detail = normalizeApplicationHandoffDetail(flag)
  return resolveApplicationField(flag, detail, 'application_claim_no', 'applicationClaimNo')
}

function findRelatedApplicationEvent(claim) {
  const events = getRiskFlags(claim).filter((flag) => (
    flag
    && typeof flag === 'object'
    && resolveRelatedApplicationClaimNo(flag)
  ))
  return getLatestEvent(events) || events[events.length - 1] || null
}

function resolveRelatedApplicationAmountLabel(flag, detail, claim) {
  const explicitLabel = normalizeText(
    flag?.application_amount_label
    || flag?.applicationAmountLabel
    || detail?.application_amount_label
    || detail?.applicationAmountLabel
  )
  if (explicitLabel) return explicitLabel

  const rawAmount = normalizeText(
    flag?.application_amount
    || flag?.applicationAmount
    || flag?.application_budget_amount
    || flag?.applicationBudgetAmount
    || detail?.application_amount
    || detail?.applicationAmount
    || detail?.amount
    || claim?.amount
  )
  const amountValue = parseNumber(rawAmount)
  return amountValue > 0 ? formatAmount(amountValue) : rawAmount
}

function resolveRelatedApplicationInfo(claim, typeLabel = '') {
  const relatedEvent = findRelatedApplicationEvent(claim)
  if (!relatedEvent) {
    return null
  }

  const detail = normalizeApplicationHandoffDetail(relatedEvent)
  const claimNo = resolveRelatedApplicationClaimNo(relatedEvent)
  const applicationType = normalizeText(
    detail.application_type
    || detail.applicationType
    || relatedEvent.application_type
    || relatedEvent.applicationType
    || typeLabel
  )
  const location = normalizeText(
    detail.application_location
    || detail.applicationLocation
    || detail.location
    || relatedEvent.application_location
    || relatedEvent.applicationLocation
    || claim?.location
  )
  const reason = normalizeText(
    detail.application_reason
    || detail.applicationReason
    || detail.reason
    || relatedEvent.application_reason
    || relatedEvent.applicationReason
    || claim?.reason
  )
  const content = normalizeText(
    detail.application_content
    || detail.applicationContent
    || relatedEvent.application_content
    || relatedEvent.applicationContent
  ) || [applicationType, location].filter(Boolean).join(' / ')
  const rawTime = normalizeText(
    detail.application_time
    || detail.applicationTime
    || detail.application_business_time
    || detail.applicationBusinessTime
    || detail.business_time
    || detail.businessTime
    || detail.time_range
    || detail.timeRange
    || detail.time
    || detail.application_date
    || detail.applicationDate
    || relatedEvent.application_time
    || relatedEvent.applicationTime
    || relatedEvent.application_business_time
    || relatedEvent.applicationBusinessTime
    || relatedEvent.business_time
    || relatedEvent.businessTime
    || relatedEvent.time_range
    || relatedEvent.timeRange
    || relatedEvent.application_date
    || relatedEvent.applicationDate
    || claim?.occurred_at
  )
  const displayTime = formatDate(rawTime) || rawTime
  const dateRange = extractDateRange(rawTime || displayTime)
  const ruleName = resolveApplicationValue(relatedEvent, detail, [
    'application_rule_name',
    'applicationRuleName',
    'rule_name',
    'ruleName'
  ])
  const ruleVersion = resolveApplicationValue(relatedEvent, detail, [
    'application_rule_version',
    'applicationRuleVersion',
    'rule_version',
    'ruleVersion'
  ])

  return {
    id: resolveApplicationField(relatedEvent, detail, 'application_claim_id', 'applicationClaimId'),
    claimNo,
    content,
    reason,
    days: normalizeText(
      detail.application_days
      || detail.applicationDays
      || detail.days
      || relatedEvent.application_days
      || relatedEvent.applicationDays
    ),
    location,
    time: displayTime,
    tripStartDate: dateRange.startDate,
    tripEndDate: dateRange.endDate,
    amountLabel: resolveRelatedApplicationAmountLabel(relatedEvent, detail, claim),
    statusLabel: resolveApplicationField(relatedEvent, detail, 'application_status_label', 'applicationStatusLabel'),
    transportMode: normalizeText(
      detail.application_transport_mode
      || detail.applicationTransportMode
      || detail.transport_mode
      || relatedEvent.application_transport_mode
      || relatedEvent.applicationTransportMode
    ),
    lodgingDailyCap: resolveApplicationValue(relatedEvent, detail, [
      'application_lodging_daily_cap',
      'applicationLodgingDailyCap',
      'lodging_daily_cap',
      'lodgingDailyCap'
    ]),
    subsidyDailyCap: resolveApplicationValue(relatedEvent, detail, [
      'application_subsidy_daily_cap',
      'applicationSubsidyDailyCap',
      'subsidy_daily_cap',
      'subsidyDailyCap'
    ]),
    transportPolicy: resolveApplicationValue(relatedEvent, detail, [
      'application_transport_policy',
      'applicationTransportPolicy',
      'transport_policy',
      'transportPolicy'
    ]),
    policyEstimate: resolveApplicationValue(relatedEvent, detail, [
      'application_policy_estimate',
      'applicationPolicyEstimate',
      'policy_estimate',
      'policyEstimate'
    ]),
    ruleName,
    ruleVersion,
    ruleLabel: [ruleName, ruleVersion].filter(Boolean).join(' / ')
  }
}


export {
  findRelatedApplicationEvent,
  resolveRelatedApplicationInfo
}
