/**
 * Shared display helpers for the unified Banking workspace
 * (`pages/accounting/banking` + `components/accounting/banking/*`).
 * Display-only — API payloads stay ISO / raw.
 */

const amountFormatter = new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 })

/** `1234.5` → `1.234,50`; '' for null/undefined/''. */
export const formatAmount = (value: any): string => {
  if (value === null || value === undefined || value === '') return ''
  const num = Number(value)
  return isNaN(num) ? String(value) : amountFormatter.format(num)
}

/** `DE02513900000095588301` → `DE02 5139 0000 0095 5883 01`. */
export const formatIban = (iban: any): string => {
  return String(iban || '').replace(/\s+/g, '').replace(/(.{4})/g, '$1 ').trim()
}

/** Truncate long free text (remittance info, messages) for table cells. */
export const truncateText = (text: any, max = 120): string => {
  const str = String(text || '')
  return str.length > max ? str.substring(0, max) + '…' : str
}

/**
 * Laravel-proxied routes return HTTP 200 with `{ success:false, message }` for
 * application-level refusals, and `{ status: 4xx/5xx }` for transport errors.
 */
export const okLaravel = (res: any): boolean => {
  return !!res && res.success !== false && Number(res.status || 200) < 400
}

/** iDempiere-backed routes follow the app-wide `Number(res.status) === 200` convention. */
export const okIdempiere = (res: any): boolean => {
  return !!res && Number(res.status) === 200
}

export type PillTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger'

/** EBICS connection lifecycle (Laravel `bank_connections.status`). */
export const connectionStatusMeta: Record<string, { key: string; fallback: string; tone: PillTone }> = {
  created:            { key: 'banking_status_created',            fallback: 'Angelegt',              tone: 'neutral' },
  keys_sent:          { key: 'banking_status_keys_sent',          fallback: 'Schlüssel gesendet',    tone: 'info' },
  letter_pending:     { key: 'banking_status_letter_pending',     fallback: 'INI-Brief ausstehend',  tone: 'info' },
  bank_keys_verified: { key: 'banking_status_bank_keys_verified', fallback: 'Bankschlüssel geprüft', tone: 'warning' },
  active:             { key: 'banking_status_active',             fallback: 'Aktiv',                 tone: 'success' },
  suspended:          { key: 'banking_status_suspended',          fallback: 'Pausiert',              tone: 'danger' }
}

/** Staged statement / transaction `import_status`. */
export const importStatusMeta: Record<string, { key: string; fallback: string; tone: PillTone }> = {
  pending:  { key: 'banking_import_status_pending',  fallback: 'Ausstehend',     tone: 'info' },
  imported: { key: 'banking_import_status_imported', fallback: 'Importiert',     tone: 'success' },
  failed:   { key: 'banking_import_status_failed',   fallback: 'Fehlgeschlagen', tone: 'danger' },
  skipped:  { key: 'banking_import_status_skipped',  fallback: 'Übersprungen',   tone: 'neutral' }
}

/** Preview verdicts from both the EBICS dry-run and the iDempiere import plan. */
export const verdictMeta: Record<string, { key: string; fallback: string; tone: PillTone }> = {
  would_create:         { key: 'banking_verdict_would_create',         fallback: 'Wird angelegt',             tone: 'info' },
  would_stage:          { key: 'banking_verdict_would_stage',          fallback: 'Wird bereitgestellt',       tone: 'info' },
  already_imported:     { key: 'banking_verdict_already_imported',     fallback: 'Bereits importiert',        tone: 'neutral' },
  already_in_idempiere: { key: 'banking_verdict_already_in_idempiere', fallback: 'Bereits in iDempiere',      tone: 'neutral' },
  skip_imported:        { key: 'banking_verdict_skip_imported',        fallback: 'Übersprungen (importiert)', tone: 'neutral' },
  skip_non_eur:         { key: 'banking_verdict_skip_non_eur',         fallback: 'Übersprungen (nicht EUR)',  tone: 'warning' },
  already_staged:       { key: 'banking_verdict_already_staged',       fallback: 'Bereits bereitgestellt',    tone: 'neutral' },
  staged:               { key: 'banking_verdict_staged',               fallback: 'Bereitgestellt',            tone: 'success' },
  bank_account_missing: { key: 'banking_verdict_bank_account_missing', fallback: 'Bankkonto fehlt',           tone: 'danger' },
  no_pending_lines:     { key: 'banking_verdict_no_pending_lines',     fallback: 'Keine offenen Umsätze',     tone: 'warning' }
}

/** Resolve `{ label, tone }` for a status value against one of the meta maps. */
export const resolveMeta = (
  map: Record<string, { key: string; fallback: string; tone: PillTone }>,
  value: any,
  t: any
): { label: string; tone: PillTone } => {
  const meta = map[String(value || '')]
  if (!meta) return { label: String(value || '—'), tone: 'neutral' }
  return { label: t?.[meta.key] || meta.fallback, tone: meta.tone }
}

/**
 * Newest-first ordering for every list on the Banking page (statements,
 * transactions, lines, fetch/import results). Compares ISO-ish date strings
 * (`YYYY-MM-DD…`) descending, then an optional numeric tie-breaker descending
 * (line no / id) so a statement's own lines also read latest → oldest.
 * Returns a NEW array — Laravel keeps processing imports oldest-first (balance
 * chain); only the display is flipped.
 */
export const newestFirst = <T = any>(rows: T[] | null | undefined, dateKey: string, tieKey = ''): T[] => {
  return [...(rows || [])].sort((a: any, b: any) => {
    const byDate = String(b?.[dateKey] ?? '').localeCompare(String(a?.[dateKey] ?? ''))
    if (byDate) return byDate
    return tieKey ? Number(b?.[tieKey] ?? 0) - Number(a?.[tieKey] ?? 0) : 0
  })
}
