/**
 * Helper-Funktionen für die Integration von Einwilligungen-Datenpunkten
 * in den Dokumentengenerator.
 *
 * Diese Funktionen generieren DSGVO-konforme Textbausteine basierend auf
 * den vom Benutzer ausgewählten Datenpunkten.
 */

import {
  DataPoint,
  DataPointCategory,
  LegalBasis,
  RetentionPeriod,
  RiskLevel,
  CATEGORY_METADATA,
  LEGAL_BASIS_INFO,
  RETENTION_PERIOD_INFO,
  RISK_LEVEL_STYLING,
  LocalizedText,
  SupportedLanguage
} from '@/lib/sdk/einwilligungen/types'

// =============================================================================
// TYPES
// =============================================================================

/**
 * Sprach-Option für alle Helper-Funktionen
 */
export type Language = SupportedLanguage

/**
 * Generierte Platzhalter-Map für den Dokumentengenerator
 */
export interface DataPointPlaceholders {
  '[DATENPUNKTE_COUNT]': string
  '[DATENPUNKTE_LIST]': string
  '[DATENPUNKTE_TABLE]': string
  '[VERARBEITUNGSZWECKE]': string
  '[RECHTSGRUNDLAGEN]': string
  '[SPEICHERFRISTEN]': string
  '[EMPFAENGER]': string
  '[BESONDERE_KATEGORIEN]': string
  '[DRITTLAND_TRANSFERS]': string
  '[RISIKO_ZUSAMMENFASSUNG]': string
}

// =============================================================================
// HELPER FUNCTIONS
// =============================================================================

/**
 * Extrahiert Text aus LocalizedText basierend auf Sprache
 */
function getText(text: LocalizedText, lang: Language): string {
  return text[lang] || text.de
}

/**
 * Generiert eine Markdown-Tabelle der Datenpunkte
 *
 * @param dataPoints - Liste der ausgewählten Datenpunkte
 * @param lang - Sprache für die Ausgabe
 * @returns Markdown-Tabelle als String
 */
export function generateDataPointsTable(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): string {
  if (dataPoints.length === 0) {
    return lang === 'de'
      ? '*Keine Datenpunkte ausgewählt.*'
      : '*No data points selected.*'
  }

  const header = lang === 'de'
    ? '| Datenpunkt | Kategorie | Zweck | Rechtsgrundlage | Speicherfrist |'
    : '| Data Point | Category | Purpose | Legal Basis | Retention Period |'
  const separator = '|------------|-----------|-------|-----------------|---------------|'

  const rows = dataPoints.map(dp => {
    const category = CATEGORY_METADATA[dp.category]
    const legalBasis = LEGAL_BASIS_INFO[dp.legalBasis]
    const retention = RETENTION_PERIOD_INFO[dp.retentionPeriod]

    const name = getText(dp.name, lang)
    const categoryName = getText(category.name, lang)
    const purpose = getText(dp.purpose, lang)
    const legalBasisName = getText(legalBasis.name, lang)
    const retentionLabel = getText(retention.label, lang)

    // Truncate long texts for table readability
    const truncatedPurpose = purpose.length > 50 ? purpose.slice(0, 47) + '...' : purpose

    return `| ${name} | ${categoryName} | ${truncatedPurpose} | ${legalBasisName} | ${retentionLabel} |`
  }).join('\n')

  return `${header}\n${separator}\n${rows}`
}

/**
 * Gruppiert Datenpunkte nach Speicherfrist
 *
 * @param dataPoints - Liste der Datenpunkte
 * @returns Record mit Speicherfrist als Key und Datenpunkten als Value
 */
export function groupByRetention(
  dataPoints: DataPoint[]
): Record<RetentionPeriod, DataPoint[]> {
  return dataPoints.reduce((acc, dp) => {
    const key = dp.retentionPeriod
    if (!acc[key]) {
      acc[key] = []
    }
    acc[key].push(dp)
    return acc
  }, {} as Record<RetentionPeriod, DataPoint[]>)
}

/**
 * Gruppiert Datenpunkte nach Kategorie
 *
 * @param dataPoints - Liste der Datenpunkte
 * @returns Record mit Kategorie als Key und Datenpunkten als Value
 */
export function groupByCategory(
  dataPoints: DataPoint[]
): Record<DataPointCategory, DataPoint[]> {
  return dataPoints.reduce((acc, dp) => {
    const key = dp.category
    if (!acc[key]) {
      acc[key] = []
    }
    acc[key].push(dp)
    return acc
  }, {} as Record<DataPointCategory, DataPoint[]>)
}

/**
 * Generiert DSGVO-konformen Abschnitt für besondere Kategorien (Art. 9 DSGVO)
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param lang - Sprache für die Ausgabe
 * @returns Markdown-Abschnitt als String (leer wenn keine Art. 9 Daten)
 */
