import { isApplicationDocumentNo } from '../../utils/documentClassification.js'
import {
  applicationDateRangesOverlap,
  normalizeApplicationPreview,
  resolveApplicationDateRange
} from '../../utils/expenseApplicationPreview.js'
import { APPLICATION_DUPLICATE_IGNORED_STATUSES } from './travelReimbursementSubmitConstants.js'

function normalizeClaimListPayload(payload) {
  if (Array.isArray(payload)) {
    return payload
  }
  return Array.isArray(payload?.items) ? payload.items : []
}

function normalizeClaimRiskFlags(claim) {
  const flags = claim?.risk_flags_json || claim?.riskFlagsJson || claim?.riskFlags || []
  if (Array.isArray(flags)) {
    return flags
  }
  return flags && typeof flags === 'object' ? [flags] : []
}

function extractApplicationDetailFromClaim(claim) {
  return normalizeClaimRiskFlags(claim).reduce((found, item) => {
    if (found || !item || typeof item !== 'object') {
      return found
    }
    const detail = item.application_detail || item.applicationDetail
    return detail && typeof detail === 'object' ? detail : null
  }, null)
}

function isApplicationClaimRecord(claim) {
  const expenseType = String(claim?.expense_type || claim?.expenseType || '').trim().toLowerCase()
  const claimNo = String(claim?.claim_no || claim?.claimNo || '').trim().toUpperCase()
  return (
    expenseType === 'application' ||
    expenseType === 'expense_application' ||
    expenseType.endsWith('_application') ||
    isApplicationDocumentNo(claimNo) ||
    Boolean(extractApplicationDetailFromClaim(claim))
  )
}

function normalizeApplicationExpenseType(value) {
  const text = String(value || '').trim().toLowerCase()
  if (!text) {
    return ''
  }
  if (text === 'travel_application' || /差旅|出差/.test(text)) {
    return 'travel_application'
  }
  if (text === 'purchase_application' || /采购/.test(text)) {
    return 'purchase_application'
  }
  if (text === 'meeting_application' || /会务|会议/.test(text)) {
    return 'meeting_application'
  }
  if (text === 'expense_application' || text === 'application' || text.endsWith('_application')) {
    return text === 'application' ? 'expense_application' : text
  }
  return 'expense_application'
}

function resolveClaimApplicationExpenseType(claim) {
  const detail = extractApplicationDetailFromClaim(claim) || {}
  return normalizeApplicationExpenseType(
    claim?.expense_type ||
      claim?.expenseType ||
      detail.application_type ||
      detail.applicationType ||
      ''
  )
}

function isIgnoredApplicationDuplicateStatus(status) {
  return APPLICATION_DUPLICATE_IGNORED_STATUSES.has(String(status || '').trim().toLowerCase())
}

function resolveClaimApplicationDateRange(claim) {
  const detail = extractApplicationDetailFromClaim(claim) || {}
  return (
    resolveApplicationDateRange(
      detail.time ||
        detail.time_range ||
        detail.timeRange ||
        detail.application_time ||
        detail.applicationTime ||
        detail.application_business_time ||
        detail.applicationBusinessTime ||
        detail.application_date ||
        detail.applicationDate,
      detail.days || detail.application_days || detail.applicationDays
    ) ||
    resolveApplicationDateRange(claim?.occurred_at || claim?.occurredAt || '')
  )
}

function formatApplicationDateRangeLabel(range) {
  if (!range?.startDate) {
    return '待确认'
  }
  return range.startDate === range.endDate ? range.startDate : `${range.startDate} 至 ${range.endDate}`
}

function findOverlappingApplicationClaim(applicationPreview, claimsPayload) {
  const preview = normalizeApplicationPreview(applicationPreview)
  const fields = preview.fields || {}
  const currentRange = resolveApplicationDateRange(fields.time, fields.days)
  if (!currentRange) {
    return null
  }
  const currentExpenseType = normalizeApplicationExpenseType(fields.applicationType)
  const claims = normalizeClaimListPayload(claimsPayload)
  for (const claim of claims) {
    if (!isApplicationClaimRecord(claim) || isIgnoredApplicationDuplicateStatus(claim?.status)) {
      continue
    }
    const existingExpenseType = resolveClaimApplicationExpenseType(claim)
    if (currentExpenseType && existingExpenseType && currentExpenseType !== existingExpenseType) {
      continue
    }
    const existingRange = resolveClaimApplicationDateRange(claim)
    if (!existingRange || !applicationDateRangesOverlap(currentRange, existingRange)) {
      continue
    }
    return {
      claim,
      currentRange,
      existingRange,
      claimId: String(claim?.id || claim?.claim_id || claim?.claimId || '').trim(),
      claimNo: String(claim?.claim_no || claim?.claimNo || claim?.id || '').trim(),
      status: String(claim?.approval_stage || claim?.approvalStage || claim?.status || '').trim(),
      reason: String(claim?.reason || '').trim(),
      location: String(claim?.location || '').trim()
    }
  }
  return null
}

function buildApplicationDateConflictMessage(conflict) {
  const claimNo = conflict?.claimNo || '已有申请'
  return [
    '我先检查了您的申请时间，发现同一天或重叠日期已经存在差旅申请，不能重复创建。',
    '',
    '已有申请：',
    `- **单号**：${claimNo}`,
    `- **申请时间**：${formatApplicationDateRangeLabel(conflict?.existingRange)}`,
    conflict?.location ? `- **地点**：${conflict.location}` : '',
    conflict?.reason ? `- **事由**：${conflict.reason}` : '',
    `- **当前节点**：${conflict?.status || '处理中'}`,
    '',
    `本次识别时间：${formatApplicationDateRangeLabel(conflict?.currentRange)}`,
    '',
    '请先查看已有申请，或修改本次出差时间后再继续。'
  ].filter(Boolean).join('\n')
}

function buildApplicationDateConflictActions(conflict) {
  const actions = []
  if (conflict?.claimId) {
    actions.push({
      action_type: 'open_application_detail',
      label: '查看已有申请',
      description: conflict.claimNo ? `进入 ${conflict.claimNo} 单据详情。` : '进入已有申请单据详情。',
      icon: 'mdi mdi-file-search-outline',
      payload: {
        claim_id: conflict.claimId,
        claim_no: conflict.claimNo
      }
    })
  }
  actions.push({
    action_type: 'prefill_composer',
    label: '修改出差时间',
    description: '在输入框中补充新的出差日期后继续。',
    icon: 'mdi mdi-calendar-edit-outline',
    payload: {
      prompt_prefill: '修改出差时间为：'
    }
  })
  return actions
}

export {
  buildApplicationDateConflictActions,
  buildApplicationDateConflictMessage,
  findOverlappingApplicationClaim
}
