// Tests for the centralized DE/EN worksheet-name synonym registry (KAR-905 /
// P3.1). Synthetic sheet-name strings only, no real BMW file content. // allow-customer-string

import { describe, expect, it } from 'vitest'
import { MODULE_SHEET_NAME_ALIASES, matchesModuleSheetName, moduleSheetNameLanguageSignal } from '../module-sheet-names'

describe('matchesModuleSheetName', () => {
  it('matches SUMMARY for both the V9 tab name and the legacy DE tab name', () => {
    expect(matchesModuleSheetName('SUMMARY', 'SUMMARY')).toBe(true)
    expect(matchesModuleSheetName('Zusammenfassung', 'SUMMARY')).toBe(true)
    expect(matchesModuleSheetName('1. SUMMARY', 'SUMMARY')).toBe(true)
  })

  it('matches MANUFACTURING for the DE tab name, the EN tab name, and the documented EN typo', () => {
    expect(matchesModuleSheetName('Fertigungskosten', 'MANUFACTURING')).toBe(true)
    expect(matchesModuleSheetName('2. FERTIGUNGSKOSTEN', 'MANUFACTURING')).toBe(true)
    expect(matchesModuleSheetName('Manufacturing costs', 'MANUFACTURING')).toBe(true)
    expect(matchesModuleSheetName('Manufactering costs', 'MANUFACTURING')).toBe(true)
  })

  it('matches MATERIAL identically for a DE-content and an EN-content file (same locale-invariant tab name)', () => {
    expect(matchesModuleSheetName('MATERIAL', 'MATERIAL')).toBe(true)
    expect(matchesModuleSheetName('3. Material', 'MATERIAL')).toBe(true)
  })

  it('matches SBM-DEVICES-FWZ regardless of file language', () => {
    expect(matchesModuleSheetName('SBM-DEVICES-FWZ', 'SBM')).toBe(true)
  })

  it('matches LOGISTICS&CUSTOM including a spaced-ampersand variant', () => {
    expect(matchesModuleSheetName('LOGISTICS&CUSTOM', 'LOGISTICS')).toBe(true)
    expect(matchesModuleSheetName('LOGISTICS & CUSTOM', 'LOGISTICS')).toBe(true)
  })

  it('matches RAW MATERIAL RISKS in both the plural (Leitfaden teil2) and singular (Leitfaden teil1) spelling', () => {
    expect(matchesModuleSheetName('RAW MATERIAL RISKS', 'RMR')).toBe(true)
    expect(matchesModuleSheetName('RAW MATERIAL RISK', 'RMR')).toBe(true)
  })

  it('matches LC-CN in both the dash and space spelling', () => {
    expect(matchesModuleSheetName('LC-CN', 'LC_CN')).toBe(true)
    expect(matchesModuleSheetName('LC CN', 'LC_CN')).toBe(true)
  })

  it('matches CO2e sheet/panel names tolerantly', () => {
    expect(matchesModuleSheetName('CO2e', 'CO2E')).toBe(true)
    expect(matchesModuleSheetName('Carbon Footprint', 'CO2E')).toBe(true)
  })

  it('does not match an unrelated sheet name', () => {
    expect(matchesModuleSheetName('Deckblatt', 'MATERIAL')).toBe(false)
    expect(matchesModuleSheetName('Sheet1', 'SBM')).toBe(false)
  })
})

describe('moduleSheetNameLanguageSignal', () => {
  it('reports the DE/EN signal for the one genuinely bilingual module (MANUFACTURING)', () => {
    expect(moduleSheetNameLanguageSignal('Fertigungskosten', 'MANUFACTURING')).toBe('de')
    expect(moduleSheetNameLanguageSignal('Manufacturing costs', 'MANUFACTURING')).toBe('en')
    expect(moduleSheetNameLanguageSignal('Manufactering costs', 'MANUFACTURING')).toBe('en')
  })

  it('reports the DE-only signal for the legacy SUMMARY tab name, and no signal for the locale-invariant V9 name', () => {
    expect(moduleSheetNameLanguageSignal('Zusammenfassung', 'SUMMARY')).toBe('de')
    expect(moduleSheetNameLanguageSignal('SUMMARY', 'SUMMARY')).toBeNull()
  })

  it('reports no language signal for locale-invariant module tab names', () => {
    expect(moduleSheetNameLanguageSignal('MATERIAL', 'MATERIAL')).toBeNull()
    expect(moduleSheetNameLanguageSignal('SBM-DEVICES-FWZ', 'SBM')).toBeNull()
    expect(moduleSheetNameLanguageSignal('LOGISTICS&CUSTOM', 'LOGISTICS')).toBeNull()
    expect(moduleSheetNameLanguageSignal('RAW MATERIAL RISKS', 'RMR')).toBeNull()
    expect(moduleSheetNameLanguageSignal('LC-CN', 'LC_CN')).toBeNull()
    expect(moduleSheetNameLanguageSignal('CO2e', 'CO2E')).toBeNull()
  })

  it('returns null for a non-matching sheet name', () => {
    expect(moduleSheetNameLanguageSignal('Deckblatt', 'MATERIAL')).toBeNull()
  })
})

describe('MODULE_SHEET_NAME_ALIASES structural invariants', () => {
  it('every module has at least one alias', () => {
    for (const [module, aliases] of Object.entries(MODULE_SHEET_NAME_ALIASES)) {
      expect(aliases.length, `module ${module} has no aliases`).toBeGreaterThan(0)
    }
  })

  it('MANUFACTURING is the only module with more than one distinct declared language', () => {
    // KAR-915: RMR joins SUMMARY in the "declares exactly one language
    // signal ('de')" bucket — "Rohstoffrisiken" is the real V8.8 DE tab
    // name (server-only real-file-verified), a genuine DE-only variant of
    // the locale-invariant "raw material risk" alias, same shape as
    // SUMMARY's pre-existing "zusammenfassung" DE-only alias below.
    for (const [module, aliases] of Object.entries(MODULE_SHEET_NAME_ALIASES)) {
      const languages = new Set(aliases.map((a) => a.language).filter((l): l is 'de' | 'en' => l !== undefined))
      if (module === 'MANUFACTURING') {
        expect(languages).toEqual(new Set(['de', 'en']))
      } else if (module === 'SUMMARY' || module === 'RMR') {
        expect(languages).toEqual(new Set(['de']))
      } else {
        expect(languages.size, `module ${module} unexpectedly declares a language signal`).toBe(0)
      }
    }
  })
})
