'use client'

import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react'
import { useSDK } from '@/lib/sdk'
import { useEinwilligungen, EinwilligungenProvider } from '@/lib/sdk/einwilligungen/context'
import { StepHeader, STEP_EXPLANATIONS } from '@/components/sdk/StepHeader'
import {
  LegalTemplateResult,
  TemplateType,
  LicenseType,
  TEMPLATE_TYPE_LABELS,
  LICENSE_TYPE_LABELS,
} from '@/lib/sdk/types'
import { DataPointsPreview } from './components/DataPointsPreview'
import { DocumentValidation } from './components/DocumentValidation'
import { generateAllPlaceholders } from '@/lib/sdk/document-generator/datapoint-helpers'
import { loadAllTemplates } from './searchTemplates'
import {
  TemplateContext, EMPTY_CONTEXT,
  contextToPlaceholders, getRelevantSections,
  getUncoveredPlaceholders, getMissingRequired,
} from './contextBridge'
import {
  runRuleset, getDocType, applyBlockRemoval,
  buildBoolContext, applyConditionalBlocks,
  type RuleInput, type RuleEngineResult,
} from './ruleEngine'

// =============================================================================
// CATEGORY CONFIG
// =============================================================================

const CATEGORIES: { key: string; label: string; types: string[] | null }[] = [
  { key: 'all', label: 'Alle', types: null },
  { key: 'privacy_policy', label: 'Datenschutz', types: ['privacy_policy'] },
  { key: 'terms', label: 'AGB', types: ['terms_of_service', 'agb', 'clause'] },
  { key: 'impressum', label: 'Impressum', types: ['impressum'] },
  { key: 'dpa', label: 'AVV/DPA', types: ['dpa'] },
  { key: 'nda', label: 'NDA', types: ['nda'] },
  { key: 'sla', label: 'SLA', types: ['sla'] },
  { key: 'acceptable_use', label: 'AUP', types: ['acceptable_use'] },
  { key: 'widerruf', label: 'Widerruf', types: ['widerruf'] },
  { key: 'cookie', label: 'Cookie', types: ['cookie_policy', 'cookie_banner'] },
  { key: 'cloud', label: 'Cloud', types: ['cloud_service_agreement'] },
  { key: 'misc', label: 'Weitere', types: ['community_guidelines', 'copyright_policy', 'data_usage_clause'] },
  { key: 'dsfa', label: 'DSFA', types: ['dsfa'] },
]

// =============================================================================
// CONTEXT FORM CONFIG
// =============================================================================

const SECTION_LABELS: Record<keyof TemplateContext, string> = {
  PROVIDER:  'Anbieter',
  CUSTOMER:  'Kunde / Gegenpartei',
  SERVICE:   'Dienst / Produkt',
  LEGAL:     'Rechtliches',
  PRIVACY:   'Datenschutz',
  SLA:       'Service Level (SLA)',
  PAYMENTS:  'Zahlungskonditionen',
  SECURITY:  'Sicherheit & Logs',
  NDA:       'Geheimhaltung (NDA)',
  CONSENT:   'Cookie / Einwilligung',
  HOSTING:   'Hosting-Provider',
  FEATURES:  'Dokument-Features & Textbausteine',
}

type FieldType = 'text' | 'email' | 'number' | 'select' | 'textarea' | 'boolean'
interface FieldDef {
  key: string
  label: string
  type?: FieldType
  opts?: string[]
  span?: boolean
  nullable?: boolean
}

