import { describe, it, expect } from 'vitest'
import {
  calculateRiskLevel,
  DSFA_SECTIONS,
  DSFA_STATUS_LABELS,
  DSFA_RISK_LEVEL_LABELS,
  DSFA_LEGAL_BASES,
  DSFA_AFFECTED_RIGHTS,
  RISK_MATRIX,
  type DSFARisk,
  type DSFAMitigation,
  type DSFASectionProgress,
  type DSFA,
} from '../types'

describe('DSFA_SECTIONS', () => {
  it('should have 9 sections defined', () => {
    expect(DSFA_SECTIONS.length).toBe(9)
  })

  it('should have sections numbered 0-8', () => {
    const numbers = DSFA_SECTIONS.map(s => s.number)
    expect(numbers).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8])
  })

  it('should have GDPR references for all sections', () => {
    DSFA_SECTIONS.forEach(section => {
      expect(section.gdprRef).toBeDefined()
      expect(section.gdprRef).toContain('Art. 35')
    })
  })

  it('should mark 7 sections as required', () => {
    const requiredSections = DSFA_SECTIONS.filter(s => s.required)
    expect(requiredSections.length).toBe(7)
    expect(requiredSections.map(s => s.number)).toEqual([0, 1, 2, 3, 4, 6, 7])
  })

  it('should mark sections 5 and 8 as optional', () => {
    const optionalSections = DSFA_SECTIONS.filter(s => !s.required)
    expect(optionalSections.length).toBe(2)
    expect(optionalSections.map(s => s.number)).toEqual([5, 8])
  })

  it('should have German titles for all sections', () => {
    DSFA_SECTIONS.forEach(section => {
      expect(section.titleDE).toBeDefined()
      expect(section.titleDE.length).toBeGreaterThan(0)
    })
  })
})

describe('DSFA_STATUS_LABELS', () => {
  it('should have all status labels defined', () => {
    expect(DSFA_STATUS_LABELS.draft).toBe('Entwurf')
    expect(DSFA_STATUS_LABELS.in_review).toBe('In Prüfung')
    expect(DSFA_STATUS_LABELS.approved).toBe('Genehmigt')
    expect(DSFA_STATUS_LABELS.rejected).toBe('Abgelehnt')
    expect(DSFA_STATUS_LABELS.needs_update).toBe('Überarbeitung erforderlich')
  })
})

describe('DSFA_RISK_LEVEL_LABELS', () => {
  it('should have all risk level labels defined', () => {
    expect(DSFA_RISK_LEVEL_LABELS.low).toBe('Niedrig')
    expect(DSFA_RISK_LEVEL_LABELS.medium).toBe('Mittel')
    expect(DSFA_RISK_LEVEL_LABELS.high).toBe('Hoch')
    expect(DSFA_RISK_LEVEL_LABELS.very_high).toBe('Sehr Hoch')
  })
})

describe('DSFA_LEGAL_BASES', () => {
  it('should have 6 legal bases defined', () => {
    expect(Object.keys(DSFA_LEGAL_BASES).length).toBe(6)
  })

  it('should reference GDPR Article 6', () => {
    Object.values(DSFA_LEGAL_BASES).forEach(label => {
      expect(label).toContain('Art. 6')
    })
  })
})

describe('DSFA_AFFECTED_RIGHTS', () => {
  it('should have multiple affected rights defined', () => {
    expect(DSFA_AFFECTED_RIGHTS.length).toBeGreaterThan(5)
  })

  it('should have id and label for each right', () => {
    DSFA_AFFECTED_RIGHTS.forEach(right => {
      expect(right.id).toBeDefined()
      expect(right.label).toBeDefined()
    })
  })

  it('should include GDPR data subject rights', () => {
    const ids = DSFA_AFFECTED_RIGHTS.map(r => r.id)
    expect(ids).toContain('right_of_access')
    expect(ids).toContain('right_to_erasure')
    expect(ids).toContain('right_to_data_portability')
  })
})

describe('RISK_MATRIX', () => {
  it('should have 9 cells defined (3x3 matrix)', () => {
    expect(RISK_MATRIX.length).toBe(9)
  })

  it('should cover all combinations of likelihood and impact', () => {
    const likelihoodValues = ['low', 'medium', 'high']
    const impactValues = ['low', 'medium', 'high']

    likelihoodValues.forEach(likelihood => {
      impactValues.forEach(impact => {
        const cell = RISK_MATRIX.find(
          c => c.likelihood === likelihood && c.impact === impact
        )
        expect(cell).toBeDefined()
      })
    })
  })

  it('should have increasing scores for higher risks', () => {
    const lowLow = RISK_MATRIX.find(c => c.likelihood === 'low' && c.impact === 'low')
    const highHigh = RISK_MATRIX.find(c => c.likelihood === 'high' && c.impact === 'high')

    expect(lowLow?.score).toBeLessThan(highHigh?.score || 0)
  })
})

