import { ConstraintEnforcer } from '../constraint-enforcer'
import type { ScopeDecision } from '../../compliance-scope-types'

describe('ConstraintEnforcer', () => {
  const enforcer = new ConstraintEnforcer()

  // Helper: minimal valid ScopeDecision
  function makeDecision(overrides: Partial<ScopeDecision> = {}): ScopeDecision {
    return {
      id: 'test-decision',
      determinedLevel: 'L2',
      scores: { risk_score: 50, complexity_score: 50, assurance_need: 50, composite_score: 50 },
      triggeredHardTriggers: [],
      requiredDocuments: [
        { documentType: 'vvt', label: 'VVT', requirement: 'mandatory' as const, priority: 'medium' as const, estimatedEffort: 2, triggeredBy: [] },
        { documentType: 'tom', label: 'TOM', requirement: 'mandatory' as const, priority: 'medium' as const, estimatedEffort: 3, triggeredBy: [] },
        { documentType: 'lf', label: 'LF', requirement: 'mandatory' as const, priority: 'medium' as const, estimatedEffort: 1, triggeredBy: [] },
      ],
      riskFlags: [],
      gaps: [],
      nextActions: [],
      reasoning: [],
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
      ...overrides,
    } as ScopeDecision
  }

  describe('check - no decision', () => {
    it('should allow basic documents (vvt, tom, dsi) without decision', () => {
      const result = enforcer.check('vvt', null)
      expect(result.allowed).toBe(true)
      expect(result.adjustments.length).toBeGreaterThan(0)
      expect(result.checkedRules).toContain('RULE-NO-DECISION')
    })

    it('should allow tom without decision', () => {
      const result = enforcer.check('tom', null)
      expect(result.allowed).toBe(true)
    })

    it('should allow dsi without decision', () => {
      const result = enforcer.check('dsi', null)
      expect(result.allowed).toBe(true)
    })

    it('should block non-basic documents without decision', () => {
      const result = enforcer.check('dsfa', null)
      expect(result.allowed).toBe(false)
      expect(result.violations.length).toBeGreaterThan(0)
    })

    it('should block av_vertrag without decision', () => {
      const result = enforcer.check('av_vertrag', null)
      expect(result.allowed).toBe(false)
    })
  })

  describe('check - RULE-DOC-REQUIRED', () => {
    it('should allow required documents', () => {
      const decision = makeDecision()
      const result = enforcer.check('vvt', decision)
      expect(result.allowed).toBe(true)
    })

    it('should warn but allow optional documents', () => {
      const decision = makeDecision({
        requiredDocuments: [
          { documentType: 'vvt', label: 'VVT', requirement: 'mandatory' as const, priority: 'medium' as const, estimatedEffort: 2, triggeredBy: [] },
        ],
      })
      const result = enforcer.check('dsfa', decision)
      expect(result.allowed).toBe(true) // Only warns, does not block
      expect(result.adjustments.some(a => a.includes('nicht als Pflicht'))).toBe(true)
    })
  })

  describe('check - RULE-DEPTH-MATCH', () => {
    it('should block when requested depth exceeds determined level', () => {
      const decision = makeDecision({ determinedLevel: 'L2' })
      const result = enforcer.check('vvt', decision, 'L4')
      expect(result.allowed).toBe(false)
      expect(result.violations.some(v => v.includes('ueberschreitet'))).toBe(true)
    })

    it('should allow when requested depth matches level', () => {
      const decision = makeDecision({ determinedLevel: 'L2' })
      const result = enforcer.check('vvt', decision, 'L2')
      expect(result.allowed).toBe(true)
    })

    it('should adjust when requested depth is below level', () => {
      const decision = makeDecision({ determinedLevel: 'L3' })
      const result = enforcer.check('vvt', decision, 'L1')
      expect(result.allowed).toBe(true)
      expect(result.adjustments.some(a => a.includes('angehoben'))).toBe(true)
    })

    it('should allow without requested depth level', () => {
      const decision = makeDecision({ determinedLevel: 'L3' })
      const result = enforcer.check('vvt', decision)
      expect(result.allowed).toBe(true)
    })
  })

  describe('check - RULE-DSFA-ENFORCEMENT', () => {
    it('should note when DSFA is not required but requested', () => {
      const decision = makeDecision({ determinedLevel: 'L2' })
      const result = enforcer.check('dsfa', decision)
      expect(result.allowed).toBe(true)
      expect(result.adjustments.some(a => a.includes('nicht verpflichtend'))).toBe(true)
    })

    it('should allow DSFA when hard triggers require it', () => {
      const decision = makeDecision({
        determinedLevel: 'L3',
        triggeredHardTriggers: [{
          ruleId: 'HT-ART9',
          category: '',
          description: 'Art. 9 Daten',
          minimumLevel: 'L3',
          requiresDSFA: true,
          mandatoryDocuments: ['dsfa'],
          legalReference: 'Art. 35 DSGVO',
          matchedValue: null,
          explanation: 'Art. 9 Daten verarbeitet',
        }],
      })
      const result = enforcer.check('dsfa', decision)
      expect(result.allowed).toBe(true)
    })

    it('should warn about DSFA when drafting non-DSFA but DSFA is required', () => {
      const decision = makeDecision({
        determinedLevel: 'L3',
        triggeredHardTriggers: [{
          ruleId: 'HT-ART9',
          category: '',
          description: 'Art. 9 Daten',
          minimumLevel: 'L3',
          requiresDSFA: true,
          mandatoryDocuments: ['dsfa'],
          legalReference: 'Art. 35 DSGVO',
          matchedValue: null,
          explanation: '',
        }],
        requiredDocuments: [
          { documentType: 'dsfa', label: 'DSFA', requirement: 'mandatory' as const, priority: 'medium' as const, estimatedEffort: 8, triggeredBy: [] },
          { documentType: 'vvt', label: 'VVT', requirement: 'mandatory' as const, priority: 'medium' as const, estimatedEffort: 2, triggeredBy: [] },
        ],
      })
      const result = enforcer.check('vvt', decision)
      expect(result.allowed).toBe(true)
      expect(result.adjustments.some(a => a.includes('DSFA') && a.includes('verpflichtend'))).toBe(true)
    })
  })

  describe('check - RULE-RISK-FLAGS', () => {
    it('should note critical risk flags', () => {
      const decision = makeDecision({
        riskFlags: [
          { severity: 'CRITICAL', category: '', message: 'Offene Art. 9 Verarbeitung', recommendation: 'DSFA durchfuehren' },
          { severity: 'HIGH', category: '', message: 'Fehlende Verschluesselung', recommendation: 'TOM erstellen' },
          { severity: 'LOW', category: '', message: 'Dokumentation unvollstaendig', recommendation: '' },
        ],
      })
      const result = enforcer.check('vvt', decision)
      expect(result.allowed).toBe(true)
      expect(result.adjustments.some(a => a.includes('2 kritische/hohe Risiko-Flags'))).toBe(true)
    })

    it('should not flag when no risk flags present', () => {
      const decision = makeDecision({ riskFlags: [] })
      const result = enforcer.check('vvt', decision)
      expect(result.adjustments.every(a => !a.includes('Risiko-Flags'))).toBe(true)
    })
  })

  describe('check - checkedRules tracking', () => {
    it('should track all checked rules', () => {
      const decision = makeDecision()
      const result = enforcer.check('vvt', decision)
      expect(result.checkedRules).toContain('RULE-DOC-REQUIRED')
      expect(result.checkedRules).toContain('RULE-DEPTH-MATCH')
      expect(result.checkedRules).toContain('RULE-DSFA-ENFORCEMENT')
      expect(result.checkedRules).toContain('RULE-RISK-FLAGS')
      expect(result.checkedRules).toContain('RULE-HARD-TRIGGER-CONSISTENCY')
    })
  })

  describe('checkFromContext', () => {
    it('should reconstruct decision from DraftContext and check', () => {
      const context = {
        decisions: {
          level: 'L2' as const,
          scores: { risk_score: 50, complexity_score: 50, assurance_need: 50, composite_score: 50 },
          hardTriggers: [],
          requiredDocuments: [
            { documentType: 'vvt' as const, depth: 'Standard', detailItems: [] },
          ],
        },
        companyProfile: { name: 'Test GmbH', industry: 'IT', employeeCount: 50, businessModel: 'SaaS', isPublicSector: false },
        constraints: {
          depthRequirements: { required: true, depth: 'Standard', detailItems: [], estimatedEffort: '2h' },
          riskFlags: [],
          boundaries: [],
        },
      }
      const result = enforcer.checkFromContext('vvt', context)
      expect(result.allowed).toBe(true)
      expect(result.checkedRules.length).toBeGreaterThan(0)
    })
  })
})
