/**
 * Sheet Calculators — pure computation functions (no DB dependency)
 *
 * Used by the main engine to compute Personalkosten, Investitionen,
 * and aggregate monthly values.
 */

import {
  MonthlyValues, MONTHS,
  emptyMonthly, dateToMonth, monthToDate,
  FPPersonalkosten, FPInvestitionen,
} from './types'

export function computePersonalkosten(positions: FPPersonalkosten[]): FPPersonalkosten[] {
  return positions.map(p => {
    const brutto = emptyMonthly()
    const sozial = emptyMonthly()
    const total = emptyMonthly()

    if (!p.start_date || !p.brutto_monthly) return { ...p, values_brutto: brutto, values_sozial: sozial, values_total: total }

    const startDate = new Date(p.start_date)
    const startM = dateToMonth(startDate.getFullYear(), startDate.getMonth() + 1)
    const endM = p.end_date
      ? dateToMonth(new Date(p.end_date).getFullYear(), new Date(p.end_date).getMonth() + 1)
      : MONTHS

    for (let m = Math.max(1, startM); m <= Math.min(MONTHS, endM); m++) {
      const { year } = monthToDate(m)
      const yearsFromStart = year - startDate.getFullYear()
      const raise = Math.pow(1 + (p.annual_raise_pct || 0) / 100, yearsFromStart)
      const monthlyBrutto = Math.round(p.brutto_monthly * raise)

      brutto[`m${m}`] = monthlyBrutto
      sozial[`m${m}`] = Math.round(monthlyBrutto * (p.ag_sozial_pct || 20.425) / 100)
      total[`m${m}`] = brutto[`m${m}`] + sozial[`m${m}`]
    }

    return { ...p, values_brutto: brutto, values_sozial: sozial, values_total: total }
  })
}

export function computeInvestitionen(items: FPInvestitionen[]): FPInvestitionen[] {
  return items.map(item => {
    const invest = emptyMonthly()
    const afa = emptyMonthly()

    if (!item.purchase_date || !item.purchase_amount) return { ...item, values_invest: invest, values_afa: afa }

    const d = new Date(item.purchase_date)
    const purchaseM = dateToMonth(d.getFullYear(), d.getMonth() + 1)

    if (purchaseM >= 1 && purchaseM <= MONTHS) {
      invest[`m${purchaseM}`] = item.purchase_amount
    }

    // AfA (linear depreciation)
    if (item.afa_years && item.afa_years > 0) {
      const afaMonths = item.afa_years * 12
      const monthlyAfa = Math.round(item.purchase_amount / afaMonths)
      for (let m = purchaseM; m < purchaseM + afaMonths && m <= MONTHS; m++) {
        if (m >= 1) afa[`m${m}`] = monthlyAfa
      }
    } else {
      // GWG: full depreciation in purchase month
      if (purchaseM >= 1 && purchaseM <= MONTHS) {
        afa[`m${purchaseM}`] = item.purchase_amount
      }
    }

    return { ...item, values_invest: invest, values_afa: afa }
  })
}

export function sumRows(rows: { values: MonthlyValues }[]): MonthlyValues {
  const result = emptyMonthly()
  for (const row of rows) {
    for (let m = 1; m <= MONTHS; m++) {
      result[`m${m}`] += row.values[`m${m}`] || 0
    }
  }
  return result
}

export function sumField(rows: { [key: string]: MonthlyValues }[], field: string): MonthlyValues {
  const result = emptyMonthly()
  for (const row of rows) {
    const v = row[field] as MonthlyValues
    if (!v) continue
    for (let m = 1; m <= MONTHS; m++) {
      result[`m${m}`] += v[`m${m}`] || 0
    }
  }
  return result
}

/**
 * Compute headcount per month from personal positions.
 */
export function computeHeadcount(personal: FPPersonalkosten[]): MonthlyValues {
  const headcount = emptyMonthly()
  for (let m = 1; m <= MONTHS; m++) {
    headcount[`m${m}`] = personal.filter(p => (p.values_total[`m${m}`] || 0) > 0).length
  }
  return headcount
}
