// =============================================================================
// Loeschfristen Document — HTML Document Builder
// =============================================================================

import type {
  LoeschfristPolicy,
} from '../loeschfristen-types'
import {
  RETENTION_DRIVER_META,
  DELETION_METHOD_LABELS,
  STATUS_LABELS,
  TRIGGER_LABELS,
  REVIEW_INTERVAL_LABELS,
  formatRetentionDuration,
  getEffectiveDeletionTrigger,
  getActiveLegalHolds,
} from '../loeschfristen-types'
import type { ComplianceCheckResult } from '../loeschfristen-compliance'
import type { LoeschkonzeptOrgHeader, LoeschkonzeptRevision } from './types-defaults'
import { escHtml, formatDateDE } from './helpers'
import { buildSections6to9, buildSections10to12 } from './html-builder-sections-6-12'

type VVTActivity = { id: string; vvt_id?: string; vvtId?: string; name?: string; activity_name?: string }

export function buildLoeschkonzeptHtml(
  policies: LoeschfristPolicy[],
  orgHeader: LoeschkonzeptOrgHeader,
  vvtActivities: VVTActivity[],
  complianceResult: ComplianceCheckResult | null,
  revisions: LoeschkonzeptRevision[]
): string {
  const today = new Date().toLocaleDateString('de-DE', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
  })

  const activePolicies = policies.filter(p => p.status !== 'ARCHIVED')
  const orgName = orgHeader.organizationName || 'Organisation'

  // Collect unique storage locations
  const allStorageLocations = new Set<string>()
  for (const p of activePolicies) {
    for (const loc of p.storageLocations) {
      allStorageLocations.add(loc.name || loc.type)
    }
  }

  // Collect unique responsible roles
  const roleMap = new Map<string, string[]>()
  for (const p of activePolicies) {
    const role = p.responsibleRole || p.responsiblePerson || 'Nicht zugewiesen'
    if (!roleMap.has(role)) roleMap.set(role, [])
    roleMap.get(role)!.push(p.dataObjectName || p.policyId)
  }

  // Collect active legal holds
  const allActiveLegalHolds: Array<{ policy: string; hold: LoeschfristPolicy['legalHolds'][0] }> = []
  for (const p of activePolicies) {
    for (const h of getActiveLegalHolds(p)) {
      allActiveLegalHolds.push({ policy: p.dataObjectName || p.policyId, hold: h })
    }
  }

  // Build VVT cross-reference data
  const vvtRefs: Array<{ policyName: string; policyId: string; vvtId: string; vvtName: string }> = []
  for (const p of activePolicies) {
    for (const linkedId of p.linkedVVTActivityIds) {
      const activity = vvtActivities.find(a => a.id === linkedId)
      if (activity) {
        vvtRefs.push({
          policyName: p.dataObjectName || p.policyId,
          policyId: p.policyId,
          vvtId: activity.vvt_id || activity.vvtId || linkedId.substring(0, 8),
          vvtName: activity.activity_name || activity.name || 'Unbenannte Verarbeitungstaetigkeit',
        })
      }
    }
  }

  // Build vendor cross-reference data
  const vendorRefs: Array<{ policyName: string; policyId: string; vendorId: string; duration: string }> = []
  for (const p of activePolicies) {
    if (p.linkedVendorIds && p.linkedVendorIds.length > 0) {
      for (const vendorId of p.linkedVendorIds) {
        vendorRefs.push({
          policyName: p.dataObjectName || p.policyId,
          policyId: p.policyId,
          vendorId,
          duration: formatRetentionDuration(p.retentionDuration, p.retentionUnit),
        })
      }
    }
  }

  let html = buildDocumentHeader(orgName)
  html += buildCoverAndTOC(orgHeader, orgName, today)
  html += buildSections1to5(orgName, orgHeader, activePolicies, allStorageLocations)
  html += buildSections6to9(activePolicies, vvtRefs, vendorRefs, allActiveLegalHolds, roleMap)
  html += buildSections10to12(orgHeader, complianceResult, revisions, today)
  html += `
<div class="page-footer">
  <span>Loeschkonzept — ${escHtml(orgName)}</span>
  <span>Stand: ${today} | Version ${escHtml(orgHeader.loeschkonzeptVersion)}</span>
</div>

</body>
</html>`

  return html
}

