// Datenqualitäts-Befunde als Differenzen (Kap. 7.6).

import { describe, it, expect } from 'vitest'
import { differencesFromFindings } from '../differences-from-findings'
import { assignFindingIds, type DetectorId, type RawFinding } from '../data-quality'

const finding = (detector: DetectorId, over: Partial<RawFinding> = {}) =>
  assignFindingIds([
    {
      detector,
      scope: 'current',
      context: 'cost_path',
      descriptionDe: 'Befundtext',
      recommendationDe: 'Empfehlung',
      affectedCells: [{ fileRole: 'current', sheet: 'SBM-DEVICES-FWZ', cell: 'AP15' }],
      relatedDifferenceIds: [],
      ...over,
    },
  ])

describe('differencesFromFindings', () => {
  it('macht aus der veralteten Infozeile eine Differenz', () => {
    const d = differencesFromFindings(finding('D07'))
    expect(d).toHaveLength(1)
    expect(d[0]).toMatchObject({ area: 'SBM', kind: 'changed', anchorRow: 15 })
    expect(d[0].relatedDq).toEqual(['DQ-B-001'])
  })

  it('führt gelöschte Angaben als geleert, nicht als Wert', () => {
    const d = differencesFromFindings(finding('D08'))
    expect(d[0].kind).toBe('cleared')
    expect(d[0].cells[0].valueState).toBe('empty')
  })

  it('übergeht Befunde, die keine Differenz zwischen den Ständen sind', () => {
    // Ein hart codierter Satz oder ein Textdatum ist eine Eigenschaft der Datei,
    // kein Unterschied zwischen den Ständen. Sie bleiben Befunde.
    expect(differencesFromFindings(finding('D13', { context: 'template' }))).toEqual([])
    expect(differencesFromFindings(finding('D01', { context: 'metadata' }))).toEqual([])
    expect(differencesFromFindings(finding('D10', { context: 'metadata' }))).toEqual([])
  })

  it('ordnet den Befund seinem Bereich zu', () => {
    expect(differencesFromFindings(finding('D11'))[0].area).toBe('MFG')
    expect(differencesFromFindings(finding('D14', { scope: 'award' }))[0].area).toBe('SBM')
  })

  it('bringt eine beide Stände betreffende Fundstelle auf den aktuellen Stand', () => {
    // Der Katalog kennt je Zelle genau eine Datei; „beide" ist dort keine
    // gültige Angabe.
    const d = differencesFromFindings(
      finding('D07', { scope: 'both', affectedCells: [{ fileRole: 'both', sheet: 'S', cell: 'A5' }] }),
    )
    expect(d[0].cells[0].fileRole).toBe('current')
  })

  it('trägt jede Fundstelle des Befunds', () => {
    const d = differencesFromFindings(
      finding('D05', {
        affectedCells: [
          { fileRole: 'current', sheet: 'S', cell: 'F1' },
          { fileRole: 'current', sheet: 'S', cell: 'G1' },
        ],
      }),
    )
    expect(d[0].cells).toHaveLength(2)
    expect(d[0].anchorRow).toBe(1)
  })

  it('kommt mit einem Befund ohne Fundstelle zurecht', () => {
    // Er bekommt dann keinen Zeilenanker — und fällt in der Prüfung der
    // Rückverfolgung als Differenz ohne Fundstelle auf, statt still
    // durchzugehen.
    const d = differencesFromFindings(finding('D07', { affectedCells: [] }))
    expect(d[0].anchorRow).toBeNull()
    expect(d[0].cells).toEqual([])
  })
})
