import { FIT_OUT_COST_CHF_PER_SQM, FITOUT_AMORTIZATION_YEARS, FITOUT_ANNUITY_RATE } from './constants'

export interface FitOutInvestment {
  grossPerSqm: { min: number; max: number }
  mabOffset: number
  netPerSqm: { min: number; max: number }
  netTotal: { min: number; max: number }
  annualBurden: { min: number; max: number }
  isFullyCovered: boolean
  shortLabel: string
  detailLabel: string
}

// Annuitätenfaktor: a = i(1+i)^n / ((1+i)^n − 1); bei i=0 → 1/n (lineare Amortisation als Fallback)
export function annuityFactor(rate: number, years: number): number {
  if (years <= 0) return 0
  if (rate === 0) return 1 / years
  const q = Math.pow(1 + rate, years)
  return (rate * q) / (q - 1)
}

// Bezugsfertige Stufen — kein Ausbau-Aufschlag (Mieter muss nicht mehr investieren)
const FITOUT_READY = new Set(['FULL', 'PREMIUM'])

/**
 * Effektive Jahresbelastung pro m². Grundsatz: die quotierte Miete gilt IMMER als realer Preis —
 * die Plattform erfindet keinen Aufschlag. Nur wenn der Mieter ausbaut (SHELL/BASIC), wird die
 * versteckte Ausbaukost annuitätisch sichtbar gemacht (abzgl. MAB). Übernimmt der Vermieter, ist der
 * Ausbau bereits in der Miete enthalten → kein Aufschlag, keine Mieter-Capex.
 */
export function effectiveAnnualBurdenPerSqm(p: {
  fitOut?: string
  rentPricePerSqm: number
  mabPerSqm: number
  fitOutByLandlord?: boolean
}): { rentPerSqm: number; fitOutPerSqm: number; effectivePerSqm: number } {
  if (p.fitOutByLandlord || FITOUT_READY.has(p.fitOut ?? '')) {
    return { rentPerSqm: p.rentPricePerSqm, fitOutPerSqm: 0, effectivePerSqm: p.rentPricePerSqm }
  }
  const bm = FIT_OUT_COST_CHF_PER_SQM[p.fitOut ?? '']
  const grossMid = bm ? (bm.min + bm.max) / 2 : 0
  const net = Math.max(0, grossMid - p.mabPerSqm)
  const fitOutPerSqm = Math.round(net * annuityFactor(FITOUT_ANNUITY_RATE, FITOUT_AMORTIZATION_YEARS))
  return { rentPerSqm: p.rentPricePerSqm, fitOutPerSqm, effectivePerSqm: p.rentPricePerSqm + fitOutPerSqm }
}

function formatChfK(value: number): string {
  if (value >= 1000) return `CHF ${(value / 1000).toLocaleString('de-CH', { minimumFractionDigits: 0, maximumFractionDigits: 1 })} Mio.`
  return `CHF ${Math.round(value / 1000)}k`
}

export function calcFitOutInvestment(
  fitOut: string,
  areaSqm: number,
  mabPerSqm: number,
  tenantBudgetPerSqm: number,
): FitOutInvestment | null {
  const benchmarks = FIT_OUT_COST_CHF_PER_SQM[fitOut]
  if (!benchmarks) return null

  const gross = benchmarks
  const totalOffset = mabPerSqm + tenantBudgetPerSqm
  const netMin = Math.max(0, gross.min - totalOffset)
  const netMax = Math.max(0, gross.max - totalOffset)

  const netTotal = {
    min: Math.round(netMin * areaSqm),
    max: Math.round(netMax * areaSqm),
  }

  const factor = annuityFactor(FITOUT_ANNUITY_RATE, FITOUT_AMORTIZATION_YEARS)
  const annualBurden = {
    min: Math.round(netTotal.min * factor),
    max: Math.round(netTotal.max * factor),
  }

  const isFullyCovered = netTotal.max <= 0

  const shortLabel = isFullyCovered
    ? 'Investition gedeckt'
    : netTotal.min === netTotal.max
      ? `Est. ${formatChfK(netTotal.min)}`
      : `Est. ${formatChfK(netTotal.min)}–${formatChfK(netTotal.max)}`

  const detailLabel = isFullyCovered
    ? 'Ausbaukosten durch MAB/Budget gedeckt'
    : `CHF ${netMin.toLocaleString('de-CH')}–${netMax.toLocaleString('de-CH')}/m² Nettoinvestition`

  return {
    grossPerSqm: gross,
    mabOffset: mabPerSqm,
    netPerSqm: { min: netMin, max: netMax },
    netTotal,
    annualBurden,
    isFullyCovered,
    shortLabel,
    detailLabel,
  }
}
