/**
 * VVT Export Utilities
 *
 * Functions for generating Art. 30 DSGVO compliant
 * Verarbeitungsverzeichnis (VVT) exports.
 */

import type {
  ProcessingActivity,
  Organization,
  LocalizedText,
  LegalBasis,
  DataSubjectCategory,
  PersonalDataCategory,
  RecipientCategory,
  ThirdCountryTransfer,
  RetentionPeriod,
} from '../types'

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

export interface VVTExportOptions {
  activities: ProcessingActivity[]
  organization: Organization
  language: 'de' | 'en'
  format: 'PDF' | 'DOCX' | 'XLSX'
  includeAnnexes?: boolean
  includeRiskAssessment?: boolean
  watermark?: string
}

export interface VVTExportResult {
  success: boolean
  filename: string
  mimeType: string
  content: Uint8Array | string
  metadata: {
    activityCount: number
    generatedAt: Date
    language: string
    organization: string
  }
}

export interface VVTRow {
  vvtId: string
  name: string
  responsible: string
  purposes: string[]
  legalBasis: string[]
  dataSubjects: string[]
  personalData: string[]
  recipients: string[]
  thirdCountryTransfers: string[]
  retentionPeriod: string
  technicalMeasures: string[]
  dpiaRequired: string
  status: string
}

// ==========================================
// CONSTANTS
// ==========================================

const DATA_SUBJECT_LABELS: Record<DataSubjectCategory, LocalizedText> = {
  EMPLOYEES: { de: 'Beschäftigte', en: 'Employees' },
  APPLICANTS: { de: 'Bewerber', en: 'Job Applicants' },
  CUSTOMERS: { de: 'Kunden', en: 'Customers' },
  PROSPECTIVE_CUSTOMERS: { de: 'Interessenten', en: 'Prospective Customers' },
  SUPPLIERS: { de: 'Lieferanten', en: 'Suppliers' },
  BUSINESS_PARTNERS: { de: 'Geschäftspartner', en: 'Business Partners' },
  VISITORS: { de: 'Besucher', en: 'Visitors' },
  WEBSITE_USERS: { de: 'Website-Nutzer', en: 'Website Users' },
  APP_USERS: { de: 'App-Nutzer', en: 'App Users' },
  NEWSLETTER_SUBSCRIBERS: { de: 'Newsletter-Abonnenten', en: 'Newsletter Subscribers' },
  MEMBERS: { de: 'Mitglieder', en: 'Members' },
  PATIENTS: { de: 'Patienten', en: 'Patients' },
  STUDENTS: { de: 'Schüler/Studenten', en: 'Students' },
  MINORS: { de: 'Minderjährige', en: 'Minors' },
  OTHER: { de: 'Sonstige', en: 'Other' },
}