function buildDocumentHeader(orgName: string): string {
  return `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Loeschkonzept — ${escHtml(orgName)}</title>
<style>
  @page { size: A4; margin: 20mm 18mm 22mm 18mm; }
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-size: 10pt; line-height: 1.5; color: #1e293b; }
  .cover { min-height: 90vh; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; page-break-after: always; }
  .cover h1 { font-size: 28pt; color: #5b21b6; margin-bottom: 8px; font-weight: 700; }
  .cover .subtitle { font-size: 14pt; color: #7c3aed; margin-bottom: 40px; }
  .cover .org-info { background: #f5f3ff; border: 1px solid #ddd6fe; border-radius: 8px; padding: 24px 40px; text-align: left; width: 400px; margin-bottom: 24px; }
  .cover .org-info div { margin-bottom: 6px; }
  .cover .org-info .label { font-weight: 600; color: #5b21b6; display: inline-block; min-width: 160px; }
  .cover .legal-ref { font-size: 9pt; color: #64748b; margin-top: 20px; }
  .toc { page-break-after: always; padding-top: 40px; }
  .toc h2 { font-size: 18pt; color: #5b21b6; margin-bottom: 20px; border-bottom: 2px solid #5b21b6; padding-bottom: 8px; }
  .toc-entry { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px dotted #cbd5e1; font-size: 10pt; }
  .toc-entry .toc-num { font-weight: 600; color: #5b21b6; min-width: 40px; }
  .section { page-break-inside: avoid; margin-bottom: 24px; }
  .section-header { font-size: 14pt; color: #5b21b6; font-weight: 700; margin: 30px 0 12px 0; border-bottom: 2px solid #ddd6fe; padding-bottom: 6px; }
  .section-body { margin-bottom: 16px; }
  table { width: 100%; border-collapse: collapse; margin: 10px 0 16px 0; font-size: 9pt; }
  th, td { border: 1px solid #e2e8f0; padding: 6px 8px; text-align: left; vertical-align: top; }
  th { background: #f5f3ff; color: #5b21b6; font-weight: 600; font-size: 8.5pt; text-transform: uppercase; letter-spacing: 0.3px; }
  tr:nth-child(even) td { background: #faf5ff; }
  .policy-detail { page-break-inside: avoid; border: 1px solid #e2e8f0; border-radius: 6px; margin-bottom: 16px; overflow: hidden; }
  .policy-detail-header { background: #f5f3ff; padding: 8px 12px; font-weight: 700; color: #5b21b6; border-bottom: 1px solid #ddd6fe; display: flex; justify-content: space-between; }
  .policy-detail-body { padding: 0; }
  .policy-detail-body table { margin: 0; }
  .policy-detail-body th { width: 200px; }
  .badge { display: inline-block; padding: 1px 8px; border-radius: 9999px; font-size: 8pt; font-weight: 600; }
  .badge-active { background: #dcfce7; color: #166534; }
  .badge-draft { background: #f3f4f6; color: #374151; }
  .badge-review { background: #fef9c3; color: #854d0e; }
  .badge-critical { background: #fecaca; color: #991b1b; }
  .badge-high { background: #fed7aa; color: #9a3412; }
  .badge-medium { background: #fef3c7; color: #92400e; }
  .badge-low { background: #f3f4f6; color: #4b5563; }
  .principle { margin-bottom: 10px; padding-left: 20px; position: relative; }
  .principle::before { content: ''; position: absolute; left: 0; top: 6px; width: 10px; height: 10px; background: #7c3aed; border-radius: 50%; }
  .principle strong { color: #5b21b6; }
  .score-box { display: inline-block; padding: 4px 16px; border-radius: 8px; font-size: 18pt; font-weight: 700; margin-right: 12px; }
  .score-excellent { background: #dcfce7; color: #166534; }
  .score-good { background: #dbeafe; color: #1e40af; }
  .score-needs-work { background: #fef3c7; color: #92400e; }
  .score-poor { background: #fecaca; color: #991b1b; }
  .page-footer { position: fixed; bottom: 0; left: 0; right: 0; padding: 8px 18mm; font-size: 7.5pt; color: #94a3b8; display: flex; justify-content: space-between; border-top: 1px solid #e2e8f0; }
  @media print { body { -webkit-print-color-adjust: exact; print-color-adjust: exact; } .no-print { display: none !important; } .page-break { page-break-after: always; } }
</style>
</head>
<body>
`
}

