// Loop 10 View-Spec-Adoption, Modul 2: buildNegotiationRun reichert die
// bestehenden Fachzeilen (buildNegotiation/buildOneTimeRows — dort geprüft)
// um SourceRef-Belege aus dem Katalog an und zieht die Einmalzahlungs-
// Facts-Zeile aus der Schale in den Builder. Diese Tests pinnen die
// Anreicherung und die Facts-Formulierung — NICHT die Fachregeln selbst.

import { describe, it, expect } from 'vitest'
import { buildNegotiationRun } from '../negotiation-run'
import type { DifferenceRecord } from '../all-differences'
import type { SummaryDiffRowData } from '../summary-view'
import type { SummaryMetricKey } from '../summary-metrics'

function row(metricKey: string, alt: number | null, neu: number | null): SummaryDiffRowData {
  const delta = alt !== null && neu !== null ? neu - alt : null
  return {
    metric_key: metricKey,
    alt_value: alt,
    neu_value: neu,
    delta_absolute: delta,
    delta_percent: delta !== null && alt ? delta / Math.abs(alt) : null,
    currency: 'EUR',
    status: null,
    source_alt: null,
    source_neu: null,
  }
}

function record(differenceId: string, sheet: string, cell: string): DifferenceRecord {
  return {
    differenceId,
    cells: [{ fileRole: 'award', sheet, cell }],
  } as unknown as DifferenceRecord
}

const IDS = new Map<SummaryMetricKey, string[]>([
  ['materialCosts', ['SUM-002', 'SUM-001']],
  ['totalOneTimePayment', ['SUM-009']],
])

describe('buildNegotiationRun', () => {
  it('Verhandlungs-Zeilen tragen die Katalog-Belege ihrer Metrik — Kennungen sortiert, Zellen aus den Records', () => {
    const run = buildNegotiationRun({
      summaryRows: [row('materialCosts', 100, 120)],
      summaryRecords: [record('SUM-001', 'Blatt1', 'C7'), record('SUM-002', 'Blatt1', 'C9')],
      idsByMetricKey: IDS,
    })
    expect(run.bringers).toHaveLength(1)
    const ref = run.bringers[0].sourceRef
    expect(ref.path).toBe('summary.materialCosts')
    expect(ref.differenceIds).toEqual(['SUM-001', 'SUM-002'])
    expect(ref.cells.map((c) => `${c.sheet}!${c.cell}`).sort()).toEqual(['Blatt1!C7', 'Blatt1!C9'])
  })

  it('eine Metrik ohne Katalog-Kennungen trägt einen ehrlich leeren Beleg — kein Wurf, keine erfundene Herkunft', () => {
    const run = buildNegotiationRun({
      summaryRows: [row('manufacturingCosts', 50, 40)],
      summaryRecords: [],
      idsByMetricKey: new Map(),
    })
    expect(run.wins).toHaveLength(1)
    expect(run.wins[0].sourceRef).toEqual({ path: 'summary.manufacturingCosts', cells: [], differenceIds: [] })
  })

  it('Einmalzahlungen: bestimmbare Summe wird als Delta-Phrase formuliert, Belege hängen an der Zeile', () => {
    const run = buildNegotiationRun({
      summaryRows: [row('totalOneTimePayment', 1000, 1500)],
      summaryRecords: [record('SUM-009', 'Blatt2', 'D4')],
      idsByMetricKey: IDS,
    })
    expect(run.oneTime).toHaveLength(1)
    expect(run.oneTime[0].sourceRef.differenceIds).toEqual(['SUM-009'])
    expect(run.oneTimeFactsDe[0]).toMatch(/\+.*EUR/)
    expect(run.oneTimeFactsDe[1]).toBeNull()
  })

  it('Einmalzahlungen ohne bestimmbares Delta: „Summe nicht bestimmbar" + benannte übergangene Position', () => {
    const run = buildNegotiationRun({
      summaryRows: [row('oneTimeTools', 500, null)],
      summaryRecords: [],
      idsByMetricKey: new Map(),
    })
    expect(run.oneTimeFactsDe[0]).toBe('Summe nicht bestimmbar')
    expect(run.oneTimeFactsDe[1]).toContain('1 Position ohne bestimmbares Delta')
  })

  it('alle Einmalzahlungen unverändert → „Alle Positionen unverändert" (Gegenprobe: keine Summen-Phrase)', () => {
    const run = buildNegotiationRun({
      summaryRows: [row('oneTimeDevelopment', 300, 300)],
      summaryRecords: [],
      idsByMetricKey: new Map(),
    })
    expect(run.oneTimeFactsDe).toEqual(['Alle Positionen unverändert'])
  })
})