const PERSONAL_DATA_LABELS: Record<PersonalDataCategory, LocalizedText> = {
  NAME: { de: 'Name', en: 'Name' },
  CONTACT: { de: 'Kontaktdaten', en: 'Contact Data' },
  ADDRESS: { de: 'Adressdaten', en: 'Address' },
  DOB: { de: 'Geburtsdatum', en: 'Date of Birth' },
  ID_NUMBER: { de: 'Ausweisnummern', en: 'ID Numbers' },
  SOCIAL_SECURITY: { de: 'Sozialversicherungsnummer', en: 'Social Security Number' },
  TAX_ID: { de: 'Steuer-ID', en: 'Tax ID' },
  BANK_ACCOUNT: { de: 'Bankverbindung', en: 'Bank Account' },
  PAYMENT_DATA: { de: 'Zahlungsdaten', en: 'Payment Data' },
  EMPLOYMENT_DATA: { de: 'Beschäftigungsdaten', en: 'Employment Data' },
  SALARY_DATA: { de: 'Gehaltsdaten', en: 'Salary Data' },
  EDUCATION_DATA: { de: 'Bildungsdaten', en: 'Education Data' },
  PHOTO_VIDEO: { de: 'Fotos/Videos', en: 'Photos/Videos' },
  IP_ADDRESS: { de: 'IP-Adressen', en: 'IP Addresses' },
  DEVICE_ID: { de: 'Geräte-Kennungen', en: 'Device IDs' },
  LOCATION_DATA: { de: 'Standortdaten', en: 'Location Data' },
  USAGE_DATA: { de: 'Nutzungsdaten', en: 'Usage Data' },
  COMMUNICATION_DATA: { de: 'Kommunikationsdaten', en: 'Communication Data' },
  CONTRACT_DATA: { de: 'Vertragsdaten', en: 'Contract Data' },
  LOGIN_DATA: { de: 'Login-Daten', en: 'Login Data' },
  HEALTH_DATA: { de: 'Gesundheitsdaten (Art. 9)', en: 'Health Data (Art. 9)' },
  GENETIC_DATA: { de: 'Genetische Daten (Art. 9)', en: 'Genetic Data (Art. 9)' },
  BIOMETRIC_DATA: { de: 'Biometrische Daten (Art. 9)', en: 'Biometric Data (Art. 9)' },
  RACIAL_ETHNIC: { de: 'Rassische/Ethnische Herkunft (Art. 9)', en: 'Racial/Ethnic Origin (Art. 9)' },
  POLITICAL_OPINIONS: { de: 'Politische Meinungen (Art. 9)', en: 'Political Opinions (Art. 9)' },
  RELIGIOUS_BELIEFS: { de: 'Religiöse Überzeugungen (Art. 9)', en: 'Religious Beliefs (Art. 9)' },
  TRADE_UNION: { de: 'Gewerkschaftszugehörigkeit (Art. 9)', en: 'Trade Union Membership (Art. 9)' },
  SEX_LIFE: { de: 'Sexualleben/Orientierung (Art. 9)', en: 'Sex Life/Orientation (Art. 9)' },
  CRIMINAL_DATA: { de: 'Strafrechtliche Daten (Art. 10)', en: 'Criminal Data (Art. 10)' },
  OTHER: { de: 'Sonstige', en: 'Other' },
}

const LEGAL_BASIS_LABELS: Record<string, LocalizedText> = {
  CONSENT: { de: 'Einwilligung (Art. 6 Abs. 1 lit. a)', en: 'Consent (Art. 6(1)(a))' },
  CONTRACT: { de: 'Vertragserfüllung (Art. 6 Abs. 1 lit. b)', en: 'Contract (Art. 6(1)(b))' },
  LEGAL_OBLIGATION: { de: 'Rechtliche Verpflichtung (Art. 6 Abs. 1 lit. c)', en: 'Legal Obligation (Art. 6(1)(c))' },
  VITAL_INTEREST: { de: 'Lebenswichtige Interessen (Art. 6 Abs. 1 lit. d)', en: 'Vital Interests (Art. 6(1)(d))' },
  PUBLIC_TASK: { de: 'Öffentliche Aufgabe (Art. 6 Abs. 1 lit. e)', en: 'Public Task (Art. 6(1)(e))' },
  LEGITIMATE_INTEREST: { de: 'Berechtigtes Interesse (Art. 6 Abs. 1 lit. f)', en: 'Legitimate Interest (Art. 6(1)(f))' },
}

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

export function getLocalizedText(text: LocalizedText | undefined, lang: 'de' | 'en'): string {
  if (!text) return ''
  return text[lang] || text.de || ''
}

export function formatDataSubjects(categories: DataSubjectCategory[], lang: 'de' | 'en'): string[] {
  return categories.map((cat) => DATA_SUBJECT_LABELS[cat]?.[lang] || cat)
}

export function formatPersonalData(categories: PersonalDataCategory[], lang: 'de' | 'en'): string[] {
  return categories.map((cat) => PERSONAL_DATA_LABELS[cat]?.[lang] || cat)
}

export function formatLegalBasis(bases: LegalBasis[], lang: 'de' | 'en'): string[] {
  return bases.map((basis) => {
    const label = LEGAL_BASIS_LABELS[basis.type]?.[lang] || basis.type
    return basis.description ? `${label}: ${basis.description}` : label
  })
}

export function formatRecipients(recipients: RecipientCategory[], lang: 'de' | 'en'): string[] {
  return recipients.map((r) => {
    const suffix = r.isThirdCountry && r.country ? ` (${r.country})` : ''
    return r.name + suffix
  })
}