function buildCoverAndTOC(
  orgHeader: LoeschkonzeptOrgHeader,
  orgName: string,
  today: string
): string {
  const sections = [
    'Ziel und Zweck', 'Geltungsbereich', 'Grundprinzipien der Datenspeicherung',
    'Loeschregeln-Uebersicht', 'Detaillierte Loeschregeln', 'VVT-Verknuepfung',
    'Auftragsverarbeiter mit Loeschpflichten', 'Legal Hold Verfahren',
    'Verantwortlichkeiten', 'Pruef- und Revisionszyklus', 'Compliance-Status', 'Aenderungshistorie',
  ]

  return `
<div class="cover">
  <h1>Loeschkonzept</h1>
  <div class="subtitle">gemaess Art. 5 Abs. 1 lit. e, Art. 17, Art. 30 DSGVO</div>
  <div class="org-info">
    <div><span class="label">Organisation:</span> ${escHtml(orgName)}</div>
    ${orgHeader.industry ? `<div><span class="label">Branche:</span> ${escHtml(orgHeader.industry)}</div>` : ''}
    ${orgHeader.dpoName ? `<div><span class="label">Datenschutzbeauftragter:</span> ${escHtml(orgHeader.dpoName)}</div>` : ''}
    ${orgHeader.dpoContact ? `<div><span class="label">DSB-Kontakt:</span> ${escHtml(orgHeader.dpoContact)}</div>` : ''}
    ${orgHeader.responsiblePerson ? `<div><span class="label">Verantwortlicher:</span> ${escHtml(orgHeader.responsiblePerson)}</div>` : ''}
    ${orgHeader.employeeCount ? `<div><span class="label">Mitarbeiter:</span> ${escHtml(orgHeader.employeeCount)}</div>` : ''}
    ${orgHeader.locations.length > 0 ? `<div><span class="label">Standorte:</span> ${escHtml(orgHeader.locations.join(', '))}</div>` : ''}
  </div>
  <div class="legal-ref">
    Version ${escHtml(orgHeader.loeschkonzeptVersion)} | Stand: ${today}<br/>
    Letzte Pruefung: ${formatDateDE(orgHeader.lastReviewDate)} | Naechste Pruefung: ${formatDateDE(orgHeader.nextReviewDate)}<br/>
    Pruefintervall: ${escHtml(orgHeader.reviewInterval)}
  </div>
</div>
<div class="toc">
  <h2>Inhaltsverzeichnis</h2>
  ${sections.map((s, i) => `<div class="toc-entry"><span><span class="toc-num">${i + 1}.</span> ${escHtml(s)}</span></div>`).join('\n  ')}
</div>
`
}

