"""
BreakPilot Studio - Security Dashboard Module

DevSecOps Dashboard fuer Entwickler, Security-Experten und Ops:

Features fuer Developer:
- Scan-Ergebnisse auf einen Blick
- Pre-commit Hook Status
- Code Quality Metriken
- Quick-Fix Suggestions

Features fuer Security:
- Vulnerability Severity Distribution
- CVE-Tracking und Trends
- SBOM-Viewer
- Compliance-Status (OWASP Top 10)
- Secrets Detection History

Features fuer Ops:
- Container Image Scan Results
- Dependency Update Status
- Security Scan Scheduling
- CI/CD Pipeline Integration Status
- Runtime Security Alerts (Falco)
"""


class SecurityModule:
    """DevSecOps Security Dashboard Modul."""

    @staticmethod
    def get_css() -> str:
        """CSS fuer das Security Dashboard."""
        return """
/* =============================================
   SECURITY DASHBOARD MODULE - DevSecOps
   ============================================= */

.panel-security {
  display: none;
  flex-direction: column;
  height: 100%;
  background: var(--bp-bg);
  overflow-y: auto;
}

.panel-security.active {
  display: flex;
}

/* Security Header */
.security-header {
  padding: 24px 32px;
  background: var(--bp-surface);
  border-bottom: 1px solid var(--bp-border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.security-header h2 {
  font-size: 24px;
  font-weight: 600;
  color: var(--bp-text);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}

.security-header-icon {
  font-size: 28px;
}

.security-header-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.security-status-badge {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 600;
}

.security-status-badge.secure {
  background: rgba(34, 197, 94, 0.15);
  color: #22c55e;
}

.security-status-badge.warning {
  background: rgba(245, 158, 11, 0.15);
  color: #f59e0b;
}

.security-status-badge.critical {
  background: rgba(239, 68, 68, 0.15);
  color: #ef4444;
}

/* Security Tabs */
.security-tabs {
  display: flex;
  gap: 4px;
  padding: 16px 32px;
  background: var(--bp-surface);
  border-bottom: 1px solid var(--bp-border);
  flex-wrap: wrap;
}

.security-tab {
  padding: 10px 20px;
  border: none;
  background: transparent;
  color: var(--bp-text-muted);
  font-size: 14px;
  font-weight: 500;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
  display: flex;
  align-items: center;
  gap: 8px;
}

.security-tab:hover {
  background: var(--bp-bg);
  color: var(--bp-text);
}

.security-tab.active {
  background: var(--bp-primary);
  color: white;
}

.security-tab-badge {
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.2);
}

.security-tab.active .security-tab-badge {
  background: rgba(255, 255, 255, 0.3);
}

/* Security Content */
.security-content {
  padding: 24px 32px;
  flex: 1;
}

/* Security Summary Cards */
.security-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.security-summary-card {
  background: var(--bp-surface);
  border: 1px solid var(--bp-border);
  border-radius: 12px;
  padding: 20px;
  transition: all 0.2s;
}

.security-summary-card:hover {
  border-color: var(--bp-primary);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.security-summary-card.critical {
  border-left: 4px solid #ef4444;
}

.security-summary-card.high {
  border-left: 4px solid #f97316;
}

.security-summary-card.medium {
  border-left: 4px solid #f59e0b;
}

.security-summary-card.low {
  border-left: 4px solid #22c55e;
}

.security-summary-card.info {
  border-left: 4px solid #3b82f6;
}

.security-summary-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.security-summary-count {
  font-size: 36px;
  font-weight: 700;
  margin-bottom: 4px;
}

.security-summary-card.critical .security-summary-count { color: #ef4444; }
.security-summary-card.high .security-summary-count { color: #f97316; }
.security-summary-card.medium .security-summary-count { color: #f59e0b; }
.security-summary-card.low .security-summary-count { color: #22c55e; }
.security-summary-card.info .security-summary-count { color: #3b82f6; }

.security-summary-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--bp-text);
}

.security-summary-sublabel {
  font-size: 11px;
  color: var(--bp-text-muted);
  margin-top: 4px;
}

/* Tool Status Section */
.security-tools-section {
  margin-bottom: 24px;
}

.security-section-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--bp-text);
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.security-tools-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}

.security-tool-card {
  background: var(--bp-surface);
  border: 1px solid var(--bp-border);
  border-radius: 12px;
  padding: 20px;
}

.security-tool-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.security-tool-name {
  font-size: 16px;
  font-weight: 600;
  color: var(--bp-text);
  display: flex;
  align-items: center;
  gap: 8px;
}

.security-tool-status {
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
}

.security-tool-status.installed {
  background: rgba(34, 197, 94, 0.15);
  color: #22c55e;
}

.security-tool-status.not-installed {
  background: rgba(239, 68, 68, 0.15);
  color: #ef4444;
}

.security-tool-status.running {
  background: rgba(59, 130, 246, 0.15);
  color: #3b82f6;
}

.security-tool-description {
  font-size: 13px;
  color: var(--bp-text-muted);
  margin-bottom: 12px;
  line-height: 1.5;
}

.security-tool-meta {
  display: flex;
  gap: 16px;
  font-size: 12px;
  color: var(--bp-text-muted);
}

.security-tool-meta-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.security-tool-actions {
  margin-top: 12px;
  display: flex;
  gap: 8px;
}

.security-tool-btn {
  padding: 8px 16px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  border: none;
  cursor: pointer;
  transition: all 0.2s;
}

.security-tool-btn.primary {
  background: var(--bp-primary);
  color: white;
}

.security-tool-btn.primary:hover {
  background: var(--bp-primary-hover);
}

.security-tool-btn.secondary {
  background: var(--bp-surface-elevated);
  color: var(--bp-text);
  border: 1px solid var(--bp-border);
}

.security-tool-btn.secondary:hover {
  background: var(--bp-bg);
}

/* Findings Table */
.security-findings-container {
  background: var(--bp-surface);
  border: 1px solid var(--bp-border);
  border-radius: 12px;
  overflow: hidden;
}

.security-findings-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--bp-border);
}

.security-findings-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--bp-text);
}

.security-findings-filter {
  display: flex;
  gap: 8px;
}

.security-filter-btn {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  border: 1px solid var(--bp-border);
  background: transparent;
  color: var(--bp-text-muted);
  cursor: pointer;
  transition: all 0.2s;
}

.security-filter-btn:hover,
.security-filter-btn.active {
  background: var(--bp-primary);
  color: white;
  border-color: var(--bp-primary);
}

.security-findings-table {
  width: 100%;
  border-collapse: collapse;
}

.security-findings-table th,
.security-findings-table td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid var(--bp-border);
}

.security-findings-table th {
  background: var(--bp-surface-elevated);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--bp-text-muted);
}

.security-findings-table td {
  font-size: 13px;
  color: var(--bp-text);
}

.security-findings-table tr:hover {
  background: var(--bp-bg);
}

.severity-badge {
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
}

.severity-badge.critical {
  background: rgba(239, 68, 68, 0.15);
  color: #ef4444;
}

.severity-badge.high {
  background: rgba(249, 115, 22, 0.15);
  color: #f97316;
}

.severity-badge.medium {
  background: rgba(245, 158, 11, 0.15);
  color: #f59e0b;
}

.severity-badge.low {
  background: rgba(34, 197, 94, 0.15);
  color: #22c55e;
}

.severity-badge.info {
  background: rgba(59, 130, 246, 0.15);
  color: #3b82f6;
}

/* SBOM Viewer */
.sbom-container {
  background: var(--bp-surface);
  border: 1px solid var(--bp-border);
  border-radius: 12px;
  overflow: hidden;
}

.sbom-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--bp-border);
}

.sbom-search {
  padding: 8px 16px;
  border-radius: 8px;
  border: 1px solid var(--bp-border);
  background: var(--bp-surface-elevated);
  color: var(--bp-text);
  font-size: 13px;
  width: 300px;
}

.sbom-stats {
  display: flex;
  gap: 24px;
  padding: 16px 20px;
  background: var(--bp-bg);
  border-bottom: 1px solid var(--bp-border);
}

.sbom-stat {
  text-align: center;
}

.sbom-stat-value {
  font-size: 24px;
  font-weight: 700;
  color: var(--bp-primary);
}

.sbom-stat-label {
  font-size: 12px;
  color: var(--bp-text-muted);
}

/* Timeline / History */
.security-timeline {
  padding: 20px;
}

.security-timeline-item {
  display: flex;
  gap: 16px;
  padding-bottom: 20px;
  border-left: 2px solid var(--bp-border);
  margin-left: 8px;
  padding-left: 20px;
  position: relative;
}

.security-timeline-item::before {
  content: '';
  position: absolute;
  left: -6px;
  top: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--bp-primary);
}

.security-timeline-item.success::before {
  background: #22c55e;
}

.security-timeline-item.warning::before {
  background: #f59e0b;
}

.security-timeline-item.error::before {
  background: #ef4444;
}

.security-timeline-time {
  font-size: 12px;
  color: var(--bp-text-muted);
  min-width: 100px;
}

.security-timeline-content {
  flex: 1;
}

.security-timeline-title {
  font-size: 14px;
  font-weight: 500;
  color: var(--bp-text);
}

.security-timeline-desc {
  font-size: 13px;
  color: var(--bp-text-muted);
  margin-top: 4px;
}

/* Loading Spinner */
.security-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px;
  color: var(--bp-text-muted);
}

.security-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid var(--bp-border);
  border-top-color: var(--bp-primary);
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Empty State */
.security-empty {
  text-align: center;
  padding: 60px 20px;
  color: var(--bp-text-muted);
}

.security-empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.security-empty-title {
  font-size: 18px;
  font-weight: 600;
  color: var(--bp-text);
  margin-bottom: 8px;
}

.security-empty-desc {
  font-size: 14px;
  max-width: 400px;
  margin: 0 auto;
}

/* Scan Progress */
.security-scan-progress {
  background: var(--bp-surface);
  border: 1px solid var(--bp-border);
  border-radius: 12px;
  padding: 20px;
  margin-bottom: 24px;
}

.security-scan-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.security-scan-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--bp-text);
}

.security-scan-percentage {
  font-size: 14px;
  font-weight: 600;
  color: var(--bp-primary);
}

.security-progress-bar {
  height: 8px;
  background: var(--bp-bg);
  border-radius: 4px;
  overflow: hidden;
}

.security-progress-fill {
  height: 100%;
  background: var(--bp-primary);
  border-radius: 4px;
  transition: width 0.3s ease;
}

.security-scan-steps {
  display: flex;
  justify-content: space-between;
  margin-top: 12px;
  font-size: 12px;
  color: var(--bp-text-muted);
}

.security-scan-step {
  display: flex;
  align-items: center;
  gap: 4px;
}

.security-scan-step.completed {
  color: #22c55e;
}

.security-scan-step.active {
  color: var(--bp-primary);
}

/* Auto-refresh indicator */
.security-auto-refresh {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--bp-text-muted);
}

.security-auto-refresh-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #22c55e;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* Responsive */
@media (max-width: 768px) {
  .security-header {
    flex-direction: column;
    gap: 16px;
    align-items: flex-start;
  }

  .security-summary-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .security-tools-grid {
    grid-template-columns: 1fr;
  }

  .security-tabs {
    padding: 12px 16px;
  }

  .security-tab {
    padding: 8px 12px;
    font-size: 12px;
  }
}
"""

    @staticmethod
    def get_html() -> str:
        """HTML-Struktur fuer das Security Dashboard."""
        return """
<!-- SECURITY DASHBOARD PANEL -->
<div class="panel-security" id="panel-security">
  <!-- Header -->
  <div class="security-header">
    <h2>
      <span class="security-header-icon">&#128737;</span>
      Security Dashboard
    </h2>
    <div class="security-header-actions">
      <div class="security-auto-refresh" id="security-auto-refresh">
        <span class="security-auto-refresh-dot"></span>
        <span>Auto-Refresh aktiv</span>
      </div>
      <span class="security-status-badge secure" id="security-overall-status">
        <span>&#10003;</span> Sicher
      </span>
      <button class="btn btn-primary" onclick="SecurityDashboard.runFullScan()">
        <span>&#9654;</span> Scan starten
      </button>
    </div>
  </div>

  <!-- Tabs -->
  <div class="security-tabs">
    <button class="security-tab active" data-tab="overview" onclick="SecurityDashboard.switchTab('overview')">
      <span>&#128200;</span> Uebersicht
    </button>
    <button class="security-tab" data-tab="secrets" onclick="SecurityDashboard.switchTab('secrets')">
      <span>&#128273;</span> Secrets
      <span class="security-tab-badge" id="secrets-count">0</span>
    </button>
    <button class="security-tab" data-tab="vulnerabilities" onclick="SecurityDashboard.switchTab('vulnerabilities')">
      <span>&#128030;</span> Schwachstellen
      <span class="security-tab-badge" id="vuln-count">0</span>
    </button>
    <button class="security-tab" data-tab="sbom" onclick="SecurityDashboard.switchTab('sbom')">
      <span>&#128230;</span> SBOM
    </button>
    <button class="security-tab" data-tab="containers" onclick="SecurityDashboard.switchTab('containers')">
      <span>&#128230;</span> Container
    </button>
    <button class="security-tab" data-tab="compliance" onclick="SecurityDashboard.switchTab('compliance')">
      <span>&#9989;</span> Compliance
    </button>
    <button class="security-tab" data-tab="history" onclick="SecurityDashboard.switchTab('history')">
      <span>&#128197;</span> Historie
    </button>
  </div>

  <!-- Content -->
  <div class="security-content">
    <!-- Scan Progress (hidden by default) -->
    <div class="security-scan-progress hidden" id="security-scan-progress">
      <div class="security-scan-header">
        <span class="security-scan-title">Security Scan laeuft...</span>
        <span class="security-scan-percentage" id="scan-percentage">0%</span>
      </div>
      <div class="security-progress-bar">
        <div class="security-progress-fill" id="scan-progress-fill" style="width: 0%"></div>
      </div>
      <div class="security-scan-steps">
        <span class="security-scan-step" id="step-secrets">&#128273; Secrets</span>
        <span class="security-scan-step" id="step-sast">&#128270; SAST</span>
        <span class="security-scan-step" id="step-deps">&#128230; Dependencies</span>
        <span class="security-scan-step" id="step-containers">&#128736; Container</span>
        <span class="security-scan-step" id="step-sbom">&#128203; SBOM</span>
      </div>
    </div>

    <!-- Tab: Overview -->
    <div class="security-tab-content" id="tab-overview">
      <!-- Summary Cards -->
      <div class="security-summary-grid" id="security-summary">
        <div class="security-summary-card critical">
          <div class="security-summary-icon">&#128680;</div>
          <div class="security-summary-count" id="critical-count">0</div>
          <div class="security-summary-label">Critical</div>
          <div class="security-summary-sublabel">Sofort beheben</div>
        </div>
        <div class="security-summary-card high">
          <div class="security-summary-icon">&#9888;</div>
          <div class="security-summary-count" id="high-count">0</div>
          <div class="security-summary-label">High</div>
          <div class="security-summary-sublabel">Hohe Prioritaet</div>
        </div>
        <div class="security-summary-card medium">
          <div class="security-summary-icon">&#128993;</div>
          <div class="security-summary-count" id="medium-count">0</div>
          <div class="security-summary-label">Medium</div>
          <div class="security-summary-sublabel">Bald beheben</div>
        </div>
        <div class="security-summary-card low">
          <div class="security-summary-icon">&#128994;</div>
          <div class="security-summary-count" id="low-count">0</div>
          <div class="security-summary-label">Low</div>
          <div class="security-summary-sublabel">Bei Gelegenheit</div>
        </div>
        <div class="security-summary-card info">
          <div class="security-summary-icon">&#128712;</div>
          <div class="security-summary-count" id="info-count">0</div>
          <div class="security-summary-label">Info</div>
          <div class="security-summary-sublabel">Zur Kenntnis</div>
        </div>
      </div>

      <!-- Tools Status -->
      <div class="security-tools-section">
        <div class="security-section-title">
          <span>&#128295;</span> DevSecOps Tools
        </div>
        <div class="security-tools-grid" id="security-tools-grid">
          <!-- Wird dynamisch gefuellt -->
        </div>
      </div>

      <!-- Recent Findings -->
      <div class="security-section-title">
        <span>&#128269;</span> Aktuelle Findings
      </div>
      <div class="security-findings-container">
        <div class="security-findings-header">
          <span class="security-findings-title">Letzte Scan-Ergebnisse</span>
          <div class="security-findings-filter">
            <button class="security-filter-btn active" data-filter="all">Alle</button>
            <button class="security-filter-btn" data-filter="critical">Critical</button>
            <button class="security-filter-btn" data-filter="high">High</button>
            <button class="security-filter-btn" data-filter="new">Neu</button>
          </div>
        </div>
        <table class="security-findings-table">
          <thead>
            <tr>
              <th>Severity</th>
              <th>Tool</th>
              <th>Finding</th>
              <th>Datei</th>
              <th>Gefunden</th>
            </tr>
          </thead>
          <tbody id="security-findings-body">
            <!-- Wird dynamisch gefuellt -->
          </tbody>
        </table>
      </div>
    </div>

    <!-- Tab: Secrets -->
    <div class="security-tab-content hidden" id="tab-secrets">
      <div class="security-section-title">
        <span>&#128273;</span> Secrets Detection (Gitleaks)
      </div>
      <div class="security-findings-container">
        <div class="security-findings-header">
          <span class="security-findings-title">Erkannte Secrets</span>
          <button class="btn btn-sm btn-primary" onclick="SecurityDashboard.runSecretsScan()">
            Secrets-Scan starten
          </button>
        </div>
        <div id="secrets-content">
          <div class="security-empty">
            <div class="security-empty-icon">&#128274;</div>
            <div class="security-empty-title">Keine Secrets gefunden</div>
            <div class="security-empty-desc">
              Gitleaks hat keine hartkodierten Secrets im Codebase gefunden.
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- Tab: Vulnerabilities -->
    <div class="security-tab-content hidden" id="tab-vulnerabilities">
      <div class="security-section-title">
        <span>&#128030;</span> Schwachstellen (Trivy / Grype)
      </div>
      <div class="security-findings-container">
        <div class="security-findings-header">
          <span class="security-findings-title">CVE-Uebersicht</span>
          <div class="security-findings-filter">
            <button class="security-filter-btn active" data-filter="all">Alle</button>
            <button class="security-filter-btn" data-filter="fixable">Behebbar</button>
            <button class="security-filter-btn" data-filter="no-fix">Kein Fix</button>
          </div>
        </div>
        <table class="security-findings-table">
          <thead>
            <tr>
              <th>CVE-ID</th>
              <th>Severity</th>
              <th>Package</th>
              <th>Version</th>
              <th>Fix verfuegbar</th>
            </tr>
          </thead>
          <tbody id="vuln-findings-body">
            <!-- Wird dynamisch gefuellt -->
          </tbody>
        </table>
      </div>
    </div>

    <!-- Tab: SBOM -->
    <div class="security-tab-content hidden" id="tab-sbom">
      <div class="security-section-title">
        <span>&#128230;</span> Software Bill of Materials (Syft)
      </div>
      <div class="sbom-container">
        <div class="sbom-header">
          <span class="security-findings-title">SBOM Viewer</span>
          <input type="text" class="sbom-search" placeholder="Package suchen..." id="sbom-search" onkeyup="SecurityDashboard.filterSBOM()">
        </div>
        <div class="sbom-stats">
          <div class="sbom-stat">
            <div class="sbom-stat-value" id="sbom-total">0</div>
            <div class="sbom-stat-label">Packages gesamt</div>
          </div>
          <div class="sbom-stat">
            <div class="sbom-stat-value" id="sbom-python">0</div>
            <div class="sbom-stat-label">Python</div>
          </div>
          <div class="sbom-stat">
            <div class="sbom-stat-value" id="sbom-go">0</div>
            <div class="sbom-stat-label">Go</div>
          </div>
          <div class="sbom-stat">
            <div class="sbom-stat-value" id="sbom-npm">0</div>
            <div class="sbom-stat-label">NPM</div>
          </div>
        </div>
        <table class="security-findings-table">
          <thead>
            <tr>
              <th>Package</th>
              <th>Version</th>
              <th>Typ</th>
              <th>Lizenz</th>
            </tr>
          </thead>
          <tbody id="sbom-body">
            <!-- Wird dynamisch gefuellt -->
          </tbody>
        </table>
      </div>
    </div>

    <!-- Tab: Containers -->
    <div class="security-tab-content hidden" id="tab-containers">
      <div class="security-section-title">
        <span>&#128736;</span> Container Image Security (Trivy)
      </div>
      <div class="security-tools-grid" id="container-images-grid">
        <!-- Wird dynamisch gefuellt -->
      </div>
    </div>

    <!-- Tab: Compliance -->
    <div class="security-tab-content hidden" id="tab-compliance">
      <div class="security-section-title">
        <span>&#9989;</span> Compliance Status
      </div>
      <div class="security-tools-grid">
        <div class="security-tool-card">
          <div class="security-tool-header">
            <span class="security-tool-name">&#128737; OWASP Top 10</span>
            <span class="security-tool-status installed">8/10 geprueft</span>
          </div>
          <div class="security-tool-description">
            Web Application Security Risks
          </div>
          <div id="owasp-checklist"></div>
        </div>
        <div class="security-tool-card">
          <div class="security-tool-header">
            <span class="security-tool-name">&#128220; DSGVO / GDPR</span>
            <span class="security-tool-status installed">Konform</span>
          </div>
          <div class="security-tool-description">
            Datenschutz-Grundverordnung Compliance
          </div>
        </div>
        <div class="security-tool-card">
          <div class="security-tool-header">
            <span class="security-tool-name">&#128230; Supply Chain</span>
            <span class="security-tool-status installed">SBOM aktuell</span>
          </div>
          <div class="security-tool-description">
            Software Supply Chain Security mit SBOM
          </div>
        </div>
      </div>
    </div>

    <!-- Tab: History -->
    <div class="security-tab-content hidden" id="tab-history">
      <div class="security-section-title">
        <span>&#128197;</span> Scan Historie
      </div>
      <div class="security-findings-container">
        <div class="security-timeline" id="security-timeline">
          <!-- Wird dynamisch gefuellt -->
        </div>
      </div>
    </div>
  </div>
</div>
"""

    @staticmethod
    def get_js() -> str:
        """JavaScript fuer das Security Dashboard."""
        return """
// ==========================================
// SECURITY DASHBOARD MODULE
// ==========================================

const SecurityDashboard = {
  autoRefreshInterval: null,
  scanPollingInterval: null,
  currentTab: 'overview',
  findings: [],
  sbomData: [],
  tools: [],

  // Initialize
  init() {
    console.log('SecurityDashboard initialized');
    this.loadDashboard();
    this.startAutoRefresh();
  },

  // Load all dashboard data
  async loadDashboard() {
    try {
      await Promise.all([
        this.loadToolStatus(),
        this.loadFindings(),
        this.loadSummary(),
        this.loadSBOM(),
        this.loadHistory()
      ]);
    } catch (error) {
      console.error('Error loading security dashboard:', error);
    }
  },

  // Switch tabs
  switchTab(tabName) {
    this.currentTab = tabName;

    // Update tab buttons
    document.querySelectorAll('.security-tab').forEach(tab => {
      tab.classList.toggle('active', tab.dataset.tab === tabName);
    });

    // Update tab content
    document.querySelectorAll('.security-tab-content').forEach(content => {
      content.classList.add('hidden');
    });
    const tabContent = document.getElementById('tab-' + tabName);
    if (tabContent) {
      tabContent.classList.remove('hidden');
    }
  },

  // Load tool status
  async loadToolStatus() {
    try {
      const response = await fetch('/api/v1/security/tools');
      if (response.ok) {
        this.tools = await response.json();
        this.renderToolStatus();
      }
    } catch (error) {
      console.error('Error loading tool status:', error);
      this.renderDefaultToolStatus();
    }
  },

  // Render tool status
  renderToolStatus() {
    const grid = document.getElementById('security-tools-grid');
    if (!grid) return;

    const defaultTools = [
      { name: 'Gitleaks', icon: '&#128273;', desc: 'Secrets Detection in Git History', license: 'MIT', version: '8.18.x' },
      { name: 'Semgrep', icon: '&#128270;', desc: 'Static Application Security Testing (SAST)', license: 'LGPL-2.1', version: '1.52.x' },
      { name: 'Bandit', icon: '&#128013;', desc: 'Python Security Linter', license: 'Apache-2.0', version: '1.7.x' },
      { name: 'Trivy', icon: '&#128736;', desc: 'Container & Filesystem Vulnerability Scanner', license: 'Apache-2.0', version: '0.48.x' },
      { name: 'Grype', icon: '&#128030;', desc: 'Vulnerability Scanner', license: 'Apache-2.0', version: '0.74.x' },
      { name: 'Syft', icon: '&#128230;', desc: 'SBOM Generator (CycloneDX/SPDX)', license: 'Apache-2.0', version: '0.100.x' }
    ];

    grid.innerHTML = defaultTools.map(tool => {
      const serverTool = this.tools.find(t => t.name === tool.name) || {};
      const isInstalled = serverTool.installed !== false;
      const lastRun = serverTool.last_run || 'Nie';

      return `
        <div class="security-tool-card">
          <div class="security-tool-header">
            <span class="security-tool-name">${tool.icon} ${tool.name}</span>
            <span class="security-tool-status ${isInstalled ? 'installed' : 'not-installed'}">
              ${isInstalled ? 'Installiert' : 'Nicht installiert'}
            </span>
          </div>
          <div class="security-tool-description">${tool.desc}</div>
          <div class="security-tool-meta">
            <span class="security-tool-meta-item">&#128196; ${tool.license}</span>
            <span class="security-tool-meta-item">&#128200; v${tool.version}</span>
            <span class="security-tool-meta-item">&#128337; ${lastRun}</span>
          </div>
          <div class="security-tool-actions">
            <button class="security-tool-btn primary" onclick="SecurityDashboard.runToolScan('${tool.name.toLowerCase()}')">
              Scan starten
            </button>
            <button class="security-tool-btn secondary" onclick="SecurityDashboard.viewToolReport('${tool.name.toLowerCase()}')">
              Report anzeigen
            </button>
          </div>
        </div>
      `;
    }).join('');
  },

  renderDefaultToolStatus() {
    this.tools = [];
    this.renderToolStatus();
  },

  // Load findings
  async loadFindings() {
    try {
      const response = await fetch('/api/v1/security/findings');
      if (response.ok) {
        this.findings = await response.json();
        this.renderFindings();
      }
    } catch (error) {
      console.error('Error loading findings:', error);
      this.renderEmptyFindings();
    }
  },

  // Render findings table
  renderFindings() {
    const tbody = document.getElementById('security-findings-body');
    if (!tbody) return;

    if (!this.findings || this.findings.length === 0) {
      this.renderEmptyFindings();
      return;
    }

    tbody.innerHTML = this.findings.slice(0, 20).map(finding => `
      <tr>
        <td><span class="severity-badge ${finding.severity.toLowerCase()}">${finding.severity}</span></td>
        <td>${finding.tool || 'Unknown'}</td>
        <td>${finding.title || finding.message || 'No description'}</td>
        <td>${finding.file || '-'}</td>
        <td>${finding.found_at ? new Date(finding.found_at).toLocaleString('de-DE') : '-'}</td>
      </tr>
    `).join('');

    // Update counts
    document.getElementById('secrets-count').textContent = this.findings.filter(f => f.tool === 'gitleaks').length;
    document.getElementById('vuln-count').textContent = this.findings.filter(f => f.tool === 'trivy' || f.tool === 'grype').length;
  },

  renderEmptyFindings() {
    const tbody = document.getElementById('security-findings-body');
    if (!tbody) return;

    tbody.innerHTML = `
      <tr>
        <td colspan="5" style="text-align: center; padding: 40px; color: var(--bp-text-muted);">
          &#128274; Keine Findings gefunden. Das ist gut!
        </td>
      </tr>
    `;
  },

  // Load summary
  async loadSummary() {
    try {
      const response = await fetch('/api/v1/security/summary');
      if (response.ok) {
        const summary = await response.json();
        this.renderSummary(summary);
      }
    } catch (error) {
      console.error('Error loading summary:', error);
      this.renderSummary({ critical: 0, high: 0, medium: 0, low: 0, info: 0 });
    }
  },

  renderSummary(summary) {
    document.getElementById('critical-count').textContent = summary.critical || 0;
    document.getElementById('high-count').textContent = summary.high || 0;
    document.getElementById('medium-count').textContent = summary.medium || 0;
    document.getElementById('low-count').textContent = summary.low || 0;
    document.getElementById('info-count').textContent = summary.info || 0;

    // Update overall status
    const statusBadge = document.getElementById('security-overall-status');
    if (summary.critical > 0) {
      statusBadge.className = 'security-status-badge critical';
      statusBadge.innerHTML = '<span>&#10060;</span> Critical Issues';
    } else if (summary.high > 0) {
      statusBadge.className = 'security-status-badge warning';
      statusBadge.innerHTML = '<span>&#9888;</span> Warnings';
    } else {
      statusBadge.className = 'security-status-badge secure';
      statusBadge.innerHTML = '<span>&#10003;</span> Sicher';
    }
  },

  // Load SBOM
  async loadSBOM() {
    try {
      const response = await fetch('/api/v1/security/sbom');
      if (response.ok) {
        this.sbomData = await response.json();
        this.renderSBOM();
      }
    } catch (error) {
      console.error('Error loading SBOM:', error);
    }
  },

  renderSBOM() {
    if (!this.sbomData || !this.sbomData.components) return;

    const components = this.sbomData.components || [];

    // Update stats
    document.getElementById('sbom-total').textContent = components.length;
    document.getElementById('sbom-python').textContent = components.filter(c => c.type === 'python' || c.purl?.startsWith('pkg:pypi')).length;
    document.getElementById('sbom-go').textContent = components.filter(c => c.type === 'go' || c.purl?.startsWith('pkg:golang')).length;
    document.getElementById('sbom-npm').textContent = components.filter(c => c.type === 'npm' || c.purl?.startsWith('pkg:npm')).length;

    // Render table
    const tbody = document.getElementById('sbom-body');
    if (!tbody) return;

    tbody.innerHTML = components.slice(0, 50).map(comp => `
      <tr>
        <td>${comp.name || 'Unknown'}</td>
        <td>${comp.version || '-'}</td>
        <td>${comp.type || this.getTypeFromPurl(comp.purl)}</td>
        <td>${comp.licenses?.[0]?.license?.id || comp.licenses?.[0]?.license?.name || '-'}</td>
      </tr>
    `).join('');
  },

  getTypeFromPurl(purl) {
    if (!purl) return 'unknown';
    if (purl.startsWith('pkg:pypi')) return 'Python';
    if (purl.startsWith('pkg:golang')) return 'Go';
    if (purl.startsWith('pkg:npm')) return 'NPM';
    return 'other';
  },

  filterSBOM() {
    const search = document.getElementById('sbom-search').value.toLowerCase();
    const tbody = document.getElementById('sbom-body');
    if (!tbody || !this.sbomData?.components) return;

    const filtered = this.sbomData.components.filter(c =>
      c.name?.toLowerCase().includes(search) ||
      c.version?.toLowerCase().includes(search)
    );

    tbody.innerHTML = filtered.slice(0, 50).map(comp => `
      <tr>
        <td>${comp.name || 'Unknown'}</td>
        <td>${comp.version || '-'}</td>
        <td>${comp.type || this.getTypeFromPurl(comp.purl)}</td>
        <td>${comp.licenses?.[0]?.license?.id || '-'}</td>
      </tr>
    `).join('');
  },

  // Load history
  async loadHistory() {
    try {
      const response = await fetch('/api/v1/security/history');
      if (response.ok) {
        const history = await response.json();
        this.renderHistory(history);
      }
    } catch (error) {
      console.error('Error loading history:', error);
      this.renderDefaultHistory();
    }
  },

  renderHistory(history) {
    const timeline = document.getElementById('security-timeline');
    if (!timeline) return;

    if (!history || history.length === 0) {
      this.renderDefaultHistory();
      return;
    }

    timeline.innerHTML = history.map(item => `
      <div class="security-timeline-item ${item.status || 'success'}">
        <div class="security-timeline-time">${new Date(item.timestamp).toLocaleString('de-DE')}</div>
        <div class="security-timeline-content">
          <div class="security-timeline-title">${item.title}</div>
          <div class="security-timeline-desc">${item.description || ''}</div>
        </div>
      </div>
    `).join('');
  },

  renderDefaultHistory() {
    const timeline = document.getElementById('security-timeline');
    if (!timeline) return;

    timeline.innerHTML = `
      <div class="security-timeline-item success">
        <div class="security-timeline-time">${new Date().toLocaleString('de-DE')}</div>
        <div class="security-timeline-content">
          <div class="security-timeline-title">Security Dashboard initialisiert</div>
          <div class="security-timeline-desc">DevSecOps Pipeline bereit</div>
        </div>
      </div>
    `;
  },

  // Run full scan
  async runFullScan() {
    const progressEl = document.getElementById('security-scan-progress');
    progressEl.classList.remove('hidden');

    const steps = ['secrets', 'sast', 'deps', 'containers', 'sbom'];
    let progress = 0;

    for (const step of steps) {
      document.getElementById('step-' + step).classList.add('active');

      try {
        await fetch('/api/v1/security/scan/' + step, { method: 'POST' });
      } catch (error) {
        console.error('Scan step failed:', step, error);
      }

      progress += 20;
      document.getElementById('scan-progress-fill').style.width = progress + '%';
      document.getElementById('scan-percentage').textContent = progress + '%';

      document.getElementById('step-' + step).classList.remove('active');
      document.getElementById('step-' + step).classList.add('completed');

      await new Promise(r => setTimeout(r, 500));
    }

    // Reload dashboard data
    await this.loadDashboard();

    // Hide progress after delay
    setTimeout(() => {
      progressEl.classList.add('hidden');
      // Reset steps
      steps.forEach(step => {
        document.getElementById('step-' + step).classList.remove('completed', 'active');
      });
      document.getElementById('scan-progress-fill').style.width = '0%';
      document.getElementById('scan-percentage').textContent = '0%';
    }, 2000);
  },

  // Run individual tool scan
  async runToolScan(tool) {
    try {
      const response = await fetch('/api/v1/security/scan/' + tool, { method: 'POST' });
      if (response.ok) {
        await this.loadDashboard();
        console.log('Scan completed:', tool);
      }
    } catch (error) {
      console.error('Scan failed:', tool, error);
    }
  },

  // Run secrets scan
  async runSecretsScan() {
    await this.runToolScan('secrets');
  },

  // View tool report
  async viewToolReport(tool) {
    try {
      const response = await fetch('/api/v1/security/reports/' + tool);
      if (response.ok) {
        const report = await response.json();
        console.log('Report:', tool, report);
        // Could open a modal with full report
      }
    } catch (error) {
      console.error('Error loading report:', tool, error);
    }
  },

  // Auto-refresh
  startAutoRefresh() {
    this.autoRefreshInterval = setInterval(() => {
      this.loadSummary();
    }, 30000); // Every 30 seconds
  },

  stopAutoRefresh() {
    if (this.autoRefreshInterval) {
      clearInterval(this.autoRefreshInterval);
      this.autoRefreshInterval = null;
    }
  }
};

// Initialize when security panel is shown
function initSecurityModule() {
  SecurityDashboard.init();
}

// Clean up when leaving
function cleanupSecurityModule() {
  SecurityDashboard.stopAutoRefresh();
}
"""
