// KAR-911 / P4.1 — degraded-module read-model for the Confidence-/
// Provenance-UI (extracts already-persisted coreFieldsFound flags from
// qaf_file.g60_meta; no new engine computation).

import { describe, expect, it } from 'vitest'
import { degradedModulesSentence, extractDegradedModules } from '../module-degradation'

describe('extractDegradedModules', () => {
  it('returns an empty array for null/undefined meta', () => {
    expect(extractDegradedModules(null)).toEqual([])
    expect(extractDegradedModules(undefined)).toEqual([])
  })

  it('returns an empty array when no module meta is present at all (file has none of the optional sheets)', () => {
    expect(extractDegradedModules({})).toEqual([])
  })

  it('does not flag a module whose meta is entirely absent (sheet never existed — not a degradation)', () => {
    expect(extractDegradedModules({ material: null, sbm: null })).toEqual([])
  })

  it('does not flag a module that parsed successfully (coreFieldsFound: true)', () => {
    expect(extractDegradedModules({ material: { parseMeta: { coreFieldsFound: true } } })).toEqual([])
  })

  it('flags MATERIAL when its sheet was present but the header was too degraded to trust', () => {
    expect(extractDegradedModules({ material: { parseMeta: { coreFieldsFound: false } } })).toEqual([
      { key: 'material', labelDe: 'MATERIAL', labelEn: 'MATERIAL' },
    ])
  })

  // KAR-915 review rider (PR #290): the "flags every degraded module" case
  // below only ever exercised SBM in its NON-degraded (coreFieldsFound: true)
  // branch — this isolates SBM alone as degraded, same shape as the MATERIAL
  // case above, so an SBM-specific regression (e.g. a typo'd 'sbm' key in
  // MODULE_FACETS) would fail here instead of only showing up buried inside
  // the multi-module list assertion.
  it('flags SBM when its sheet was present but the header was too degraded to trust', () => {
    expect(extractDegradedModules({ sbm: { parseMeta: { coreFieldsFound: false } } })).toEqual([
      { key: 'sbm', labelDe: 'SBM-DEVICES-FWZ', labelEn: 'SBM-DEVICES-FWZ' },
    ])
  })

  it('flags every degraded module, preserving a stable QAF-guide order', () => {
    const result = extractDegradedModules({
      material: { parseMeta: { coreFieldsFound: false } },
      sbm: { parseMeta: { coreFieldsFound: true } },
      rmr: { parseMeta: { coreFieldsFound: false } },
      logistics: { parseMeta: { coreFieldsFound: false } },
      lccn: { meta: { coreFieldsFound: true } },
      co2e: { material: { parseMeta: { coreFieldsFound: false } } },
    })
    expect(result.map((m) => m.key)).toEqual(['material', 'rmr', 'logistics', 'co2e_material'])
  })

  it('reads LC-CN degradation from .meta (single-record parser shape), not .parseMeta', () => {
    expect(extractDegradedModules({ lccn: { meta: { coreFieldsFound: false } } })).toEqual([
      { key: 'lccn', labelDe: 'LC-CN', labelEn: 'LC-CN' },
    ])
  })

  it('reads CO2e degradation from the material facet only', () => {
    expect(extractDegradedModules({ co2e: { material: { parseMeta: { coreFieldsFound: false } } } })).toEqual([
      { key: 'co2e_material', labelDe: 'Carbon Footprint (Material)', labelEn: 'Carbon Footprint (material)' },
    ])
  })
})

describe('degradedModulesSentence', () => {
  it('returns null for an empty module list', () => {
    expect(degradedModulesSentence([])).toBeNull()
  })

  it('joins a single module into one bilingual sentence', () => {
    const sentence = degradedModulesSentence([{ key: 'material', labelDe: 'MATERIAL', labelEn: 'MATERIAL' }])
    expect(sentence).toEqual({
      de: 'Modul(e) nicht ausgewertet — Detail-Sheet vorhanden, aber Kopfzeile nicht zuordenbar: MATERIAL.',
      en: 'Module(s) not evaluated — detail sheet present but its header could not be mapped: MATERIAL.',
    })
  })

  it('joins several modules with a comma', () => {
    const sentence = degradedModulesSentence([
      { key: 'material', labelDe: 'MATERIAL', labelEn: 'MATERIAL' },
      { key: 'sbm', labelDe: 'SBM-DEVICES-FWZ', labelEn: 'SBM-DEVICES-FWZ' },
    ])
    expect(sentence?.de).toBe(
      'Modul(e) nicht ausgewertet — Detail-Sheet vorhanden, aber Kopfzeile nicht zuordenbar: MATERIAL, SBM-DEVICES-FWZ.',
    )
    expect(sentence?.en).toBe(
      'Module(s) not evaluated — detail sheet present but its header could not be mapped: MATERIAL, SBM-DEVICES-FWZ.',
    )
  })
})