function buildSections1to5(
  orgName: string,
  orgHeader: LoeschkonzeptOrgHeader,
  activePolicies: LoeschfristPolicy[],
  allStorageLocations: Set<string>
): string {
  const storageListHtml = allStorageLocations.size > 0
    ? Array.from(allStorageLocations).map(s => `<li>${escHtml(s)}</li>`).join('')
    : '<li><em>Keine Speicherorte dokumentiert</em></li>'

  return `
<div class="section">
  <div class="section-header">1. Ziel und Zweck</div>
  <div class="section-body">
    <p>Dieses Loeschkonzept definiert die systematischen Regeln und Verfahren fuer die Loeschung
    personenbezogener Daten bei <strong>${escHtml(orgName)}</strong>. Es dient der Umsetzung
    folgender DSGVO-Anforderungen:</p>
    <table>
      <tr><th>Rechtsgrundlage</th><th>Inhalt</th></tr>
      <tr><td><strong>Art. 5 Abs. 1 lit. e DSGVO</strong></td><td>Grundsatz der Speicherbegrenzung — personenbezogene Daten duerfen nur so lange gespeichert werden, wie es fuer die Zwecke der Verarbeitung erforderlich ist.</td></tr>
      <tr><td><strong>Art. 17 DSGVO</strong></td><td>Recht auf Loeschung (&bdquo;Recht auf Vergessenwerden&ldquo;) — Betroffene haben das Recht, die Loeschung ihrer Daten zu verlangen.</td></tr>
      <tr><td><strong>Art. 30 DSGVO</strong></td><td>Verzeichnis von Verarbeitungstaetigkeiten — vorgesehene Fristen fuer die Loeschung der verschiedenen Datenkategorien muessen dokumentiert werden.</td></tr>
    </table>
    <p>Das Loeschkonzept ist fester Bestandteil des Datenschutz-Managementsystems und wird
    regelmaessig ueberprueft und aktualisiert.</p>
  </div>
</div>

<div class="section">
  <div class="section-header">2. Geltungsbereich</div>
  <div class="section-body">
    <p>Dieses Loeschkonzept gilt fuer alle personenbezogenen Daten, die von <strong>${escHtml(orgName)}</strong>
    verarbeitet werden. Es umfasst <strong>${activePolicies.length}</strong> Loeschregeln fuer folgende Systeme und Speicherorte:</p>
    <ul style="margin: 8px 0 8px 24px;">${storageListHtml}</ul>
    <p>Saemtliche Verarbeitungstaetigkeiten, die im Verzeichnis von Verarbeitungstaetigkeiten (VVT)
    erfasst sind, werden durch dieses Loeschkonzept abgedeckt.</p>
  </div>
</div>

<div class="section">
  <div class="section-header">3. Grundprinzipien der Datenspeicherung</div>
  <div class="section-body">
    <div class="principle"><strong>Speicherbegrenzung:</strong> Personenbezogene Daten werden nur so lange gespeichert, wie es fuer den jeweiligen Verarbeitungszweck erforderlich ist (Art. 5 Abs. 1 lit. e DSGVO).</div>
    <div class="principle"><strong>3-Level-Loeschlogik:</strong> Die Loeschung folgt einer dreistufigen Priorisierung: (1) Zweckende, (2) gesetzliche Aufbewahrungspflichten, (3) Legal Hold — jeweils mit der laengsten Frist als massgeblich.</div>
    <div class="principle"><strong>Dokumentationspflicht:</strong> Jede Loeschregel ist dokumentiert mit Rechtsgrundlage, Frist, Loeschmethode und Verantwortlichkeit.</div>
    <div class="principle"><strong>Regelmaessige Ueberpruefung:</strong> Alle Loeschregeln werden im definierten Intervall ueberprueft und bei Bedarf angepasst.</div>
    <div class="principle"><strong>Datenschutz durch Technikgestaltung:</strong> Loeschmechanismen werden moeglichst automatisiert, um menschliche Fehler zu minimieren (Art. 25 DSGVO).</div>
  </div>
</div>

${buildSection4Overview(activePolicies)}
${buildSection5Detail(activePolicies)}
`
}

function buildSection4Overview(activePolicies: LoeschfristPolicy[]): string {
  let html = `
<div class="section page-break">
  <div class="section-header">4. Loeschregeln-Uebersicht</div>
  <div class="section-body">
    <p>Die folgende Tabelle zeigt eine Uebersicht aller ${activePolicies.length} aktiven Loeschregeln:</p>
    <table>
      <tr>
        <th>LF-Nr.</th>
        <th>Datenobjekt</th>
        <th>Loeschtrigger</th>
        <th>Aufbewahrungsfrist</th>
        <th>Loeschmethode</th>
        <th>Status</th>
      </tr>
`
  for (const p of activePolicies) {
    const trigger = TRIGGER_LABELS[getEffectiveDeletionTrigger(p)]
    const duration = formatRetentionDuration(p.retentionDuration, p.retentionUnit)
    const method = DELETION_METHOD_LABELS[p.deletionMethod]
    const statusLabel = STATUS_LABELS[p.status]
    const statusClass = p.status === 'ACTIVE' ? 'badge-active' : p.status === 'REVIEW_NEEDED' ? 'badge-review' : 'badge-draft'

    html += `      <tr>
        <td>${escHtml(p.policyId)}</td>
        <td>${escHtml(p.dataObjectName)}</td>
        <td>${escHtml(trigger)}</td>
        <td>${escHtml(duration)}</td>
        <td>${escHtml(method)}</td>
        <td><span class="badge ${statusClass}">${escHtml(statusLabel)}</span></td>
      </tr>
`
  }

  html += `    </table>
  </div>
</div>
`
  return html
}