describe('calculateRiskLevel', () => {
  it('should return low for low likelihood and low impact', () => {
    const result = calculateRiskLevel('low', 'low')
    expect(result.level).toBe('low')
    expect(result.score).toBe(10)
  })

  it('should return very_high for high likelihood and high impact', () => {
    const result = calculateRiskLevel('high', 'high')
    expect(result.level).toBe('very_high')
    expect(result.score).toBe(90)
  })

  it('should return medium for medium likelihood and medium impact', () => {
    const result = calculateRiskLevel('medium', 'medium')
    expect(result.level).toBe('medium')
    expect(result.score).toBe(50)
  })

  it('should return high for high likelihood and medium impact', () => {
    const result = calculateRiskLevel('high', 'medium')
    expect(result.level).toBe('high')
    expect(result.score).toBe(70)
  })

  it('should return medium for low likelihood and high impact', () => {
    const result = calculateRiskLevel('low', 'high')
    expect(result.level).toBe('medium')
    expect(result.score).toBe(40)
  })
})

describe('DSFARisk type', () => {
  it('should accept valid risk data', () => {
    const risk: DSFARisk = {
      id: 'risk-001',
      category: 'confidentiality',
      description: 'Unauthorized access to personal data',
      likelihood: 'medium',
      impact: 'high',
      risk_level: 'high',
      affected_data: ['customer_data', 'financial_data'],
    }

    expect(risk.id).toBe('risk-001')
    expect(risk.category).toBe('confidentiality')
    expect(risk.likelihood).toBe('medium')
    expect(risk.impact).toBe('high')
  })
})

describe('DSFAMitigation type', () => {
  it('should accept valid mitigation data', () => {
    const mitigation: DSFAMitigation = {
      id: 'mit-001',
      risk_id: 'risk-001',
      description: 'Implement encryption at rest',
      type: 'technical',
      status: 'implemented',
      residual_risk: 'low',
      responsible_party: 'IT Security Team',
    }

    expect(mitigation.id).toBe('mit-001')
    expect(mitigation.type).toBe('technical')
    expect(mitigation.status).toBe('implemented')
  })
})

describe('DSFASectionProgress type', () => {
  it('should track completion for all 9 sections', () => {
    const progress: DSFASectionProgress = {
      section_0_complete: false,
      section_1_complete: true,
      section_2_complete: true,
      section_3_complete: false,
      section_4_complete: false,
      section_5_complete: false,
      section_6_complete: false,
      section_7_complete: false,
      section_8_complete: false,
    }

    expect(progress.section_1_complete).toBe(true)
    expect(progress.section_2_complete).toBe(true)
    expect(progress.section_3_complete).toBe(false)
  })
})

describe('DSFA type', () => {
  it('should accept a complete DSFA object', () => {
    const dsfa: DSFA = {
      id: 'dsfa-001',
      version: 1,
      tenant_id: 'tenant-001',
      name: 'AI Chatbot DSFA',
      description: 'Data Protection Impact Assessment for AI Chatbot',
      processing_description: 'Automated customer service using AI',
      processing_purpose: 'Customer support automation',
      data_categories: ['contact_data', 'inquiry_content'],
      data_subjects: ['customers'],
      recipients: ['internal_staff'],
      legal_basis: 'legitimate_interest',
      necessity_assessment: 'Required for efficient customer service',
      proportionality_assessment: 'Minimal data processing for the purpose',
      risks: [],
      overall_risk_level: 'medium',
      risk_score: 50,
      mitigations: [],
      dpo_consulted: false,
      authority_consulted: false,
      status: 'draft',
      section_progress: {
        section_0_complete: false,
        section_1_complete: true,
        section_2_complete: true,
        section_3_complete: false,
        section_4_complete: false,
        section_5_complete: false,
        section_6_complete: false,
        section_7_complete: false,
        section_8_complete: false,
      },
      conclusion: '',
      created_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
      created_by: 'user-001',
    }

    expect(dsfa.id).toBe('dsfa-001')
    expect(dsfa.name).toBe('AI Chatbot DSFA')
    expect(dsfa.status).toBe('draft')
    expect(dsfa.data_categories).toHaveLength(2)
  })
})
