// "Exported to lexoffice as CSV" marker on C_Order.
//
// The settlement pages (Amazon / eBay) build a lexoffice bank-statement CSV from
// the marketplace payout data. To give the bookkeeper an overview of which orders
// already went out in such a file, two custom columns on C_Order record it:
//   - isLexofficeCsvExported   (Yes-No, default 'N', IsAlwaysUpdateable=Y)
//   - lexofficeCsvExportDate   (Date,   nullable,    IsAlwaysUpdateable=Y)
// Both are custom (EntityType=U) columns without a generated model getter, so
// iDempiere REST uses the ColumnName verbatim on reads AND writes — hence the
// lowercase-first names (same style as C_Invoice.isUploadToLexoffice).
//
// FAIL-SOFT: until the columns exist every read that $selects them is answered
// with `400 "<col> is not a valid column of table C_Order"`. The settlement
// routes therefore ask for them optimistically, and on that specific error
// retry without them and remember (per process) that the feature is unavailable.
// The frontend shows the CSV marker/filters only when `csvExportAvailable` is true.

export const CSV_EXPORT_FLAG_COL = 'isLexofficeCsvExported'
export const CSV_EXPORT_DATE_COL = 'lexofficeCsvExportDate'
export const CSV_EXPORT_COLS = [CSV_EXPORT_FLAG_COL, CSV_EXPORT_DATE_COL]

// null = not probed yet, true = columns exist, false = missing (retry-free fast path)
let csvColumnsAvailable: boolean | null = null

export const isCsvExportColumnsAvailable = () => csvColumnsAvailable !== false

const errorText = (err: any): string =>
  String(err?.data?.detail || err?.data?.message || err?.data?.title || err?.message || '')

// True when the error is iDempiere complaining about one of OUR columns —
// anything else (auth, network, other invalid column) must keep propagating.
export const isCsvExportColumnError = (err: any): boolean => {
  const text = errorText(err)
  return CSV_EXPORT_COLS.some(col => new RegExp(`\\b${col}\\b`, 'i').test(text)) &&
    /not a valid column|column .* not found|invalid column|no such column/i.test(text)
}

export const markCsvExportColumnsMissing = () => { csvColumnsAvailable = false }
export const markCsvExportColumnsPresent = () => { csvColumnsAvailable = true }

// Runs `request(extraSelectCols)` with the CSV columns appended to the $select
// list; on the "not a valid column" error retries once without them.
export const withOptionalCsvExportCols = async <T>(request: (cols: string[]) => Promise<T>): Promise<T> => {
  if (csvColumnsAvailable === false) return request([])
  try {
    const res = await request(CSV_EXPORT_COLS)
    csvColumnsAvailable = true
    return res
  } catch (err: any) {
    if (!isCsvExportColumnError(err)) throw err
    csvColumnsAvailable = false
    return request([])
  }
}

const truthy = (v: any) => v === true || v === 'Y' || v === 'true'

// Tolerant read of the marker off a c_order REST record (either casing).
export const readCsvExportMark = (rec: any): { exported: boolean; date: string } => {
  if (!rec) return { exported: false, date: '' }
  const flag = rec[CSV_EXPORT_FLAG_COL] ?? rec.IsLexofficeCsvExported ?? rec.islexofficecsvexported
  const date = rec[CSV_EXPORT_DATE_COL] ?? rec.LexofficeCsvExportDate ?? rec.lexofficecsvexportdate
  return { exported: truthy(flag), date: date ? String(date) : '' }
}