export function generateSpecialCategorySection(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): string {
  const special = dataPoints.filter(dp => dp.isSpecialCategory)

  if (special.length === 0) {
    return ''
  }

  if (lang === 'de') {
    const items = special.map(dp =>
      `- **${getText(dp.name, lang)}**: ${getText(dp.description, lang)}`
    ).join('\n')

    return `## Verarbeitung besonderer Kategorien personenbezogener Daten (Art. 9 DSGVO)

Wir verarbeiten folgende besondere Kategorien personenbezogener Daten:

${items}

Die Verarbeitung erfolgt auf Grundlage Ihrer ausdrücklichen Einwilligung gemäß Art. 9 Abs. 2 lit. a DSGVO. Sie können Ihre Einwilligung jederzeit mit Wirkung für die Zukunft widerrufen.`
  } else {
    const items = special.map(dp =>
      `- **${getText(dp.name, lang)}**: ${getText(dp.description, lang)}`
    ).join('\n')

    return `## Processing of Special Categories of Personal Data (Art. 9 GDPR)

We process the following special categories of personal data:

${items}

Processing is based on your explicit consent pursuant to Art. 9(2)(a) GDPR. You may withdraw your consent at any time with effect for the future.`
  }
}

/**
 * Generiert Liste aller eindeutigen Verarbeitungszwecke
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param lang - Sprache für die Ausgabe
 * @returns Kommaseparierte Liste der Zwecke
 */
export function generatePurposesList(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): string {
  const purposes = new Set<string>()

  dataPoints.forEach(dp => {
    purposes.add(getText(dp.purpose, lang))
  })

  return [...purposes].join(', ')
}

/**
 * Generiert Liste aller verwendeten Rechtsgrundlagen
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param lang - Sprache für die Ausgabe
 * @returns Formatierte Liste der Rechtsgrundlagen
 */
export function generateLegalBasisList(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): string {
  const bases = new Set<LegalBasis>()

  dataPoints.forEach(dp => {
    bases.add(dp.legalBasis)
  })

  return [...bases].map(basis => {
    const info = LEGAL_BASIS_INFO[basis]
    return `${info.article} (${getText(info.name, lang)})`
  }).join(', ')
}

/**
 * Generiert Liste aller Speicherfristen gruppiert
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param lang - Sprache für die Ausgabe
 * @returns Formatierte Liste der Speicherfristen mit zugehörigen Kategorien
 */
export function generateRetentionList(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): string {
  const grouped = groupByRetention(dataPoints)
  const entries: string[] = []

  for (const [period, points] of Object.entries(grouped)) {
    const retentionInfo = RETENTION_PERIOD_INFO[period as RetentionPeriod]
    const categories = [...new Set(points.map(p => getText(CATEGORY_METADATA[p.category].name, lang)))]

    entries.push(`${getText(retentionInfo.label, lang)}: ${categories.join(', ')}`)
  }

  return entries.join('; ')
}

/**
 * Generiert Liste aller Empfänger/Drittparteien
 *
 * @param dataPoints - Liste der Datenpunkte
 * @returns Kommaseparierte Liste der Empfänger
 */
export function generateRecipientsList(dataPoints: DataPoint[]): string {
  const recipients = new Set<string>()

  dataPoints.forEach(dp => {
    dp.thirdPartyRecipients?.forEach(r => recipients.add(r))
  })

  if (recipients.size === 0) {
    return ''
  }

  return [...recipients].join(', ')
}

/**
 * Generiert Abschnitt für Drittland-Übermittlungen
 *
 * @param dataPoints - Liste der Datenpunkte mit thirdCountryTransfer === true
 * @param lang - Sprache für die Ausgabe
 * @returns Markdown-Abschnitt als String
 */
export function generateThirdCountrySection(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): string {
  // Note: We assume dataPoints have been filtered for thirdCountryTransfer
  // The actual flag would need to be added to the DataPoint interface
  // For now, we check if any thirdPartyRecipients suggest third country
  const thirdCountryIndicators = ['Google', 'AWS', 'Microsoft', 'Meta', 'Facebook', 'Cloudflare']

  const thirdCountryPoints = dataPoints.filter(dp =>
    dp.thirdPartyRecipients?.some(r =>
      thirdCountryIndicators.some(indicator =>
        r.toLowerCase().includes(indicator.toLowerCase())
      )
    )
  )

  if (thirdCountryPoints.length === 0) {
    return ''
  }

  const recipients = new Set<string>()
  thirdCountryPoints.forEach(dp => {
    dp.thirdPartyRecipients?.forEach(r => {
      if (thirdCountryIndicators.some(i => r.toLowerCase().includes(i.toLowerCase()))) {
        recipients.add(r)
      }
    })
  })

  if (lang === 'de') {
    return `## Übermittlung in Drittländer

Wir übermitteln personenbezogene Daten an folgende Empfänger in Drittländern (außerhalb der EU/des EWR):

${[...recipients].map(r => `- ${r}`).join('\n')}

Die Übermittlung erfolgt auf Grundlage von Standardvertragsklauseln (Art. 46 Abs. 2 lit. c DSGVO) bzw. einem Angemessenheitsbeschluss der EU-Kommission (Art. 45 DSGVO).`
  } else {
    return `## Transfers to Third Countries

We transfer personal data to the following recipients in third countries (outside the EU/EEA):

${[...recipients].map(r => `- ${r}`).join('\n')}

The transfer is based on Standard Contractual Clauses (Art. 46(2)(c) GDPR) or an adequacy decision by the EU Commission (Art. 45 GDPR).`
  }
}

