'use client' import React, { useState, useCallback } from 'react' import type { ScopeDecision, ScopeProfilingAnswer } from '@/lib/sdk/compliance-scope-types' import { DEPTH_LEVEL_LABELS, DOCUMENT_TYPE_LABELS } from '@/lib/sdk/compliance-scope-types' interface ScopeExportTabProps { decision?: ScopeDecision | null answers?: ScopeProfilingAnswer[] scopeState?: { decision: ScopeDecision | null; answers: ScopeProfilingAnswer[] } onBackToDecision?: () => void } export function ScopeExportTab({ decision: decisionProp, answers: answersProp, scopeState, onBackToDecision }: ScopeExportTabProps) { const decision = decisionProp ?? scopeState?.decision ?? null const answers = answersProp ?? scopeState?.answers ?? [] // onBackToDecision is accepted but not used in this component (navigation handled by parent) const [copiedMarkdown, setCopiedMarkdown] = useState(false) const handleDownloadJSON = useCallback(() => { if (!decision) return const dataStr = JSON.stringify(decision, null, 2) const dataBlob = new Blob([dataStr], { type: 'application/json' }) const url = URL.createObjectURL(dataBlob) const link = document.createElement('a') link.href = url link.download = `compliance-scope-decision-${new Date().toISOString().split('T')[0]}.json` link.click() URL.revokeObjectURL(url) }, [decision]) const handleDownloadCSV = useCallback(() => { if (!decision || !decision.requiredDocuments) return const headers = ['Typ', 'Priorität', 'Aufwand (Stunden)', 'Pflicht', 'Hard-Trigger'] const rows = decision.requiredDocuments.map((doc) => [ DOCUMENT_TYPE_LABELS[doc.documentType] || doc.documentType, doc.priority, String(doc.estimatedEffort || 0), doc.requirement === 'mandatory' ? 'Ja' : 'Nein', doc.triggeredBy.length > 0 ? 'Ja' : 'Nein', ]) const csvContent = [headers, ...rows].map((row) => row.map((cell) => `"${cell}"`).join(',')).join('\n') const dataBlob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }) const url = URL.createObjectURL(dataBlob) const link = document.createElement('a') link.href = url link.download = `compliance-scope-documents-${new Date().toISOString().split('T')[0]}.csv` link.click() URL.revokeObjectURL(url) }, [decision]) const generateMarkdownSummary = useCallback(() => { if (!decision) return '' let markdown = `# Compliance Scope Entscheidung\n\n` markdown += `**Datum:** ${new Date().toLocaleDateString('de-DE')}\n\n` markdown += `## Einstufung\n\n` markdown += `**Level:** ${decision.determinedLevel} - ${DEPTH_LEVEL_LABELS[decision.determinedLevel]}\n\n` if (decision.reasoning && decision.reasoning.length > 0) { markdown += `**Begründung:** ${decision.reasoning.map(r => r.description).filter(Boolean).join('. ')}\n\n` } if (decision.scores) { markdown += `## Scores\n\n` markdown += `- **Risiko-Score:** ${decision.scores.risk_score}/100\n` markdown += `- **Komplexitäts-Score:** ${decision.scores.complexity_score}/100\n` markdown += `- **Assurance-Score:** ${decision.scores.assurance_need}/100\n` markdown += `- **Gesamt-Score:** ${decision.scores.composite_score}/100\n\n` } if (decision.triggeredHardTriggers && decision.triggeredHardTriggers.length > 0) { markdown += `## Aktive Hard-Trigger\n\n` decision.triggeredHardTriggers.forEach((trigger) => { markdown += `- **${trigger.description}**\n` markdown += ` - ${trigger.description}\n` if (trigger.legalReference) { markdown += ` - Rechtsgrundlage: ${trigger.legalReference}\n` } }) markdown += `\n` } if (decision.requiredDocuments && decision.requiredDocuments.length > 0) { markdown += `## Erforderliche Dokumente\n\n` markdown += `| Typ | Priorität | Aufwand (h) | Pflicht | Hard-Trigger |\n` markdown += `|-----|-----------|-------------|---------|-------------|\n` decision.requiredDocuments.forEach((doc) => { markdown += `| ${DOCUMENT_TYPE_LABELS[doc.documentType] || doc.documentType} | ${doc.priority} | ${ doc.estimatedEffort || 0 } | ${doc.requirement === 'mandatory' ? 'Ja' : 'Nein'} | ${doc.triggeredBy.length > 0 ? 'Ja' : 'Nein'} |\n` }) markdown += `\n` } if (decision.riskFlags && decision.riskFlags.length > 0) { markdown += `## Risiko-Flags\n\n` decision.riskFlags.forEach((flag) => { markdown += `### ${flag.message} (${flag.severity})\n\n` if (flag.legalReference) markdown += `Rechtsgrundlage: ${flag.legalReference}\n\n` markdown += `**Empfehlung:** ${flag.recommendation}\n\n` }) } if (decision.gaps && decision.gaps.length > 0) { markdown += `## Gap-Analyse\n\n` decision.gaps.forEach((gap) => { markdown += `### ${gap.description} (${gap.severity})\n\n` markdown += `- **Ist:** ${gap.currentState}\n` markdown += `- **Soll:** ${gap.targetState}\n` markdown += `- **Aufwand:** ~${gap.effort}h\n\n` }) } if (decision.nextActions && decision.nextActions.length > 0) { markdown += `## Nächste Schritte\n\n` decision.nextActions.forEach((action, idx) => { markdown += `${idx + 1}. **${action.title}**\n` markdown += ` ${action.description}\n` if (action.estimatedEffort) { markdown += ` Aufwand: ~${action.estimatedEffort}h\n` } markdown += `\n` }) } return markdown }, [decision]) const handleCopyMarkdown = useCallback(() => { const markdown = generateMarkdownSummary() navigator.clipboard.writeText(markdown).then(() => { setCopiedMarkdown(true) setTimeout(() => setCopiedMarkdown(false), 2000) }) }, [generateMarkdownSummary]) /** Simple markdown-to-HTML converter for print view */ const markdownToHtml = useCallback((md: string): string => { let html = md // Escape HTML entities .replace(/&/g, '&') .replace(//g, '>') // Headers html = html.replace(/^### (.+)$/gm, '

$1

') html = html.replace(/^## (.+)$/gm, '

$1

') html = html.replace(/^# (.+)$/gm, '

$1

') // Bold html = html.replace(/\*\*(.+?)\*\*/g, '$1') // Tables const lines = html.split('\n') let inTable = false const result: string[] = [] for (const line of lines) { if (line.trim().startsWith('|') && line.trim().endsWith('|')) { if (line.includes('---')) continue // separator row const cells = line.split('|').filter(c => c.trim() !== '') if (!inTable) { result.push('') cells.forEach(c => result.push(``)) result.push('') inTable = true } else { result.push('') cells.forEach(c => result.push(``)) result.push('') } } else { if (inTable) { result.push('
${c.trim()}
${c.trim()}
') inTable = false } // List items if (line.trim().startsWith('- ')) { result.push(`
  • ${line.trim().slice(2)}
  • `) } else if (/^\d+\.\s/.test(line.trim())) { result.push(`
  • ${line.trim().replace(/^\d+\.\s/, '')}
  • `) } else if (line.trim() === '') { result.push('
    ') } else { result.push(`

    ${line}

    `) } } } if (inTable) result.push('') return result.join('\n') }, []) const handlePrintView = useCallback(() => { if (!decision) return const markdown = generateMarkdownSummary() const renderedHtml = markdownToHtml(markdown) const htmlContent = ` Compliance Scope Entscheidung ${renderedHtml} ` const printWindow = window.open('', '_blank') if (printWindow) { printWindow.document.write(htmlContent) printWindow.document.close() printWindow.focus() setTimeout(() => printWindow.print(), 250) } }, [decision, generateMarkdownSummary, markdownToHtml]) if (!decision) { return (

    Keine Daten zum Export

    Bitte führen Sie zuerst das Scope-Profiling durch.

    ) } return (
    {/* JSON Export */}

    JSON Export

    Exportieren Sie die vollständige Entscheidung als strukturierte JSON-Datei für weitere Verarbeitung oder Archivierung.

    {/* CSV Export */}

    CSV Export

    Exportieren Sie die Liste der erforderlichen Dokumente als CSV-Datei für Excel, Google Sheets oder andere Tabellenkalkulationen.

    {/* Markdown Summary */}

    Markdown-Zusammenfassung

    Strukturierte Zusammenfassung im Markdown-Format für Dokumentation oder Berichte.