function buildSection5Detail(activePolicies: LoeschfristPolicy[]): string {
  let html = `
<div class="section">
  <div class="section-header">5. Detaillierte Loeschregeln</div>
  <div class="section-body">
`
  for (const p of activePolicies) {
    const trigger = TRIGGER_LABELS[getEffectiveDeletionTrigger(p)]
    const duration = formatRetentionDuration(p.retentionDuration, p.retentionUnit)
    const method = DELETION_METHOD_LABELS[p.deletionMethod]
    const statusLabel = STATUS_LABELS[p.status]
    const driverLabel = p.retentionDriver ? RETENTION_DRIVER_META[p.retentionDriver]?.label || p.retentionDriver : '-'
    const driverStatute = p.retentionDriver ? RETENTION_DRIVER_META[p.retentionDriver]?.statute || '' : ''
    const locations = p.storageLocations.map(l => l.name || l.type).join(', ') || '-'
    const responsible = [p.responsiblePerson, p.responsibleRole].filter(s => s.trim()).join(' / ') || '-'
    const activeHolds = getActiveLegalHolds(p)

    html += `
    <div class="policy-detail">
      <div class="policy-detail-header">
        <span>${escHtml(p.policyId)} — ${escHtml(p.dataObjectName)}</span>
        <span class="badge ${p.status === 'ACTIVE' ? 'badge-active' : 'badge-draft'}">${escHtml(statusLabel)}</span>
      </div>
      <div class="policy-detail-body">
        <table>
          <tr><th>Beschreibung</th><td>${escHtml(p.description || '-')}</td></tr>
          <tr><th>Betroffenengruppen</th><td>${escHtml(p.affectedGroups.join(', ') || '-')}</td></tr>
          <tr><th>Datenkategorien</th><td>${escHtml(p.dataCategories.join(', ') || '-')}</td></tr>
          <tr><th>Verarbeitungszweck</th><td>${escHtml(p.primaryPurpose || '-')}</td></tr>
          <tr><th>Loeschtrigger</th><td>${escHtml(trigger)}</td></tr>
          <tr><th>Aufbewahrungstreiber</th><td>${escHtml(driverLabel)}${driverStatute ? ` (${escHtml(driverStatute)})` : ''}</td></tr>
          <tr><th>Aufbewahrungsfrist</th><td>${escHtml(duration)}</td></tr>
          <tr><th>Startereignis</th><td>${escHtml(p.startEvent || '-')}</td></tr>
          <tr><th>Loeschmethode</th><td>${escHtml(method)}</td></tr>
          <tr><th>Loeschmethode (Detail)</th><td>${escHtml(p.deletionMethodDetail || '-')}</td></tr>
          <tr><th>Speicherorte</th><td>${escHtml(locations)}</td></tr>
          <tr><th>Verantwortlich</th><td>${escHtml(responsible)}</td></tr>
          <tr><th>Pruefintervall</th><td>${escHtml(REVIEW_INTERVAL_LABELS[p.reviewInterval] || p.reviewInterval)}</td></tr>
          ${activeHolds.length > 0 ? `<tr><th>Aktive Legal Holds</th><td>${activeHolds.map(h => `${escHtml(h.reason)} (seit ${formatDateDE(h.startDate)})`).join('<br/>')}</td></tr>` : ''}
        </table>
      </div>
    </div>
`
  }

  html += `  </div>
</div>
`
  return html
}