/**
 * Generiert Risiko-Zusammenfassung
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param lang - Sprache für die Ausgabe
 * @returns Formatierte Risiko-Zusammenfassung
 */
export function generateRiskSummary(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): string {
  const riskCounts: Record<RiskLevel, number> = {
    LOW: 0,
    MEDIUM: 0,
    HIGH: 0
  }

  dataPoints.forEach(dp => {
    riskCounts[dp.riskLevel]++
  })

  const parts = Object.entries(riskCounts)
    .filter(([, count]) => count > 0)
    .map(([level, count]) => {
      const styling = RISK_LEVEL_STYLING[level as RiskLevel]
      return `${count} ${getText(styling.label, lang).toLowerCase()}`
    })

  return parts.join(', ')
}

/**
 * Generiert alle Platzhalter für den Dokumentengenerator
 *
 * @param dataPoints - Liste der ausgewählten Datenpunkte
 * @param lang - Sprache für die Ausgabe
 * @returns Objekt mit allen Platzhaltern
 */
export function generateAllPlaceholders(
  dataPoints: DataPoint[],
  lang: Language = 'de'
): DataPointPlaceholders {
  return {
    '[DATENPUNKTE_COUNT]': String(dataPoints.length),
    '[DATENPUNKTE_LIST]': dataPoints.map(dp => getText(dp.name, lang)).join(', '),
    '[DATENPUNKTE_TABLE]': generateDataPointsTable(dataPoints, lang),
    '[VERARBEITUNGSZWECKE]': generatePurposesList(dataPoints, lang),
    '[RECHTSGRUNDLAGEN]': generateLegalBasisList(dataPoints, lang),
    '[SPEICHERFRISTEN]': generateRetentionList(dataPoints, lang),
    '[EMPFAENGER]': generateRecipientsList(dataPoints),
    '[BESONDERE_KATEGORIEN]': generateSpecialCategorySection(dataPoints, lang),
    '[DRITTLAND_TRANSFERS]': generateThirdCountrySection(dataPoints, lang),
    '[RISIKO_ZUSAMMENFASSUNG]': generateRiskSummary(dataPoints, lang)
  }
}

// =============================================================================
// VALIDATION HELPERS
// =============================================================================

/**
 * Validierungswarnung für den Dokumentengenerator
 */
export interface ValidationWarning {
  type: 'error' | 'warning' | 'info'
  code: string
  message: string
  suggestion: string
  affectedDataPoints?: DataPoint[]
}

/**
 * Prüft ob besondere Kategorien vorhanden sind aber kein entsprechender Abschnitt
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param documentContent - Der generierte Dokumentinhalt
 * @param lang - Sprache
 * @returns ValidationWarning oder null
 */
export function checkSpecialCategoriesWarning(
  dataPoints: DataPoint[],
  documentContent: string,
  lang: Language = 'de'
): ValidationWarning | null {
  const specialCategories = dataPoints.filter(dp => dp.isSpecialCategory)

  if (specialCategories.length === 0) {
    return null
  }

  const hasSection = lang === 'de'
    ? documentContent.includes('Art. 9') || documentContent.includes('Artikel 9') || documentContent.includes('besondere Kategorie')
    : documentContent.includes('Art. 9') || documentContent.includes('Article 9') || documentContent.includes('special categor')

  if (!hasSection) {
    return {
      type: 'error',
      code: 'MISSING_ART9_SECTION',
      message: lang === 'de'
        ? `${specialCategories.length} besondere Datenkategorien (Art. 9 DSGVO) ausgewählt, aber kein entsprechender Abschnitt im Dokument gefunden.`
        : `${specialCategories.length} special data categories (Art. 9 GDPR) selected, but no corresponding section found in document.`,
      suggestion: lang === 'de'
        ? 'Fügen Sie einen Abschnitt zu besonderen Kategorien personenbezogener Daten hinzu oder verwenden Sie [BESONDERE_KATEGORIEN] als Platzhalter.'
        : 'Add a section about special categories of personal data or use [BESONDERE_KATEGORIEN] as placeholder.',
      affectedDataPoints: specialCategories
    }
  }

  return null
}

