/**
 * DependencyMap Component Tests
 *
 * Tests fuer die Control-Requirement Mapping Visualisierung
 */

import { describe, it, expect, vi } from 'vitest'
import { render, screen, fireEvent } from '@testing-library/react'
import DependencyMap from '../../components/compliance/charts/DependencyMap'

// Mock-Daten
const mockRequirements = [
  {
    id: 'req-1',
    article: 'Art. 32',
    title: 'Sicherheit der Verarbeitung',
    regulation_code: 'GDPR',
  },
  {
    id: 'req-2',
    article: 'Art. 9',
    title: 'Risikomanagement',
    regulation_code: 'AIACT',
  },
  {
    id: 'req-3',
    article: 'Art. 25',
    title: 'Datenschutz durch Technikgestaltung',
    regulation_code: 'GDPR',
  },
]

const mockControls = [
  {
    id: 'ctrl-1',
    control_id: 'PRIV-001',
    title: 'Verarbeitungsverzeichnis',
    domain: 'priv',
    status: 'pass',
  },
  {
    id: 'ctrl-2',
    control_id: 'CRYPTO-001',
    title: 'Verschluesselung',
    domain: 'crypto',
    status: 'pass',
  },
  {
    id: 'ctrl-3',
    control_id: 'AI-001',
    title: 'KI-Risikobewertung',
    domain: 'ai',
    status: 'partial',
  },
]

const mockMappings = [
  { requirement_id: 'req-1', control_id: 'PRIV-001', coverage_level: 'full' as const },
  { requirement_id: 'req-1', control_id: 'CRYPTO-001', coverage_level: 'partial' as const },
  { requirement_id: 'req-2', control_id: 'AI-001', coverage_level: 'full' as const },
  { requirement_id: 'req-3', control_id: 'PRIV-001', coverage_level: 'planned' as const },
]

describe('DependencyMap', () => {
  it('should render the component with data', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    // Statistik-Header sollte sichtbar sein
    expect(screen.getByText('Abdeckung')).toBeInTheDocument()
    expect(screen.getByText('Vollstaendig')).toBeInTheDocument()
    expect(screen.getByText('Teilweise')).toBeInTheDocument()
    expect(screen.getByText('Geplant')).toBeInTheDocument()
  })

  it('should render empty state when no data', () => {
    render(
      <DependencyMap
        requirements={[]}
        controls={[]}
        mappings={[]}
      />
    )

    expect(screen.getByText(/Keine Mappings vorhanden/i)).toBeInTheDocument()
  })

  it('should show correct coverage statistics', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    // 2 full, 1 partial, 1 planned
    expect(screen.getByText('2')).toBeInTheDocument() // full mappings
    expect(screen.getByText('1')).toBeInTheDocument() // partial/planned mappings
  })

  it('should display control IDs in matrix header', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    expect(screen.getByText('PRIV-001')).toBeInTheDocument()
    expect(screen.getByText('CRYPTO-001')).toBeInTheDocument()
    expect(screen.getByText('AI-001')).toBeInTheDocument()
  })

  it('should display requirement articles', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    expect(screen.getByText(/GDPR Art. 32/i)).toBeInTheDocument()
    expect(screen.getByText(/AIACT Art. 9/i)).toBeInTheDocument()
  })

  it('should support German language', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
        lang="de"
      />
    )

    expect(screen.getByText('Alle Verordnungen')).toBeInTheDocument()
    expect(screen.getByText('Alle Domains')).toBeInTheDocument()
  })

  it('should support English language', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
        lang="en"
      />
    )

    expect(screen.getByText('All Regulations')).toBeInTheDocument()
    expect(screen.getByText('All Domains')).toBeInTheDocument()
    expect(screen.getByText('Coverage')).toBeInTheDocument()
  })

  it('should call onControlClick when control is clicked', () => {
    const onControlClick = vi.fn()
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
        onControlClick={onControlClick}
      />
    )

    const controlHeader = screen.getByText('PRIV-001')
    fireEvent.click(controlHeader)

    expect(onControlClick).toHaveBeenCalledWith(mockControls[0])
  })

  it('should call onRequirementClick when requirement is clicked', () => {
    const onRequirementClick = vi.fn()
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
        onRequirementClick={onRequirementClick}
      />
    )

    // Finde den Requirement-Text
    const reqElement = screen.getByText(/Sicherheit der Verarbeitung/i)
    fireEvent.click(reqElement.closest('div[class*="cursor-pointer"]')!)

    expect(onRequirementClick).toHaveBeenCalledWith(mockRequirements[0])
  })

  it('should filter by regulation', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    const regSelect = screen.getByDisplayValue('Alle Verordnungen')
    fireEvent.change(regSelect, { target: { value: 'AIACT' } })

    // Nur AIACT Requirements sollten sichtbar sein
    expect(screen.queryByText(/GDPR Art. 32/i)).not.toBeInTheDocument()
    expect(screen.getByText(/AIACT Art. 9/i)).toBeInTheDocument()
  })

  it('should filter by domain', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    const domainSelect = screen.getByDisplayValue('Alle Domains')
    fireEvent.change(domainSelect, { target: { value: 'priv' } })

    // Nur Privacy Controls sollten sichtbar sein
    expect(screen.getByText('PRIV-001')).toBeInTheDocument()
    expect(screen.queryByText('CRYPTO-001')).not.toBeInTheDocument()
  })

  it('should switch between matrix and connection view', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    // Standard ist Matrix-Ansicht
    expect(screen.getByText('Matrix')).toBeInTheDocument()

    // Wechsle zu Verbindungs-Ansicht
    fireEvent.click(screen.getByText('Verbindungen'))

    // Connection-View Text sollte erscheinen
    expect(screen.getByText(/Waehlen Sie ein Control/i)).toBeInTheDocument()
  })

  it('should highlight connected items when control is selected', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    // Klicke auf einen Control
    fireEvent.click(screen.getByText('PRIV-001'))

    // Der Control sollte highlighted sein (bg-primary-100 Klasse)
    const controlElement = screen.getByText('PRIV-001').closest('div')
    expect(controlElement?.className).toContain('bg-primary-100')
  })

  it('should show legend with coverage levels', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    expect(screen.getByText('Vollstaendig abgedeckt')).toBeInTheDocument()
    expect(screen.getByText('Teilweise abgedeckt')).toBeInTheDocument()
    expect(screen.getByText('Geplant')).toBeInTheDocument()
  })

  it('should calculate coverage percentage correctly', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    // 3 von 3 Requirements haben mindestens ein Mapping = 100%
    expect(screen.getByText('100.0%')).toBeInTheDocument()
  })

  it('should show control counts in connection view', () => {
    render(
      <DependencyMap
        requirements={mockRequirements}
        controls={mockControls}
        mappings={mockMappings}
      />
    )

    // Wechsle zu Verbindungs-Ansicht
    fireEvent.click(screen.getByText('Verbindungen'))

    // PRIV-001 hat 2 Verbindungen
    const privControl = screen.getAllByText('PRIV-001')[0].closest('button')
    expect(privControl?.textContent).toContain('2')
  })
})