const SECTION_FIELDS: Record<keyof TemplateContext, FieldDef[]> = {
  PROVIDER: [
    { key: 'LEGAL_NAME', label: 'Firmenname' },
    { key: 'EMAIL', label: 'Kontakt-E-Mail', type: 'email' },
    { key: 'LEGAL_FORM', label: 'Rechtsform' },
    { key: 'ADDRESS_LINE', label: 'Adresse' },
    { key: 'POSTAL_CODE', label: 'PLZ' },
    { key: 'CITY', label: 'Stadt' },
    { key: 'WEBSITE_URL', label: 'Website-URL' },
    { key: 'CEO_NAME', label: 'Geschäftsführer' },
    { key: 'REGISTER_COURT', label: 'Registergericht' },
    { key: 'REGISTER_NUMBER', label: 'HRB-Nummer' },
    { key: 'VAT_ID', label: 'USt-ID' },
    { key: 'PHONE', label: 'Telefon' },
  ],
  CUSTOMER: [
    { key: 'LEGAL_NAME', label: 'Name / Firma' },
    { key: 'EMAIL', label: 'E-Mail', type: 'email' },
    { key: 'CONTACT_NAME', label: 'Ansprechpartner' },
    { key: 'ADDRESS_LINE', label: 'Adresse' },
    { key: 'POSTAL_CODE', label: 'PLZ' },
    { key: 'CITY', label: 'Stadt' },
    { key: 'COUNTRY', label: 'Land' },
    { key: 'IS_CONSUMER', label: 'Verbraucher (B2C)', type: 'boolean' },
    { key: 'IS_BUSINESS', label: 'Unternehmer (B2B)', type: 'boolean' },
  ],
  SERVICE: [
    { key: 'NAME', label: 'Dienstname' },
    { key: 'DESCRIPTION', label: 'Beschreibung', type: 'textarea', span: true },
    { key: 'MODEL', label: 'Modell', type: 'select', opts: ['SaaS', 'PaaS', 'IaaS', 'OnPrem', 'Hybrid'] },
    { key: 'TIER', label: 'Plan / Tier' },
    { key: 'DATA_LOCATION', label: 'Datenspeicherort' },
    { key: 'EXPORT_WINDOW_DAYS', label: 'Export-Frist (Tage)', type: 'number' },
    { key: 'MIN_TERM_MONTHS', label: 'Mindestlaufzeit (Monate)', type: 'number' },
    { key: 'TERMINATION_NOTICE_DAYS', label: 'Kündigungsfrist (Tage)', type: 'number' },
  ],
  LEGAL: [
    { key: 'GOVERNING_LAW', label: 'Anwendbares Recht' },
    { key: 'JURISDICTION_CITY', label: 'Gerichtsstand (Stadt)' },
    { key: 'VERSION_DATE', label: 'Versionsstand (JJJJ-MM-TT)' },
    { key: 'EFFECTIVE_DATE', label: 'Gültig ab (JJJJ-MM-TT)' },
  ],
  PRIVACY: [
    { key: 'DPO_NAME', label: 'DSB-Name' },
    { key: 'DPO_EMAIL', label: 'DSB-E-Mail', type: 'email' },
    { key: 'CONTACT_EMAIL', label: 'Datenschutz-Kontakt', type: 'email' },
    { key: 'PRIVACY_POLICY_URL', label: 'Datenschutz-URL' },
    { key: 'COOKIE_POLICY_URL', label: 'Cookie-Policy-URL' },
    { key: 'ANALYTICS_RETENTION_MONTHS', label: 'Analytics-Aufbewahrung (Monate)', type: 'number' },
    { key: 'SUPERVISORY_AUTHORITY_NAME', label: 'Aufsichtsbehörde' },
  ],
  SLA: [
    { key: 'AVAILABILITY_PERCENT', label: 'Verfügbarkeit (%)', type: 'number' },
    { key: 'MAINTENANCE_NOTICE_HOURS', label: 'Wartungsankündigung (h)', type: 'number' },
    { key: 'SUPPORT_EMAIL', label: 'Support-E-Mail', type: 'email' },
    { key: 'SUPPORT_HOURS', label: 'Support-Zeiten' },
    { key: 'RESPONSE_CRITICAL_H', label: 'Reaktion Kritisch (h)', type: 'number' },
    { key: 'RESOLUTION_CRITICAL_H', label: 'Lösung Kritisch (h)', type: 'number' },
    { key: 'RESPONSE_HIGH_H', label: 'Reaktion Hoch (h)', type: 'number' },
    { key: 'RESOLUTION_HIGH_H', label: 'Lösung Hoch (h)', type: 'number' },
    { key: 'RESPONSE_MEDIUM_H', label: 'Reaktion Mittel (h)', type: 'number' },
    { key: 'RESOLUTION_MEDIUM_H', label: 'Lösung Mittel (h)', type: 'number' },
    { key: 'RESPONSE_LOW_H', label: 'Reaktion Niedrig (h)', type: 'number' },
  ],
  PAYMENTS: [
    { key: 'MONTHLY_FEE_EUR', label: 'Monatl. Gebühr (EUR)', type: 'number' },
    { key: 'PAYMENT_DUE_DAY', label: 'Fälligkeitstag', type: 'number' },
    { key: 'PAYMENT_METHOD', label: 'Zahlungsmethode' },
    { key: 'PAYMENT_DAYS', label: 'Zahlungsziel (Tage)', type: 'number' },
  ],
  SECURITY: [
    { key: 'INCIDENT_NOTICE_HOURS', label: 'Meldepflicht Vorfälle (h)', type: 'number' },
    { key: 'LOG_RETENTION_DAYS', label: 'Log-Aufbewahrung (Tage)', type: 'number' },
    { key: 'SECURITY_LOG_RETENTION_DAYS', label: 'Sicherheits-Log (Tage)', type: 'number' },
  ],
  NDA: [
    { key: 'PURPOSE', label: 'Zweck', type: 'textarea', span: true },
    { key: 'DURATION_YEARS', label: 'Laufzeit (Jahre)', type: 'number' },
    { key: 'PENALTY_AMOUNT_EUR', label: 'Vertragsstrafe EUR (leer = keine)', type: 'number', nullable: true },
  ],
  CONSENT: [
    { key: 'WEBSITE_NAME', label: 'Website-Name' },
    { key: 'ANALYTICS_TOOLS', label: 'Analytics-Tools (leer = kein Block)', nullable: true },
    { key: 'MARKETING_PARTNERS', label: 'Marketing-Partner (leer = kein Block)', nullable: true },
  ],
  HOSTING: [
    { key: 'PROVIDER_NAME', label: 'Hosting-Anbieter' },
    { key: 'COUNTRY', label: 'Hosting-Land' },
    { key: 'CONTRACT_TYPE', label: 'Vertragstyp (z. B. AVV nach Art. 28 DSGVO)' },
  ],
  FEATURES: [
    // ── DSI / Cookie ─────────────────────────────────────────────────────────
    { key: 'CONSENT_WITHDRAWAL_PATH', label: 'Einwilligungs-Widerrufspfad' },
    { key: 'SECURITY_MEASURES_SUMMARY', label: 'Sicherheitsmaßnahmen (kurz)' },
    { key: 'DATA_SUBJECT_REQUEST_CHANNEL', label: 'Kanal für Betroffenenanfragen' },
    { key: 'HAS_THIRD_COUNTRY', label: 'Drittlandübermittlung möglich', type: 'boolean' },
    { key: 'TRANSFER_GUARDS', label: 'Garantien (z. B. SCC)' },
    // ── Cookie/Consent ───────────────────────────────────────────────────────
    { key: 'HAS_FUNCTIONAL_COOKIES', label: 'Funktionale Cookies aktiviert', type: 'boolean' },
    { key: 'CMP_NAME', label: 'Consent-Manager-Name (optional)' },
    { key: 'CMP_LOGS_CONSENTS', label: 'Consent-Protokollierung aktiv', type: 'boolean' },
    { key: 'ANALYTICS_TOOLS_DETAIL', label: 'Analyse-Tools (Detailtext)', type: 'textarea', span: true },
    { key: 'MARKETING_TOOLS_DETAIL', label: 'Marketing-Tools (Detailtext)', type: 'textarea', span: true },
    // ── Service-Features ─────────────────────────────────────────────────────
    { key: 'HAS_ACCOUNT', label: 'Nutzerkonten vorhanden', type: 'boolean' },
    { key: 'HAS_PAYMENTS', label: 'Zahlungsabwicklung vorhanden', type: 'boolean' },
    { key: 'PAYMENT_PROVIDER_DETAIL', label: 'Zahlungsanbieter (Detailtext)', type: 'textarea', span: true },
    { key: 'HAS_SUPPORT', label: 'Support-Funktion vorhanden', type: 'boolean' },
    { key: 'SUPPORT_CHANNELS_TEXT', label: 'Support-Kanäle / Zeiten' },
    { key: 'HAS_NEWSLETTER', label: 'Newsletter vorhanden', type: 'boolean' },
    { key: 'NEWSLETTER_PROVIDER_DETAIL', label: 'Newsletter-Anbieter (Detailtext)', type: 'textarea', span: true },
    { key: 'HAS_SOCIAL_MEDIA', label: 'Social-Media-Präsenz', type: 'boolean' },
    { key: 'SOCIAL_MEDIA_DETAIL', label: 'Social-Media-Details', type: 'textarea', span: true },
    // ── AGB ──────────────────────────────────────────────────────────────────
    { key: 'HAS_PAID_PLANS', label: 'Kostenpflichtige Pläne', type: 'boolean' },
    { key: 'PRICES_TEXT', label: 'Preise (Text/Link)', type: 'textarea', span: true },
    { key: 'PAYMENT_TERMS_TEXT', label: 'Zahlungsbedingungen', type: 'textarea', span: true },
    { key: 'CONTRACT_TERM_TEXT', label: 'Laufzeit & Kündigung', type: 'textarea', span: true },
    { key: 'HAS_SLA', label: 'SLA vorhanden', type: 'boolean' },
    { key: 'SLA_URL', label: 'SLA-URL' },
    { key: 'HAS_EXPORT_POLICY', label: 'Datenexport/Löschung geregelt', type: 'boolean' },
    { key: 'EXPORT_POLICY_TEXT', label: 'Datenexport-Regelung (Text)', type: 'textarea', span: true },
    { key: 'HAS_WITHDRAWAL', label: 'Widerrufsrecht (B2C digital)', type: 'boolean' },
    { key: 'CONSUMER_WITHDRAWAL_TEXT', label: 'Widerrufsbelehrung (Text)', type: 'textarea', span: true },
    { key: 'LIMITATION_CAP_TEXT', label: 'Haftungsdeckel B2B (Text)' },
    // ── Impressum ────────────────────────────────────────────────────────────
    { key: 'HAS_REGULATED_PROFESSION', label: 'Reglementierter Beruf', type: 'boolean' },
    { key: 'REGULATED_PROFESSION_TEXT', label: 'Berufsrecht-Text', type: 'textarea', span: true },
    { key: 'HAS_EDITORIAL_RESPONSIBLE', label: 'V.i.S.d.P. (redaktionell)', type: 'boolean' },
    { key: 'EDITORIAL_RESPONSIBLE_NAME', label: 'V.i.S.d.P. Name' },
    { key: 'EDITORIAL_RESPONSIBLE_ADDRESS', label: 'V.i.S.d.P. Adresse' },
    { key: 'HAS_DISPUTE_RESOLUTION', label: 'Streitbeilegungshinweis', type: 'boolean' },
    { key: 'DISPUTE_RESOLUTION_TEXT', label: 'Streitbeilegungstext', type: 'textarea', span: true },
  ],
}

