// `summary_lines` — die Preisblock-Zeilen mit ihrer Bedeutung (Spezifikation
// Kap. 7.2, R-04/R-05/R-06/R-18/R-22).
//
// Die Kennzahlen-Tabelle zeigt Werte, sagt aber nichts über die Zeilen selbst:
// welche Nummer sie im Preisblock trägt, ob sie in eine Summe eingeht, in
// welcher Einheit sie steht, ob ihr Label von der Datei gedeckt ist. Genau
// diese Angaben braucht jeder Konsument, der mehr tun will als anzeigen —
// und ihr Fehlen ist der gemeinsame Nenner der Befunde F-01, F-02 und F-10.

import { describe, it, expect } from 'vitest'
import { buildSummaryLines, type SummaryDiffRowData } from '../summary-view'
import { SUMMARY_ROW_REGISTRY } from '../summary-row-registry'

function row(metric_key: string, alt: number | null, neu: number | null, over: Partial<SummaryDiffRowData> = {}): SummaryDiffRowData {
  return {
    metric_key,
    alt_value: alt,
    neu_value: neu,
    delta_absolute: alt !== null && neu !== null ? neu - alt : null,
    delta_percent: null,
    currency: 'EUR',
    status: 'anstieg',
    source_alt: 'P11',
    source_neu: 'P11',
    ...over,
  }
}

describe('buildSummaryLines (Kap. 7.2)', () => {
  const lines = buildSummaryLines([
    row('materialCosts', 300, 310),
    row('customsSupplierToBMW', 0.76, null, { label_file_alt: 'JIS', label_verified_alt: false }),
  ])

  it('führt jede Registry-Zeile, auch die ohne Daten (R-22)', () => {
    expect(lines).toHaveLength(SUMMARY_ROW_REGISTRY.length)
    expect(lines.map((l) => l.rowKey)).toEqual(SUMMARY_ROW_REGISTRY.map((s) => s.rowKey))
  })

  it('nennt Rolle, Blocknummer und Einheit je Zeile (R-05/R-18)', () => {
    const material = lines.find((l) => l.rowKey === 'summary.material')!
    expect(material.role).toBe('additive')
    expect(material.blockNo).toBe('1')
    expect(material.unit).toBe('EUR_per_piece')

    const memo = lines.find((l) => l.rowKey === 'summary.packaging_transport_included')!
    expect(memo.role).toBe('memo')
    expect(memo.blockNo).toBeNull()
  })

  it('trägt Werte und Quellzellen durch', () => {
    const material = lines.find((l) => l.rowKey === 'summary.material')!
    expect(material.valueAward).toBe(300)
    expect(material.valueCurrent).toBe(310)
    expect(material.delta).toBeCloseTo(10, 6)
    expect(material.sourceAward).toBe('P11')
  })

  it('führt das Datei-Label und seinen Verifikationsstand mit (R-04)', () => {
    const jis = lines.find((l) => l.rowKey === 'summary.jis')!
    expect(jis.labelFileAward).toBe('JIS')
    expect(jis.labelVerifiedAward).toBe(false)
    // Anzeige folgt der Datei, nicht der Konfiguration.
    expect(jis.label).toBe('JIS')
  })

  it('lässt eine Zeile ohne Daten leer statt sie zu erfinden', () => {
    const untouched = lines.find((l) => l.rowKey === 'summary.transport_supplier_to_bmw')!
    expect(untouched.valueAward).toBeNull()
    expect(untouched.valueCurrent).toBeNull()
    expect(untouched.delta).toBeNull()
    expect(untouched.present).toBe(false)
    // Ohne Datei-Label bleibt das Registry-Label.
    expect(untouched.label.length).toBeGreaterThan(0)
    expect(untouched.labelVerifiedAward).toBeNull()
  })

  it('kennzeichnet die Einmalzahlungen in Euro statt Euro je Stück', () => {
    const tools = lines.find((l) => l.rowKey === 'summary.one_time_tools')!
    expect(tools.unit).toBe('EUR')
    expect(tools.role).toBe('one_time')
  })

  it('macht die additiven Zeilen als Menge auffindbar (R-06)', () => {
    const additive = lines.filter((l) => l.role === 'additive')
    expect(additive.map((l) => l.blockNo)).not.toContain(null)
    expect(new Set(additive.map((l) => l.blockNo))).toEqual(new Set(['1', '2', '3', '4', '5', '6', '7', '8']))
  })
})
