import { DQRule } from '../models/dq-rules.model'
import { parseFormulaRule } from './parseFormulaRule'

/**
 * Injects the computed `=...` formula string into each row's data for every
 * HARDFORMULA/SOFTFORMULA column, so Handsontable/HyperFormula displays the
 * evaluated result. HARDFORMULA's readOnly-ness is handled separately in
 * dc-validator.ts, alongside the existing READONLY rule - this only deals
 * with the actual computed value.
 *
 * Mutates and returns `dataSource` (same in-place-mutate convention as
 * applyNumericFormats).
 */
export const applyFormulaRules = (
  dataSource: any[],
  dqRules: DQRule[],
  columnNames: string[],
  dataSourceUnchanged: any[],
  headerPks: string[],
  userName: string
): any[] => {
  const formulaRules = dqRules.filter(
    (rule) =>
      rule.RULE_TYPE === 'HARDFORMULA' || rule.RULE_TYPE === 'SOFTFORMULA'
  )
  if (formulaRules.length === 0) return dataSource

  dataSource.forEach((row, rowIndex) => {
    for (const formulaRule of formulaRules) {
      const origRow = dataSourceUnchanged.find((candidate) =>
        headerPks.every((pk) => candidate[pk] === row[pk])
      )

      row[formulaRule.BASE_COL] = parseFormulaRule(formulaRule.RULE_VALUE, {
        columnNames,
        rowIndex,
        userName,
        origValue: origRow ? origRow[formulaRule.BASE_COL] : undefined
      })
    }
  })

  return dataSource
}