// =============================================================================
// SMALL COMPONENTS
// =============================================================================

function LicenseBadge({ licenseId, small = false }: { licenseId: LicenseType | null; small?: boolean }) {
  if (!licenseId) return null
  const colors: Partial<Record<LicenseType, string>> = {
    public_domain: 'bg-green-100 text-green-700 border-green-200',
    cc0: 'bg-green-100 text-green-700 border-green-200',
    unlicense: 'bg-green-100 text-green-700 border-green-200',
    mit: 'bg-blue-100 text-blue-700 border-blue-200',
    cc_by_4: 'bg-purple-100 text-purple-700 border-purple-200',
    reuse_notice: 'bg-orange-100 text-orange-700 border-orange-200',
  }
  return (
    <span className={`${small ? 'px-1.5 py-0.5 text-[10px]' : 'px-2 py-1 text-xs'} rounded border ${colors[licenseId] || 'bg-gray-100 text-gray-600 border-gray-200'}`}>
      {LICENSE_TYPE_LABELS[licenseId] || licenseId}
    </span>
  )
}

// =============================================================================
// LIBRARY CARD
// =============================================================================

function LibraryCard({
  template,
  expanded,
  onTogglePreview,
  onUse,
}: {
  template: LegalTemplateResult
  expanded: boolean
  onTogglePreview: () => void
  onUse: () => void
}) {
  const typeLabel = template.templateType
    ? (TEMPLATE_TYPE_LABELS[template.templateType as TemplateType] || template.templateType)
    : null
  const placeholderCount = template.placeholders?.length ?? 0

  return (
    <div className="bg-white rounded-xl border border-gray-200 overflow-hidden hover:border-purple-300 transition-colors">
      <div className="p-4">
        <div className="flex items-start justify-between gap-2 mb-2">
          <h3 className="font-medium text-gray-900 text-sm leading-snug">
            {template.documentTitle || 'Vorlage'}
          </h3>
          <span className="text-xs text-gray-400 uppercase shrink-0">{template.language}</span>
        </div>
        <div className="flex items-center gap-2 flex-wrap mb-3">
          {typeLabel && (
            <span className="text-xs text-purple-600 bg-purple-50 px-2 py-0.5 rounded">
              {typeLabel}
            </span>
          )}
          <LicenseBadge licenseId={template.licenseId as LicenseType} small />
          {placeholderCount > 0 && (
            <span className="text-xs text-gray-500">{placeholderCount} Platzh.</span>
          )}
        </div>
        <div className="flex gap-2">
          <button
            onClick={onTogglePreview}
            className="flex-1 text-xs px-3 py-1.5 border border-gray-200 rounded-lg hover:bg-gray-50 text-gray-600 transition-colors"
          >
            {expanded ? 'Vorschau ▲' : 'Vorschau ▼'}
          </button>
          <button
            onClick={onUse}
            className="flex-1 text-xs px-3 py-1.5 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors"
          >
            Verwenden
          </button>
        </div>
      </div>

      {expanded && (
        <div className="border-t border-gray-100 bg-gray-50 p-4 max-h-[32rem] overflow-y-auto">
          <pre className="text-xs text-gray-600 whitespace-pre-wrap font-mono leading-relaxed">
            {template.text}
          </pre>
        </div>
      )}
    </div>
  )
}