export function formatTransfers(transfers: ThirdCountryTransfer[], lang: 'de' | 'en'): string[] {
  const labels: Record<string, LocalizedText> = {
    ADEQUACY_DECISION: { de: 'Angemessenheitsbeschluss', en: 'Adequacy Decision' },
    SCC_CONTROLLER: { de: 'SCC (C2C)', en: 'SCC (C2C)' },
    SCC_PROCESSOR: { de: 'SCC (C2P)', en: 'SCC (C2P)' },
    BCR: { de: 'BCR', en: 'BCR' },
  }

  return transfers.map((t) => {
    const mechanism = labels[t.transferMechanism]?.[lang] || t.transferMechanism
    return `${t.country}: ${t.recipient} (${mechanism})`
  })
}

export function formatRetention(retention: RetentionPeriod | undefined, lang: 'de' | 'en'): string {
  if (!retention) return lang === 'de' ? 'Nicht festgelegt' : 'Not specified'

  // If description is available, use it
  if (retention.description) {
    const desc = retention.description[lang] || retention.description.de
    if (desc) return desc
  }

  // Otherwise build from duration
  if (!retention.duration) {
    return lang === 'de' ? 'Nicht festgelegt' : 'Not specified'
  }

  const periodLabels: Record<string, LocalizedText> = {
    DAYS: { de: 'Tage', en: 'days' },
    MONTHS: { de: 'Monate', en: 'months' },
    YEARS: { de: 'Jahre', en: 'years' },
  }

  const unit = periodLabels[retention.durationUnit || 'YEARS'][lang]
  let result = `${retention.duration} ${unit}`

  if (retention.legalBasis) {
    result += ` (${retention.legalBasis})`
  }

  return result
}

// ==========================================
// EXPORT FUNCTIONS
// ==========================================

/**
 * Transform processing activities to VVT rows for export
 */
export function transformToVVTRows(
  activities: ProcessingActivity[],
  lang: 'de' | 'en'
): VVTRow[] {
  return activities.map((activity) => ({
    vvtId: activity.vvtId,
    name: getLocalizedText(activity.name, lang),
    responsible: activity.responsible.organizationName,
    purposes: activity.purposes.map((p) => getLocalizedText(p, lang)),
    legalBasis: formatLegalBasis(activity.legalBasis, lang),
    dataSubjects: formatDataSubjects(activity.dataSubjectCategories, lang),
    personalData: formatPersonalData(activity.personalDataCategories, lang),
    recipients: formatRecipients(activity.recipientCategories, lang),
    thirdCountryTransfers: formatTransfers(activity.thirdCountryTransfers, lang),
    retentionPeriod: formatRetention(activity.retentionPeriod, lang),
    technicalMeasures: activity.technicalMeasures,
    dpiaRequired: activity.dpiaRequired
      ? lang === 'de'
        ? 'Ja'
        : 'Yes'
      : lang === 'de'
      ? 'Nein'
      : 'No',
    status: activity.status,
  }))
}

/**
 * Generate VVT as JSON (for further processing)
 */
export function generateVVTJson(options: VVTExportOptions): VVTExportResult {
  const rows = transformToVVTRows(options.activities, options.language)

  const exportData = {
    metadata: {
      organization: options.organization.name,
      generatedAt: new Date().toISOString(),
      language: options.language,
      activityCount: rows.length,
      version: '1.0',
      gdprArticle: 'Art. 30 DSGVO',
    },
    responsible: {
      name: options.organization.name,
      legalForm: options.organization.legalForm,
      address: options.organization.address,
      dpo: options.organization.dpoContact,
    },
    activities: rows,
  }

  const content = JSON.stringify(exportData, null, 2)

  return {
    success: true,
    filename: `VVT_${options.organization.name.replace(/\s+/g, '_')}_${new Date().toISOString().slice(0, 10)}.json`,
    mimeType: 'application/json',
    content,
    metadata: {
      activityCount: rows.length,
      generatedAt: new Date(),
      language: options.language,
      organization: options.organization.name,
    },
  }
}

/**
 * Generate VVT CSV content (for Excel compatibility)
 */
