// Tests for the CanonicalFieldRegistry capability-scoped view (KAR-959/P2).

import { describe, expect, it } from 'vitest'
import { CANONICAL_FIELDS } from '../../canonical-fields'
import { deriveFieldScope, fieldsForModule, fieldsByScope, findFieldByAlias, moduleSheetRole, CAPABILITY_FIELDS } from '../field-registry'

describe('deriveFieldScope', () => {
  it('maps level: summary to global scope', () => {
    expect(deriveFieldScope({ level: 'summary' })).toBe('global')
  })

  it('maps level: row to process scope', () => {
    expect(deriveFieldScope({ level: 'row' })).toBe('process')
  })
})

describe('CAPABILITY_FIELDS — additive over canonical-fields.ts', () => {
  it('is a strict superset of CANONICAL_FIELDS (KAR-892/P1.1 registry untouched)', () => {
    expect(CAPABILITY_FIELDS.length).toBeGreaterThan(CANONICAL_FIELDS.length)
    for (const f of CANONICAL_FIELDS) {
      expect(CAPABILITY_FIELDS.some((c) => c.id === f.id)).toBe(true)
    }
  })

  it('carries no duplicate ids across the merged registry', () => {
    const ids = CAPABILITY_FIELDS.map((f) => f.id)
    expect(new Set(ids).size).toBe(ids.length)
  })

  it('includes the KAR-959/P2 inefficiency-factor extension field, scoped as process', () => {
    const found = fieldsForModule('MANUFACTURING').find((f) => f.id === 'cap_mfg_inefficiency_factor')
    expect(found).toBeDefined()
    expect(found?.scope).toBe('process')
    expect(found?.evidence.length).toBeGreaterThan(0)
  })

  it('includes the KAR-959/P2 SG&A/profit master-rate extension field, scoped as global', () => {
    const found = fieldsForModule('SUMMARY').find((f) => f.id === 'cap_sum_sga_profit_rate')
    expect(found).toBeDefined()
    expect(found?.scope).toBe('global')
  })
})

describe('fieldsForModule', () => {
  it('returns every MANUFACTURING field including the already-registered process parameters', () => {
    const ids = fieldsForModule('MANUFACTURING').map((f) => f.id)
    expect(ids).toContain('mfg_cycle_time')
    expect(ids).toContain('mfg_parts_per_cycle')
    expect(ids).toContain('mfg_direct_employee_count')
    expect(ids).toContain('mfg_machine_hour_rate')
    expect(ids).toContain('mfg_scrap_rate')
  })

  it('returns fields scoped consistently with their level', () => {
    for (const f of fieldsForModule('MATERIAL')) {
      expect(f.scope).toBe(f.level === 'summary' ? 'global' : 'process')
    }
  })

  it('returns an empty array for a module with no registered fields (defensive — every real module has entries today)', () => {
    expect(fieldsForModule('MANUFACTURING').length).toBeGreaterThan(0)
  })
})

describe('fieldsByScope', () => {
  it('partitions the whole registry into global and process with no overlap and no loss', () => {
    const global = fieldsByScope('global')
    const process = fieldsByScope('process')
    expect(global.length + process.length).toBe(CAPABILITY_FIELDS.length)
    const globalIds = new Set(global.map((f) => f.id))
    expect(process.every((f) => !globalIds.has(f.id))).toBe(true)
  })
})

describe('findFieldByAlias', () => {
  it('finds a canonical field by its DE label', () => {
    const hits = findFieldByAlias('Zykluszeit [s]', 'de')
    expect(hits.some((f) => f.id === 'mfg_cycle_time')).toBe(true)
  })

  it('finds the KAR-959/P2 extension field by its documented alias', () => {
    const hits = findFieldByAlias('Ineffizienz-Aufschlag')
    expect(hits.some((f) => f.id === 'cap_mfg_inefficiency_factor')).toBe(true)
  })

  it('returns an empty array for a label with no match', () => {
    expect(findFieldByAlias('Definitely Not A QAF Label 12345')).toEqual([])
  })
})

describe('moduleSheetRole', () => {
  it('maps every capability module onto its sheet role', () => {
    expect(moduleSheetRole('SUMMARY')).toBe('summary')
    expect(moduleSheetRole('MANUFACTURING')).toBe('manufacturing')
    expect(moduleSheetRole('MATERIAL')).toBe('material')
    expect(moduleSheetRole('SBM')).toBe('sbm')
    expect(moduleSheetRole('LOGISTICS')).toBe('logistics')
    expect(moduleSheetRole('RMR')).toBe('rmr')
    expect(moduleSheetRole('LC_CN')).toBe('lccn')
    expect(moduleSheetRole('CO2E')).toBe('co2e')
  })

  it('returns null for a module outside this PR scope (G60/WAF/LAF/LEK)', () => {
    expect(moduleSheetRole('G60')).toBeNull()
    expect(moduleSheetRole('WAF')).toBeNull()
    expect(moduleSheetRole('LAF')).toBeNull()
    expect(moduleSheetRole('LEK')).toBeNull()
  })
})