// =============================================================================
// CONTEXT SECTION FORM
// =============================================================================

function ContextSectionForm({
  section,
  context,
  onChange,
}: {
  section: keyof TemplateContext
  context: TemplateContext
  onChange: (section: keyof TemplateContext, key: string, value: unknown) => void
}) {
  const fields = SECTION_FIELDS[section]
  const sectionData = context[section] as Record<string, unknown>

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
      {fields.map((field) => {
        const rawValue = sectionData[field.key]
        const inputCls = 'w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-purple-400'

        if (field.type === 'boolean') {
          return (
            <div key={field.key} className="flex items-center gap-2 py-2">
              <input
                type="checkbox"
                id={`${section}-${field.key}`}
                checked={!!rawValue}
                onChange={(e) => onChange(section, field.key, e.target.checked)}
                className="w-4 h-4 accent-purple-600"
              />
              <label htmlFor={`${section}-${field.key}`} className="text-sm text-gray-700">
                {field.label}
              </label>
            </div>
          )
        }

        if (field.type === 'select' && field.opts) {
          return (
            <div key={field.key} className={field.span ? 'md:col-span-2' : ''}>
              <label className="block text-xs text-gray-500 mb-1">{field.label}</label>
              <select
                value={String(rawValue ?? '')}
                onChange={(e) => onChange(section, field.key, e.target.value)}
                className={inputCls}
              >
                {field.opts.map((o) => <option key={o} value={o}>{o}</option>)}
              </select>
            </div>
          )
        }

        if (field.type === 'textarea') {
          return (
            <div key={field.key} className={field.span ? 'md:col-span-2' : ''}>
              <label className="block text-xs text-gray-500 mb-1">{field.label}</label>
              <textarea
                value={String(rawValue ?? '')}
                onChange={(e) => onChange(section, field.key, field.nullable && e.target.value === '' ? null : e.target.value)}
                rows={3}
                className={`${inputCls} resize-none`}
              />
            </div>
          )
        }

        if (field.type === 'number') {
          return (
            <div key={field.key} className={field.span ? 'md:col-span-2' : ''}>
              <label className="block text-xs text-gray-500 mb-1">{field.label}</label>
              <input
                type="number"
                value={rawValue === null || rawValue === undefined ? '' : String(rawValue)}
                onChange={(e) => {
                  const v = e.target.value
                  onChange(section, field.key, field.nullable && v === '' ? null : v === '' ? '' : Number(v))
                }}
                className={inputCls}
              />
            </div>
          )
        }

        // default: text / email
        return (
          <div key={field.key} className={field.span ? 'md:col-span-2' : ''}>
            <label className="block text-xs text-gray-500 mb-1">{field.label}</label>
            <input
              type={field.type === 'email' ? 'email' : 'text'}
              value={rawValue === null || rawValue === undefined ? '' : String(rawValue)}
              onChange={(e) => onChange(section, field.key, field.nullable && e.target.value === '' ? null : e.target.value)}
              className={inputCls}
            />
          </div>
        )
      })}
    </div>
  )
}

// =============================================================================
// GENERATOR SECTION
// =============================================================================

// Available module definitions (id → display label)
const MODULE_LABELS: Record<string, string> = {
  CLOUD_EXPORT_DELETE_DE: 'Datenexport & Löschrecht',
  B2C_WITHDRAWAL_DE: 'Widerrufsrecht (B2C)',
}

