import { describe, expect, it } from 'vitest'
import JSZip from 'jszip'
import { DEFAULT_ENGINE_CONFIG, type QafComparisonResult } from '@/lib/qaf-differences'
import { buildQafComparisonCopilotDocx } from '../internal/qaf-docx'

function comparison(): QafComparisonResult {
  return {
    partNumber: '12345-AB',
    altRef: { id: 'file-alt', fileName: 'ALT_Angebot.xlsx', quotationDate: '2026-01-01' },
    neuRef: { id: 'file-neu', fileName: 'NEU_Aktuell.xlsx', quotationDate: '2026-06-01' },
    stepComparisons: [
      {
        altIndex: 0,
        neuIndex: 0,
        stepLabel: '10 Schweißen',
        match: {
          altIndex: 0,
          neuIndex: 0,
          matchStatus: 'safe_match',
          confidenceScore: 1,
          matchMethod: 'exact',
          matchedFields: [],
          conflictingFields: [],
          explanation: 'exakte Übereinstimmung',
          requiresReview: true,
        },
        fieldDiffs: [
          {
            field: 'fk',
            altValue: 10,
            neuValue: 12,
            deltaAbsolute: 2,
            deltaPercent: 0.2,
            deltaPercentagePoints: null,
            isPercentField: false,
            status: 'anstieg',
          },
        ],
        includedInDelta: true,
      },
    ],
    summaryDiffs: [],
    structureChanges: { new: ['20 Neuer Prozessschritt'], removed: [], possible: [] },
    plausibility: [
      {
        type: 'formel_geaendert',
        severity: 'pruefen',
        step: '10 Schweißen',
        field: 'fk',
        explanation: 'Formel wurde gegenüber ALT verändert.',
      },
    ],
    rootCause: {
      partNumber: '12345-AB',
      topAbsoluteDrivers: [{ stepLabel: '10 Schweißen', field: 'fk', deltaAbsolute: 2, deltaPercent: 0.2 }],
      topRelativeDrivers: [],
      structureChanges: { new: ['20 Neuer Prozessschritt'], removed: [], possible: [] },
      currencyEffect: false,
      managementSummary: 'Die Fertigungskosten steigen primär durch Prozessschritt 10 Schweißen.',
      requiresReviewNote: true,
    },
    matchReviewCount: 1,
    ruleEnforcement: 'warn',
    engineConfig: DEFAULT_ENGINE_CONFIG,
  }
}

async function documentXml(buf: Buffer): Promise<string> {
  const zip = await JSZip.loadAsync(buf)
  const entry = zip.file('word/document.xml')
  if (!entry) throw new Error('word/document.xml missing from generated DOCX')
  return entry.async('string')
}

describe('buildQafComparisonCopilotDocx', () => {
  it('produces a real DOCX with AI-instruction block, management summary, structure changes, and the field-diff table', async () => {
    const buf = await buildQafComparisonCopilotDocx({ comparison: comparison(), isDemo: false, generatedAtLabel: '19.07.2026, 10:00' })
    expect(Buffer.isBuffer(buf)).toBe(true)

    const xml = await documentXml(buf)
    expect(xml).toContain('QAF-Vergleich-Export')
    expect(xml).toContain('12345-AB')
    expect(xml).toContain('ALT_Angebot.xlsx')
    expect(xml).toContain('Die Fertigungskosten steigen primär durch Prozessschritt 10 Schweißen.')
    expect(xml).toContain('20 Neuer Prozessschritt')
    expect(xml).toContain('Formel wurde gegenüber ALT verändert.')
    expect(xml).toContain('Qualitäts-Anforderungs-Formular')
    expect(xml).not.toContain('Demo-Hinweis')
  })

  it('renders the fictional-data disclaimer only when isDemo is true', async () => {
    const withDemo = await buildQafComparisonCopilotDocx({ comparison: comparison(), isDemo: true, generatedAtLabel: 'x' })
    const withoutDemo = await buildQafComparisonCopilotDocx({ comparison: comparison(), isDemo: false, generatedAtLabel: 'x' })
    expect(await documentXml(withDemo)).toContain('Demo-Hinweis')
    expect(await documentXml(withoutDemo)).not.toContain('Demo-Hinweis')
  })

  it('renders "keine Feld-Diffs" when no step comparisons matched', async () => {
    const unmatched: QafComparisonResult = {
      ...comparison(),
      stepComparisons: [{ ...comparison().stepComparisons[0], altIndex: null, neuIndex: null }],
    }
    const buf = await buildQafComparisonCopilotDocx({ comparison: unmatched, isDemo: false, generatedAtLabel: 'x' })
    const xml = await documentXml(buf)
    expect(xml).toContain('Keine Feld-Diffs verfügbar')
  })
})
