import { describe, it, expect } from 'vitest'
import ExcelJS from 'exceljs'
import { TEMPLATE_HEADERS } from '@/lib/qaf-parser'
import { parseQafFile } from '../workbook-adapter'

async function workbookFile(): Promise<File> {
  const wb = new ExcelJS.Workbook()

  const zs = wb.addWorksheet('Zusammenfassung')
  zs.getCell('F8').value = 'BMW Sachnummer:' // allow-customer-string
  zs.getCell('I8').value = 7490365
  zs.getCell('L5').value = 'Teilebenennung:'
  zs.getCell('M5').value = 'Blende'

  const fk = wb.addWorksheet('Fertigungskosten')
  // headers in row 1 (template position; the parser auto-detects the header row)
  fk.getRow(1).values = [null, ...TEMPLATE_HEADERS]
  // one data row
  fk.getRow(2).values = [null, '1', 'Blende', 'Montage', 'Anlage A', 'Werk', 'EUR', 12, 1, 1, 30, 10, 50, 0, 0, 0, 100, 'EUR', 1, 1, 100, 2, 1]

  const buf = await wb.xlsx.writeBuffer()
  return new File([buf], 'qaf.xlsx', {
    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  })
}

/** A workbook whose Fertigungskosten sheet has NO recognizable header at all
 * (headerIdx === null in qaf-parser.ts) — parseQAFTemplate throws "Keine
 * passenden Spalten gefunden…", while the SUMMARY sheet stays fully intact
 * and parseable. This is the exact real-corpus symptom class gate-audit.md's
 * B14 documents (37 "0-Steps" files, batch-report.md §3a). */
async function workbookWithUnreadableManufacturingHeader(): Promise<File> {
  const wb = new ExcelJS.Workbook()

  const zs = wb.addWorksheet('Zusammenfassung')
  zs.getCell('F8').value = 'BMW Sachnummer:' // allow-customer-string
  zs.getCell('I8').value = 7490365
  zs.getCell('L5').value = 'Teilebenennung:'
  zs.getCell('M5').value = 'Blende'

  const fk = wb.addWorksheet('Fertigungskosten')
  fk.getRow(1).values = [null, 'Voellig', 'Andere', 'Spalten']
  fk.getRow(2).values = [null, 'a', 'b', 'c']

  const buf = await wb.xlsx.writeBuffer()
  return new File([buf], 'qaf-unreadable-manufacturing.xlsx', {
    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  })
}

describe('parseQafFile', () => {
  it('returns both the summary and the manufacturing steps', async () => {
    const { summary, steps } = await parseQafFile(await workbookFile())
    expect(summary.partNumber.value).toBe('7490365')
    expect(summary.partName.value).toBe('Blende')
    expect(steps.length).toBe(1)
    expect(steps[0].prozessbezeichnung).toBe('Montage')
    expect(steps[0].fk).toBe(100)
    expect(steps[0].zykluszeit).toBe(12)
  })

  // KAR-958/P1 (gate-audit.md B14, Parse-Entkopplung): the actual fix under
  // test — a manufacturing-facet throw used to reject the WHOLE Promise.all,
  // discarding the already-successful summary parse right along with it.
  describe('manufacturing-facet decoupling (KAR-958/P1)', () => {
    it('a Fertigungskosten header the parser cannot read no longer takes the SUMMARY parse down with it', async () => {
      const result = await parseQafFile(await workbookWithUnreadableManufacturingHeader())

      // The fix: summary survives untouched.
      expect(result.summary.partNumber.value).toBe('7490365')
      expect(result.summary.partName.value).toBe('Blende')

      // The degraded facet: empty steps, structured finding instead of a
      // propagated exception.
      expect(result.steps).toEqual([])
      expect(result.manufacturingParseMeta).toEqual({ parseConfidence: 0, unmappedHeaders: [], mappedFieldCount: 0 })
      expect(result.manufacturingDegradation).toEqual({
        facet: 'manufacturing',
        reason: 'PARSE_FAILED',
        sheet: 'Fertigungskosten',
        message: expect.stringContaining('Keine passenden Spalten gefunden'),
      })
    })

    it('a workbook with zero worksheets: summary degrades to all-null (not thrown), manufacturing is flagged', async () => {
      const wb = new ExcelJS.Workbook()
      const buf = await wb.xlsx.writeBuffer()
      const file = new File([buf], 'empty.xlsx', {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      })

      const result = await parseQafFile(file)
      expect(result.summary.partNumber.value).toBeNull()
      expect(result.steps).toEqual([])
      expect(result.manufacturingDegradation?.reason).toBe('PARSE_FAILED')
      expect(result.manufacturingDegradation?.message).toContain('keine Tabellenblätter')
    })
  })
})