function GeneratorSection({
  template,
  context,
  onContextChange,
  extraPlaceholders,
  onExtraChange,
  onClose,
  enabledModules,
  onModuleToggle,
}: {
  template: LegalTemplateResult
  context: TemplateContext
  onContextChange: (section: keyof TemplateContext, key: string, value: unknown) => void
  extraPlaceholders: Record<string, string>
  onExtraChange: (key: string, value: string) => void
  onClose: () => void
  enabledModules: string[]
  onModuleToggle: (mod: string, checked: boolean) => void
}) {
  const [activeTab, setActiveTab] = useState<'placeholders' | 'preview'>('placeholders')
  const [expandedSections, setExpandedSections] = useState<Set<string>>(new Set(['PROVIDER', 'LEGAL']))

  const placeholders = template.placeholders || []
  const relevantSections = useMemo(() => getRelevantSections(placeholders), [placeholders])
  const uncovered = useMemo(() => getUncoveredPlaceholders(placeholders, context), [placeholders, context])
  const missing = useMemo(() => getMissingRequired(placeholders, context), [placeholders, context])

  // Rule engine evaluation
  const ruleResult = useMemo((): RuleEngineResult | null => {
    if (!template) return null
    return runRuleset({
      doc_type: getDocType(template.templateType ?? '', template.language ?? 'de'),
      render: { lang: template.language ?? 'de', variant: 'standard' },
      context,
      modules: { enabled: enabledModules },
    } satisfies RuleInput)
  }, [template, context, enabledModules])

  const allPlaceholderValues = useMemo(() => ({
    ...contextToPlaceholders(ruleResult?.contextAfterDefaults ?? context),
    ...extraPlaceholders,
  }), [context, extraPlaceholders, ruleResult])

  // Boolean context for {{#IF}} rendering
  const boolCtx = useMemo(
    () => ruleResult ? buildBoolContext(ruleResult.contextAfterDefaults, ruleResult.computedFlags) : {},
    [ruleResult]
  )

  const renderedContent = useMemo(() => {
    // 1. Remove ruleset-driven blocks ([BLOCK:ID])
    let content = applyBlockRemoval(template.text, ruleResult?.removedBlocks ?? [])
    // 2. Evaluate {{#IF}} / {{#IF_NOT}} / {{#IF_ANY}} directives
    content = applyConditionalBlocks(content, boolCtx)
    // 3. Substitute placeholders
    for (const [key, value] of Object.entries(allPlaceholderValues)) {
      if (value) {
        content = content.replace(new RegExp(key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), value)
      }
    }
    return content
  }, [template.text, allPlaceholderValues, ruleResult, boolCtx])

  // Compute which modules are relevant (mentioned in violations/warnings)
  const relevantModules = useMemo(() => {
    if (!ruleResult) return []
    const mentioned = new Set<string>()
    const allIssues = [...ruleResult.violations, ...ruleResult.warnings]
    for (const issue of allIssues) {
      if (issue.phase === 'module_requirements') {
        // Extract module ID from message
        for (const modId of Object.keys(MODULE_LABELS)) {
          if (issue.message.includes(modId)) mentioned.add(modId)
        }
      }
    }
    // Also show modules that are enabled but not mentioned
    for (const mod of enabledModules) {
      if (mod in MODULE_LABELS) mentioned.add(mod)
    }
    return [...mentioned]
  }, [ruleResult, enabledModules])

  const handleCopy = () => navigator.clipboard.writeText(renderedContent)

  const handleExportMarkdown = () => {
    const blob = new Blob([renderedContent], { type: 'text/markdown' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `${(template.documentTitle || 'dokument').replace(/\s+/g, '-').toLowerCase()}.md`
    a.click()
    URL.revokeObjectURL(url)
  }

  const toggleSection = (sec: string) => {
    setExpandedSections((prev) => {
      const next = new Set(prev)
      if (next.has(sec)) next.delete(sec)
      else next.add(sec)
      return next
    })
  }

  // Auto-expand all relevant sections on first render
  useEffect(() => {
    if (relevantSections.length > 0) {
      setExpandedSections(new Set(relevantSections))
    }
  }, [template.id]) // eslint-disable-line react-hooks/exhaustive-deps

  // Computed flags pills config
  const flagPills: { key: keyof typeof ruleResult.computedFlags; label: string; color: string }[] = ruleResult ? [
    { key: 'IS_B2C',          label: 'B2C',           color: 'bg-blue-100 text-blue-700' },
    { key: 'SERVICE_IS_SAAS', label: 'SaaS',           color: 'bg-green-100 text-green-700' },
    { key: 'HAS_PENALTY',     label: 'Vertragsstrafe', color: 'bg-orange-100 text-orange-700' },
    { key: 'HAS_ANALYTICS',   label: 'Analytics',      color: 'bg-gray-100 text-gray-600' },
  ] : []

  return (
    <div className="bg-white rounded-xl border-2 border-purple-300 overflow-hidden">
      {/* Header */}
      <div className="bg-purple-50 px-6 py-4 flex items-center justify-between">
        <div className="flex items-center gap-3 flex-wrap">
          <svg className="w-5 h-5 text-purple-600 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
          </svg>
          <div>
            <div className="text-xs text-purple-500 font-medium uppercase tracking-wide">Generator</div>
            <div className="font-semibold text-gray-900 text-sm">{template.documentTitle}</div>
          </div>
          {/* Computed flags pills */}
          {ruleResult && (
            <div className="flex gap-1.5 flex-wrap">
              {flagPills.map(({ key, label, color }) =>
                ruleResult.computedFlags[key] ? (
                  <span key={key} className={`px-2 py-0.5 text-[10px] font-medium rounded-full ${color}`}>
                    {label}
                  </span>
                ) : null
              )}
            </div>
          )}
        </div>
        <button onClick={onClose} className="text-gray-400 hover:text-gray-600 transition-colors shrink-0" aria-label="Schließen">
          <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
          </svg>
        </button>
      </div>

      {/* Tab bar */}
      <div className="flex border-b border-gray-200 px-6">
        {(['placeholders', 'preview'] as const).map((tab) => (
          <button
            key={tab}
            onClick={() => setActiveTab(tab)}
            className={`px-4 py-3 text-sm font-medium transition-colors border-b-2 -mb-px ${
              activeTab === tab
                ? 'text-purple-600 border-purple-600'
                : 'text-gray-500 border-transparent hover:text-gray-700'
            }`}
          >
            {tab === 'placeholders' ? 'Kontext ausfüllen' : 'Vorschau & Export'}
            {tab === 'placeholders' && missing.length > 0 && (
              <span className="ml-2 px-1.5 py-0.5 text-[10px] bg-orange-100 text-orange-600 rounded-full">
                {missing.length}
              </span>
            )}
            {tab === 'preview' && ruleResult && ruleResult.violations.length > 0 && (
              <span className="ml-2 px-1.5 py-0.5 text-[10px] bg-red-100 text-red-600 rounded-full">
                {ruleResult.violations.length}
              </span>
            )}
          </button>
        ))}
      </div>

      {/* Tab content */}
      <div className="p-6">
        {activeTab === 'placeholders' && (
          <div className="space-y-4">
            {placeholders.length === 0 ? (
              <div className="text-sm text-gray-500 text-center py-4">
                Keine Platzhalter — Vorlage kann direkt verwendet werden.
              </div>
            ) : (
              <>
                {/* Relevant sections */}
                {relevantSections.length === 0 ? (
                  <p className="text-sm text-gray-500">Alle Platzhalter müssen manuell befüllt werden.</p>
                ) : (
                  <div className="space-y-3">
                    {relevantSections.map((section) => (
                      <div key={section} className="border border-gray-200 rounded-xl overflow-hidden">
                        <button
                          onClick={() => toggleSection(section)}
                          className="w-full flex items-center justify-between px-4 py-3 bg-gray-50 hover:bg-gray-100 transition-colors text-left"
                        >
                          <span className="text-sm font-medium text-gray-800">{SECTION_LABELS[section]}</span>
                          <svg
                            className={`w-4 h-4 text-gray-400 transition-transform ${expandedSections.has(section) ? 'rotate-180' : ''}`}
                            fill="none" stroke="currentColor" viewBox="0 0 24 24"
                          >
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
                          </svg>
                        </button>
                        {expandedSections.has(section) && (
                          <div className="p-4 border-t border-gray-100">
                            <ContextSectionForm
                              section={section}
                              context={context}
                              onChange={onContextChange}
                            />
                          </div>
                        )}
                      </div>
                    ))}
                  </div>
                )}

                {/* Uncovered / manual placeholders */}
                {uncovered.length > 0 && (
                  <div className="border border-dashed border-gray-300 rounded-xl p-4">
                    <p className="text-xs font-medium text-gray-500 uppercase tracking-wide mb-3">
                      Weitere Platzhalter (manuell ausfüllen)
                    </p>
                    <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                      {uncovered.map((ph) => (
                        <div key={ph}>
                          <label className="block text-xs text-gray-500 mb-1 font-mono">{ph}</label>
                          <input
                            type="text"
                            value={extraPlaceholders[ph] || ''}
                            onChange={(e) => onExtraChange(ph, e.target.value)}
                            placeholder={`Wert für ${ph}`}
                            className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-purple-400"
                          />
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                {/* Module toggles */}
                {relevantModules.length > 0 && (
                  <div className="border border-gray-200 rounded-xl p-4">
                    <p className="text-xs font-medium text-gray-500 uppercase tracking-wide mb-3">Module</p>
                    <div className="space-y-2">
                      {relevantModules.map((modId) => (
                        <label key={modId} className="flex items-center gap-3 cursor-pointer">
                          <input
                            type="checkbox"
                            checked={enabledModules.includes(modId)}
                            onChange={(e) => onModuleToggle(modId, e.target.checked)}
                            className="w-4 h-4 accent-purple-600"
                          />
                          <span className="text-xs font-mono text-gray-600">{modId}</span>
                          {MODULE_LABELS[modId] && (
                            <span className="text-xs text-gray-500">{MODULE_LABELS[modId]}</span>
                          )}
                        </label>
                      ))}
                    </div>
                  </div>
                )}

                {/* Validation summary + CTA */}
                <div className="flex items-center justify-between pt-2 flex-wrap gap-3">
                  <div>
                    {missing.length > 0 ? (
                      <span className="text-sm text-orange-600">
                        ⚠ {missing.length} Pflichtfeld{missing.length > 1 ? 'er' : ''} fehlt{missing.length === 1 ? '' : 'en'}
                        <span className="ml-1 text-xs text-orange-400">
                          ({missing.map((m) => m.replace(/\{\{|\}\}/g, '')).slice(0, 3).join(', ')}{missing.length > 3 ? ` +${missing.length - 3}` : ''})
                        </span>
                      </span>
                    ) : (
                      <span className="text-sm text-green-600">Alle Pflichtfelder ausgefüllt</span>
                    )}
                  </div>
                  <button
                    onClick={() => setActiveTab('preview')}
                    className="px-5 py-2 bg-purple-600 text-white text-sm rounded-lg hover:bg-purple-700 transition-colors"
                  >
                    Zur Vorschau →
                  </button>
                </div>
              </>
            )}
          </div>
        )}

        {activeTab === 'preview' && (
          <div className="space-y-4">
            {/* Rule engine banners */}
            {ruleResult && ruleResult.violations.length > 0 && (
              <div className="bg-red-50 border border-red-200 rounded-xl p-4">
                <p className="text-sm font-semibold text-red-700 mb-2">
                  🔴 {ruleResult.violations.length} Fehler
                </p>
                <ul className="space-y-1">
                  {ruleResult.violations.map((v) => (
                    <li key={v.id} className="text-xs text-red-600">
                      <span className="font-mono font-medium">[{v.id}]</span> {v.message}
                    </li>
                  ))}
                </ul>
              </div>
            )}
            {ruleResult && ruleResult.warnings.filter((w) => w.id !== 'WARN_LEGAL_REVIEW').length > 0 && (
              <div className="bg-yellow-50 border border-yellow-200 rounded-xl p-4">
                <ul className="space-y-1">
                  {ruleResult.warnings
                    .filter((w) => w.id !== 'WARN_LEGAL_REVIEW')
                    .map((w) => (
                      <li key={w.id} className="text-xs text-yellow-700">
                        🟡 <span className="font-mono font-medium">[{w.id}]</span> {w.message}
                      </li>
                    ))}
                </ul>
              </div>
            )}
            {ruleResult && (
              <div className="bg-blue-50 border border-blue-200 rounded-xl p-3">
                <p className="text-xs text-blue-700">
                  ℹ️ Rechtlicher Hinweis: Diese Vorlage ist MIT-lizenziert. Vor Produktionseinsatz
                  wird eine rechtliche Überprüfung dringend empfohlen.
                </p>
              </div>
            )}
            {ruleResult && ruleResult.appliedDefaults.length > 0 && (
              <p className="text-xs text-gray-400">
                Defaults angewendet: {ruleResult.appliedDefaults.join(', ')}
              </p>
            )}

            <div className="flex items-center justify-between flex-wrap gap-2">
              <span className="text-sm text-gray-600">
                {missing.length > 0 && (
                  <span className="text-orange-600">
                    ⚠ {missing.length} Platzhalter noch nicht ausgefüllt
                  </span>
                )}
              </span>
              <div className="flex gap-2">
                <button
                  onClick={handleCopy}
                  className="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-gray-200 rounded-lg hover:bg-gray-50 text-gray-600 transition-colors"
                >
                  <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
                  </svg>
                  Kopieren
                </button>
                <button
                  onClick={handleExportMarkdown}
                  className="flex items-center gap-1.5 px-3 py-1.5 text-xs border border-gray-200 rounded-lg hover:bg-gray-50 text-gray-600 transition-colors"
                >
                  <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                  </svg>
                  Markdown
                </button>
                <button
                  onClick={() => window.print()}
                  className="flex items-center gap-1.5 px-4 py-1.5 text-xs bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors"
                >
                  <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
                  </svg>
                  PDF drucken
                </button>
              </div>
            </div>
            <div className="bg-gray-50 rounded-xl border border-gray-200 p-6 max-h-[600px] overflow-y-auto">
              <pre className="text-sm text-gray-800 whitespace-pre-wrap leading-relaxed font-sans">
                {renderedContent}
              </pre>
            </div>
            {template.attributionRequired && template.attributionText && (
              <div className="text-xs text-orange-600 bg-orange-50 p-3 rounded-lg border border-orange-200">
                <strong>Attribution erforderlich:</strong> {template.attributionText}
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  )
}

// =============================================================================
// MAIN PAGE
// =============================================================================

function DocumentGeneratorPageInner() {
  const { state } = useSDK()
  const { selectedDataPointsData } = useEinwilligungen()

  // Library state
  const [allTemplates, setAllTemplates] = useState<LegalTemplateResult[]>([])
  const [isLoadingLibrary, setIsLoadingLibrary] = useState(true)
  const [activeCategory, setActiveCategory] = useState<string>('all')
  const [activeLanguage, setActiveLanguage] = useState<'all' | 'de' | 'en'>('all')
  const [librarySearch, setLibrarySearch] = useState('')
  const [expandedPreviewId, setExpandedPreviewId] = useState<string | null>(null)

  // Generator state
  const [activeTemplate, setActiveTemplate] = useState<LegalTemplateResult | null>(null)
  const [context, setContext] = useState<TemplateContext>(EMPTY_CONTEXT)
  const [extraPlaceholders, setExtraPlaceholders] = useState<Record<string, string>>({})
  const [enabledModules, setEnabledModules] = useState<string[]>([])
  const generatorRef = useRef<HTMLDivElement>(null)

  const [totalCount, setTotalCount] = useState<number>(0)

  // Load all templates on mount
  useEffect(() => {
    setIsLoadingLibrary(true)
    loadAllTemplates(200).then((templates) => {
      setAllTemplates(templates)
      setTotalCount(templates.length)
      setIsLoadingLibrary(false)
    })
  }, [])

  // Pre-fill context from company profile + SDK state
  useEffect(() => {
    if (state?.companyProfile) {
      const profile = state.companyProfile
      const p = profile as Record<string, string>
      setContext((prev) => ({
        ...prev,
        PROVIDER: {
          ...prev.PROVIDER,
          LEGAL_NAME:      profile.companyName   || prev.PROVIDER.LEGAL_NAME,
          LEGAL_FORM:      p.legalForm           || prev.PROVIDER.LEGAL_FORM,
          ADDRESS_LINE:    p.addressLine         || prev.PROVIDER.ADDRESS_LINE,
          POSTAL_CODE:     p.postalCode          || prev.PROVIDER.POSTAL_CODE,
          CITY:            p.city                || prev.PROVIDER.CITY,
          COUNTRY:         p.country             || prev.PROVIDER.COUNTRY,
          EMAIL:           p.email               || prev.PROVIDER.EMAIL,
          PHONE:           p.phone               || prev.PROVIDER.PHONE,
          WEBSITE_URL:     p.websiteUrl          || prev.PROVIDER.WEBSITE_URL,
          CEO_NAME:        p.representedByName   || p.ceoName || prev.PROVIDER.CEO_NAME,
          REGISTER_COURT:  p.registerCourt       || prev.PROVIDER.REGISTER_COURT,
          REGISTER_NUMBER: p.registerNumber      || prev.PROVIDER.REGISTER_NUMBER,
          VAT_ID:          p.vatId               || prev.PROVIDER.VAT_ID,
        },
        PRIVACY: {
          ...prev.PRIVACY,
          DPO_NAME:  profile.dpoName  || prev.PRIVACY.DPO_NAME,
          DPO_EMAIL: profile.dpoEmail || prev.PRIVACY.DPO_EMAIL,
          CONTACT_EMAIL: profile.dpoEmail || prev.PRIVACY.CONTACT_EMAIL,
          SUPERVISORY_AUTHORITY_NAME:    p.supervisoryAuthorityName    || prev.PRIVACY.SUPERVISORY_AUTHORITY_NAME,
          SUPERVISORY_AUTHORITY_ADDRESS: p.supervisoryAuthorityAddress || prev.PRIVACY.SUPERVISORY_AUTHORITY_ADDRESS,
        },
        FEATURES: {
          ...prev.FEATURES,
          DATA_SUBJECT_REQUEST_CHANNEL: p.email
            ? `per E-Mail an ${p.email}`
            : prev.FEATURES.DATA_SUBJECT_REQUEST_CHANNEL,
        },
      }))
    }
  }, [state?.companyProfile])

  // Pre-fill extra placeholders from Einwilligungen data points
  useEffect(() => {
    if (selectedDataPointsData && selectedDataPointsData.length > 0) {
      const generated = generateAllPlaceholders(selectedDataPointsData, 'de')
      setExtraPlaceholders((prev) => ({ ...prev, ...generated }))
    }
  }, [selectedDataPointsData])

  // Filtered templates (computed)
  const filteredTemplates = useMemo(() => {
    const category = CATEGORIES.find((c) => c.key === activeCategory)
    return allTemplates.filter((t) => {
      if (category && category.types !== null) {
        if (!category.types.includes(t.templateType || '')) return false
      }
      if (activeLanguage !== 'all' && t.language !== activeLanguage) return false
      if (librarySearch.trim()) {
        const q = librarySearch.toLowerCase()
        const title = (t.documentTitle || '').toLowerCase()
        const type = (t.templateType || '').toLowerCase()
        if (!title.includes(q) && !type.includes(q)) return false
      }
      return true
    })
  }, [allTemplates, activeCategory, activeLanguage, librarySearch])

  const handleUseTemplate = useCallback((t: LegalTemplateResult) => {
    setActiveTemplate(t)
    setExpandedPreviewId(null)
    setExtraPlaceholders({})
    setEnabledModules([])
    setTimeout(() => {
      generatorRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
    }, 100)
  }, [])

  const handleContextChange = useCallback(
    (section: keyof TemplateContext, key: string, value: unknown) => {
      setContext((prev) => ({
        ...prev,
        [section]: { ...(prev[section] as Record<string, unknown>), [key]: value },
      }))
    },
    []
  )

  const handleInsertPlaceholder = useCallback((placeholder: string) => {
    if (!extraPlaceholders[placeholder]) {
      const generated = generateAllPlaceholders(selectedDataPointsData || [], 'de')
      const val = generated[placeholder as keyof typeof generated]
      if (val) {
        setExtraPlaceholders((prev) => ({ ...prev, [placeholder]: val }))
      }
    }
  }, [extraPlaceholders, selectedDataPointsData])

  const stepInfo = STEP_EXPLANATIONS['document-generator'] || {
    title: 'Dokumentengenerator',
    description: 'Generieren Sie rechtliche Dokumente aus lizenzkonformen Vorlagen',
    explanation: 'Der Dokumentengenerator nutzt frei lizenzierte Textbausteine um Datenschutzerklaerungen, AGB und andere rechtliche Dokumente zu erstellen.',
    tips: ['Wählen Sie eine Vorlage aus der Bibliothek aus', 'Füllen Sie die Platzhalter mit Ihren Unternehmensdaten'],
  }

  return (
    <div className="space-y-8">
      <StepHeader
        stepId="document-generator"
        title="Dokumentengenerator"
        description="Generieren Sie rechtliche Dokumente aus lizenzkonformen Vorlagen"
        explanation={stepInfo.explanation}
        tips={stepInfo.tips}
      />

      {/* Status bar */}
      <div className="grid grid-cols-3 gap-4">
        <div className="bg-white rounded-xl border border-gray-200 p-5">
          <div className="text-sm text-gray-500">Vorlagen gesamt</div>
          <div className="text-3xl font-bold text-gray-900">{totalCount}</div>
        </div>
        <div className="bg-white rounded-xl border border-gray-200 p-5">
          <div className="text-sm text-gray-500">Angezeigt</div>
          <div className="text-3xl font-bold text-purple-600">{filteredTemplates.length}</div>
        </div>
        <div className="bg-white rounded-xl border border-gray-200 p-5">
          <div className="text-sm text-gray-500">Aktive Vorlage</div>
          <div className="text-sm font-medium text-gray-900 mt-1 truncate">
            {activeTemplate ? activeTemplate.documentTitle : '—'}
          </div>
        </div>
      </div>

      {/* ================================================================= */}
      {/* SECTION 1: TEMPLATE-BIBLIOTHEK                                     */}
      {/* ================================================================= */}
      <div className="bg-white rounded-xl border border-gray-200 overflow-hidden">
        <div className="px-6 py-4 border-b border-gray-100 flex items-center justify-between flex-wrap gap-3">
          <h2 className="font-semibold text-gray-900">Template-Bibliothek</h2>
          <div className="flex items-center gap-1 bg-gray-100 rounded-lg p-1">
            {(['all', 'de', 'en'] as const).map((lang) => (
              <button
                key={lang}
                onClick={() => setActiveLanguage(lang)}
                className={`px-3 py-1.5 text-xs rounded-md font-medium transition-colors ${
                  activeLanguage === lang
                    ? 'bg-white text-gray-900 shadow-sm'
                    : 'text-gray-500 hover:text-gray-700'
                }`}
              >
                {lang === 'all' ? 'Alle' : lang.toUpperCase()}
              </button>
            ))}
          </div>
        </div>

        {/* Category pills */}
        <div className="px-6 py-3 border-b border-gray-100 flex gap-2 flex-wrap">
          {CATEGORIES.map((cat) => {
            const count = cat.types === null
              ? allTemplates.filter(t => activeLanguage === 'all' || t.language === activeLanguage).length
              : allTemplates.filter(t =>
                  cat.types!.includes(t.templateType || '') &&
                  (activeLanguage === 'all' || t.language === activeLanguage)
                ).length
            return (
              <button
                key={cat.key}
                onClick={() => setActiveCategory(cat.key)}
                className={`px-3 py-1.5 rounded-full text-xs font-medium transition-colors ${
                  activeCategory === cat.key
                    ? 'bg-purple-600 text-white'
                    : 'bg-gray-100 text-gray-600 hover:bg-gray-200'
                }`}
              >
                {cat.label}
                {count > 0 && (
                  <span className={`ml-1.5 ${activeCategory === cat.key ? 'text-purple-200' : 'text-gray-400'}`}>
                    {count}
                  </span>
                )}
              </button>
            )
          })}
        </div>

        {/* Search */}
        <div className="px-6 py-3 border-b border-gray-100">
          <div className="relative">
            <svg className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
            </svg>
            <input
              type="text"
              value={librarySearch}
              onChange={(e) => setLibrarySearch(e.target.value)}
              placeholder="Vorlage suchen... (optional)"
              className="w-full pl-9 pr-4 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-purple-400"
            />
            {librarySearch && (
              <button
                onClick={() => setLibrarySearch('')}
                className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
              >
                ×
              </button>
            )}
          </div>
        </div>

        {/* Template grid */}
        <div className="p-6">
          {isLoadingLibrary ? (
            <div className="flex items-center justify-center h-40">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-purple-600" />
            </div>
          ) : filteredTemplates.length === 0 ? (
            <div className="text-center py-12 text-gray-500">
              <div className="text-4xl mb-3">📄</div>
              <p>Keine Vorlagen für diese Auswahl</p>
            </div>
          ) : (
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
              {filteredTemplates.map((template) => (
                <LibraryCard
                  key={template.id}
                  template={template}
                  expanded={expandedPreviewId === template.id}
                  onTogglePreview={() =>
                    setExpandedPreviewId((prev) => (prev === template.id ? null : template.id))
                  }
                  onUse={() => handleUseTemplate(template)}
                />
              ))}
            </div>
          )}
        </div>
      </div>

      {/* ================================================================= */}
      {/* SECTION 2: GENERATOR (visible only when activeTemplate is set)     */}
      {/* ================================================================= */}
      {activeTemplate && (
        <div ref={generatorRef} className="space-y-6">
          <GeneratorSection
            template={activeTemplate}
            context={context}
            onContextChange={handleContextChange}
            extraPlaceholders={extraPlaceholders}
            onExtraChange={(key, value) => setExtraPlaceholders((prev) => ({ ...prev, [key]: value }))}
            onClose={() => setActiveTemplate(null)}
            enabledModules={enabledModules}
            onModuleToggle={(mod, checked) =>
              setEnabledModules((prev) =>
                checked ? [...prev, mod] : prev.filter((m) => m !== mod)
              )
            }
          />

          {selectedDataPointsData && selectedDataPointsData.length > 0 && (
            <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
              <div className="lg:col-span-2">
                <DocumentValidation
                  dataPoints={selectedDataPointsData}
                  documentContent={activeTemplate.text}
                  language="de"
                  onInsertPlaceholder={handleInsertPlaceholder}
                />
              </div>
              <div className="lg:col-span-1">
                <DataPointsPreview
                  dataPoints={selectedDataPointsData}
                  onInsertPlaceholder={handleInsertPlaceholder}
                  language="de"
                />
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  )
}

export default function DocumentGeneratorPage() {
  return (
    <EinwilligungenProvider>
      <DocumentGeneratorPageInner />
    </EinwilligungenProvider>
  )
}