export function generateVVTCsv(options: VVTExportOptions): string {
  const rows = transformToVVTRows(options.activities, options.language)
  const lang = options.language

  const headers = lang === 'de'
    ? [
        'VVT-Nr.',
        'Bezeichnung',
        'Verantwortlicher',
        'Zwecke',
        'Rechtsgrundlage',
        'Betroffene',
        'Datenkategorien',
        'Empfänger',
        'Drittlandtransfers',
        'Löschfristen',
        'TOM',
        'DSFA erforderlich',
        'Status',
      ]
    : [
        'VVT ID',
        'Name',
        'Responsible',
        'Purposes',
        'Legal Basis',
        'Data Subjects',
        'Data Categories',
        'Recipients',
        'Third Country Transfers',
        'Retention Period',
        'Technical Measures',
        'DPIA Required',
        'Status',
      ]

  const csvRows = rows.map((row) => [
    row.vvtId,
    row.name,
    row.responsible,
    row.purposes.join('; '),
    row.legalBasis.join('; '),
    row.dataSubjects.join('; '),
    row.personalData.join('; '),
    row.recipients.join('; '),
    row.thirdCountryTransfers.join('; '),
    row.retentionPeriod,
    row.technicalMeasures.join('; '),
    row.dpiaRequired,
    row.status,
  ])

  const escape = (val: string) => `"${val.replace(/"/g, '""')}"`

  return [
    headers.map(escape).join(','),
    ...csvRows.map((row) => row.map(escape).join(',')),
  ].join('\n')
}

/**
 * Check if activities have special category data (Art. 9)
 */
export function hasSpecialCategoryData(activities: ProcessingActivity[]): boolean {
  const specialCategories: PersonalDataCategory[] = [
    'HEALTH_DATA',
    'GENETIC_DATA',
    'BIOMETRIC_DATA',
    'RACIAL_ETHNIC',
    'POLITICAL_OPINIONS',
    'RELIGIOUS_BELIEFS',
    'TRADE_UNION',
    'SEX_LIFE',
  ]

  return activities.some((activity) =>
    activity.personalDataCategories.some((cat) => specialCategories.includes(cat))
  )
}

/**
 * Check if activities have third country transfers
 */
export function hasThirdCountryTransfers(activities: ProcessingActivity[]): boolean {
  return activities.some((activity) => activity.thirdCountryTransfers.length > 0)
}

/**
 * Generate compliance summary for VVT
 */
export function generateComplianceSummary(
  activities: ProcessingActivity[],
  lang: 'de' | 'en'
): {
  totalActivities: number
  byStatus: Record<string, number>
  withSpecialCategories: number
  withThirdCountryTransfers: number
  dpiaRequired: number
  issues: string[]
} {
  const byStatus: Record<string, number> = {}
  let withSpecialCategories = 0
  let withThirdCountryTransfers = 0
  let dpiaRequired = 0
  const issues: string[] = []

  for (const activity of activities) {
    // Count by status
    byStatus[activity.status] = (byStatus[activity.status] || 0) + 1

    // Check for special categories
    if (
      activity.personalDataCategories.some((cat) =>
        [
          'HEALTH_DATA',
          'GENETIC_DATA',
          'BIOMETRIC_DATA',
          'RACIAL_ETHNIC',
          'POLITICAL_OPINIONS',
          'RELIGIOUS_BELIEFS',
          'TRADE_UNION',
          'SEX_LIFE',
        ].includes(cat)
      )
    ) {
      withSpecialCategories++
    }

    // Check for third country transfers
    if (activity.thirdCountryTransfers.length > 0) {
      withThirdCountryTransfers++
    }

    // Check DPIA
    if (activity.dpiaRequired) {
      dpiaRequired++
    }

    // Check for issues
    if (activity.legalBasis.length === 0) {
      issues.push(
        lang === 'de'
          ? `${activity.vvtId}: Keine Rechtsgrundlage angegeben`
          : `${activity.vvtId}: No legal basis specified`
      )
    }

    if (!activity.retentionPeriod) {
      issues.push(
        lang === 'de'
          ? `${activity.vvtId}: Keine Löschfrist angegeben`
          : `${activity.vvtId}: No retention period specified`
      )
    }
  }

  return {
    totalActivities: activities.length,
    byStatus,
    withSpecialCategories,
    withThirdCountryTransfers,
    dpiaRequired,
    issues,
  }
}