/**
 * Prüft ob Drittland-Übermittlungen vorhanden sind aber keine SCC erwähnt werden
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param documentContent - Der generierte Dokumentinhalt
 * @param lang - Sprache
 * @returns ValidationWarning oder null
 */
export function checkThirdCountryWarning(
  dataPoints: DataPoint[],
  documentContent: string,
  lang: Language = 'de'
): ValidationWarning | null {
  const thirdCountryIndicators = ['Google', 'AWS', 'Microsoft', 'Meta', 'Facebook', 'Cloudflare', 'USA', 'US']

  const thirdCountryPoints = dataPoints.filter(dp =>
    dp.thirdPartyRecipients?.some(r =>
      thirdCountryIndicators.some(i => r.toLowerCase().includes(i.toLowerCase()))
    )
  )

  if (thirdCountryPoints.length === 0) {
    return null
  }

  const hasSCCMention = lang === 'de'
    ? documentContent.includes('Standardvertragsklauseln') || documentContent.includes('SCC') || documentContent.includes('Art. 46')
    : documentContent.includes('Standard Contractual Clauses') || documentContent.includes('SCC') || documentContent.includes('Art. 46')

  if (!hasSCCMention) {
    return {
      type: 'warning',
      code: 'MISSING_SCC_SECTION',
      message: lang === 'de'
        ? `Drittland-Übermittlung für ${thirdCountryPoints.length} Datenpunkte erkannt, aber keine Standardvertragsklauseln (SCC) erwähnt.`
        : `Third country transfer detected for ${thirdCountryPoints.length} data points, but no Standard Contractual Clauses (SCC) mentioned.`,
      suggestion: lang === 'de'
        ? 'Erwägen Sie die Aufnahme eines Abschnitts zu Drittland-Übermittlungen und Standardvertragsklauseln oder verwenden Sie [DRITTLAND_TRANSFERS] als Platzhalter.'
        : 'Consider adding a section about third country transfers and Standard Contractual Clauses or use [DRITTLAND_TRANSFERS] as placeholder.',
      affectedDataPoints: thirdCountryPoints
    }
  }

  return null
}

/**
 * Prüft ob Datenpunkte mit expliziter Einwilligung korrekt behandelt werden
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param documentContent - Der generierte Dokumentinhalt
 * @param lang - Sprache
 * @returns ValidationWarning oder null
 */
export function checkExplicitConsentWarning(
  dataPoints: DataPoint[],
  documentContent: string,
  lang: Language = 'de'
): ValidationWarning | null {
  const explicitConsentPoints = dataPoints.filter(dp => dp.requiresExplicitConsent)

  if (explicitConsentPoints.length === 0) {
    return null
  }

  const hasConsentSection = lang === 'de'
    ? documentContent.includes('Einwilligung') || documentContent.includes('Widerruf') || documentContent.includes('Art. 7')
    : documentContent.includes('consent') || documentContent.includes('withdraw') || documentContent.includes('Art. 7')

  if (!hasConsentSection) {
    return {
      type: 'warning',
      code: 'MISSING_CONSENT_SECTION',
      message: lang === 'de'
        ? `${explicitConsentPoints.length} Datenpunkte erfordern ausdrückliche Einwilligung, aber kein Abschnitt zu Einwilligung/Widerruf gefunden.`
        : `${explicitConsentPoints.length} data points require explicit consent, but no section about consent/withdrawal found.`,
      suggestion: lang === 'de'
        ? 'Fügen Sie einen Abschnitt zum Widerrufsrecht hinzu.'
        : 'Add a section about the right to withdraw consent.',
      affectedDataPoints: explicitConsentPoints
    }
  }

  return null
}

/**
 * Führt alle Validierungsprüfungen durch
 *
 * @param dataPoints - Liste der Datenpunkte
 * @param documentContent - Der generierte Dokumentinhalt
 * @param lang - Sprache
 * @returns Array aller Warnungen
 */
export function validateDocument(
  dataPoints: DataPoint[],
  documentContent: string,
  lang: Language = 'de'
): ValidationWarning[] {
  const warnings: ValidationWarning[] = []

  const specialCatWarning = checkSpecialCategoriesWarning(dataPoints, documentContent, lang)
  if (specialCatWarning) warnings.push(specialCatWarning)

  const thirdCountryWarning = checkThirdCountryWarning(dataPoints, documentContent, lang)
  if (thirdCountryWarning) warnings.push(thirdCountryWarning)

  const consentWarning = checkExplicitConsentWarning(dataPoints, documentContent, lang)
  if (consentWarning) warnings.push(consentWarning)

  return warnings
}
