// =============================================================================
// Loeschfristen Module - Profiling Wizard
// 4-Step Profiling (15 Fragen) zur Generierung von Baseline-Loeschrichtlinien
// =============================================================================

import type { LoeschfristPolicy, StorageLocation } from './loeschfristen-types'
import { BASELINE_TEMPLATES, type BaselineTemplate, templateToPolicy } from './loeschfristen-baseline-catalog'

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

export type ProfilingStepId = 'organization' | 'data-categories' | 'systems' | 'special'

export interface ProfilingQuestion {
  id: string
  step: ProfilingStepId
  question: string // German
  helpText?: string
  type: 'single' | 'multi' | 'boolean' | 'number'
  options?: { value: string; label: string }[]
  required: boolean
}

export interface ProfilingAnswer {
  questionId: string
  value: string | string[] | boolean | number
}

export interface ProfilingStep {
  id: ProfilingStepId
  title: string
  description: string
  questions: ProfilingQuestion[]
}

export interface ProfilingResult {
  matchedTemplates: BaselineTemplate[]
  generatedPolicies: LoeschfristPolicy[]
  additionalStorageLocations: StorageLocation[]
  hasLegalHoldRequirement: boolean
}

// =============================================================================
// PROFILING STEPS (4 Steps, 15 Questions)
// =============================================================================

export const PROFILING_STEPS: ProfilingStep[] = [
  // =========================================================================
  // Step 1: Organisation (4 Fragen)
  // =========================================================================
  {
    id: 'organization',
    title: 'Organisation',
    description: 'Allgemeine Informationen zu Ihrem Unternehmen, um branchenspezifische Loeschfristen zu ermitteln.',
    questions: [
      {
        id: 'org-branche',
        step: 'organization',
        question: 'In welcher Branche ist Ihr Unternehmen taetig?',
        helpText: 'Die Branche bestimmt, welche branchenspezifischen Aufbewahrungspflichten relevant sind.',
        type: 'single',
        options: [
          { value: 'it-software', label: 'IT / Software' },
          { value: 'handel', label: 'Handel' },
          { value: 'dienstleistung', label: 'Dienstleistung' },
          { value: 'gesundheitswesen', label: 'Gesundheitswesen' },
          { value: 'bildung', label: 'Bildung' },
          { value: 'fertigung-industrie', label: 'Fertigung / Industrie' },
          { value: 'finanzwesen', label: 'Finanzwesen' },
          { value: 'oeffentlicher-sektor', label: 'Oeffentlicher Sektor' },
          { value: 'sonstige', label: 'Sonstige' },
        ],
        required: true,
      },
      {
        id: 'org-mitarbeiter',
        step: 'organization',
        question: 'Wie viele Mitarbeiter hat Ihr Unternehmen?',
        helpText: 'Die Unternehmensgroesse beeinflusst den Umfang der erforderlichen Loeschkonzepte.',
        type: 'single',
        options: [
          { value: '<10', label: 'Weniger als 10' },
          { value: '10-49', label: '10 bis 49' },
          { value: '50-249', label: '50 bis 249' },
          { value: '250+', label: '250 und mehr' },
        ],
        required: true,
      },
      {
        id: 'org-geschaeftsmodell',
        step: 'organization',
        question: 'Welches Geschaeftsmodell verfolgen Sie?',
        helpText: 'B2B und B2C haben unterschiedliche Anforderungen an die Datenhaltung.',
        type: 'single',
        options: [
          { value: 'b2b', label: 'B2B (Geschaeftskunden)' },
          { value: 'b2c', label: 'B2C (Endkunden)' },
          { value: 'beides', label: 'Beides (B2B und B2C)' },
        ],
        required: true,
      },
      {
        id: 'org-website',
        step: 'organization',
        question: 'Betreiben Sie eine Website oder Online-Praesenz?',
        helpText: 'Websites erzeugen Webserver-Logs und erfordern Cookie-Consent-Verwaltung.',
        type: 'boolean',
        required: true,
      },
    ],
  },

  // =========================================================================
  // Step 2: Datenkategorien (5 Fragen)
  // =========================================================================
  {
    id: 'data-categories',
    title: 'Datenkategorien',
    description: 'Welche Arten personenbezogener Daten verarbeiten Sie? Dies bestimmt die relevanten Aufbewahrungsfristen.',
    questions: [
      {
        id: 'data-hr',
        step: 'data-categories',
        question: 'Verarbeiten Sie HR-/Personaldaten (Personalakten, Gehaltsabrechnungen, Zeiterfassung)?',
        helpText: 'Personalakten unterliegen umfangreichen gesetzlichen Aufbewahrungspflichten (bis zu 10 Jahre).',
        type: 'boolean',
        required: true,
      },
      {
        id: 'data-buchhaltung',
        step: 'data-categories',
        question: 'Fuehren Sie eine Buchhaltung mit Finanzdaten (Rechnungen, Belege, Steuererklarungen)?',
        helpText: 'Buchhaltungsunterlagen muessen gemaess HGB und AO bis zu 10 Jahre aufbewahrt werden.',
        type: 'boolean',
        required: true,
      },
      {
        id: 'data-vertraege',
        step: 'data-categories',
        question: 'Verwalten Sie Vertraege mit Kunden oder Lieferanten?',
        helpText: 'Vertragsunterlagen und Geschaeftsbriefe haben spezifische Aufbewahrungspflichten.',
        type: 'boolean',
        required: true,
      },
      {
        id: 'data-marketing',
        step: 'data-categories',
        question: 'Betreiben Sie Marketing-Aktivitaeten (Newsletter, CRM-Kampagnen)?',
        helpText: 'Marketing-Einwilligungen und Kontakthistorien muessen dokumentiert und verwaltet werden.',
        type: 'boolean',
        required: true,
      },
      {
        id: 'data-video',
        step: 'data-categories',
        question: 'Setzen Sie Videoueberwachung ein?',
        helpText: 'Videoueberwachungsdaten haben besonders kurze Loeschfristen (in der Regel 72 Stunden).',
        type: 'boolean',
        required: true,
      },
    ],
  },

  // =========================================================================
  // Step 3: Systeme (3 Fragen)
  // =========================================================================
  {
    id: 'systems',
    title: 'Systeme & Infrastruktur',
    description: 'Welche IT-Systeme und Infrastruktur nutzen Sie? Dies beeinflusst die Speicherorte in Ihrem Loeschkonzept.',
    questions: [
      {
        id: 'sys-cloud',
        step: 'systems',
        question: 'Nutzen Sie Cloud-Dienste zur Datenspeicherung oder -verarbeitung?',
        helpText: 'Cloud-Speicherorte muessen in den Loeschrichtlinien als separate Speicherorte dokumentiert werden.',
        type: 'boolean',
        required: true,
      },
      {
        id: 'sys-backup',
        step: 'systems',
        question: 'Haben Sie Backup-Systeme im Einsatz?',
        helpText: 'Backups erfordern eine eigene Loeschstrategie, da Daten dort nach der primaeren Loeschung weiter existieren koennen.',
        type: 'boolean',
        required: true,
      },
      {
        id: 'sys-erp',
        step: 'systems',
        question: 'Setzen Sie ein ERP- oder CRM-System ein?',
        helpText: 'ERP-/CRM-Systeme sind haeufig zentrale Speicherorte fuer Kunden- und Geschaeftsdaten.',
        type: 'boolean',
        required: true,
      },
    ],
  },

  // =========================================================================
  // Step 4: Spezielle Anforderungen (3 Fragen)
  // =========================================================================
  {
    id: 'special',
    title: 'Spezielle Anforderungen',
    description: 'Gibt es besondere rechtliche oder organisatorische Anforderungen, die Ihr Loeschkonzept beeinflussen?',
    questions: [
      {
        id: 'special-legal-hold',
        step: 'special',
        question: 'Gibt es Legal-Hold-Anforderungen (z.B. laufende Rechtsstreitigkeiten, behoerdliche Untersuchungen)?',
        helpText: 'Bei einem Legal Hold muessen betroffene Daten trotz abgelaufener Loeschfristen aufbewahrt werden.',
        type: 'boolean',
        required: true,
      },
      {
        id: 'special-archivierung',
        step: 'special',
        question: 'Benoetigen Sie eine Langzeitarchivierung von Dokumenten?',
        helpText: 'Langzeitarchivierung kann ueber die gesetzlichen Mindestfristen hinausgehen und erfordert eine gesonderte Rechtfertigung.',
        type: 'boolean',
        required: true,
      },
      {
        id: 'special-gesundheit',
        step: 'special',
        question: 'Verarbeiten Sie Gesundheitsdaten (z.B. Krankmeldungen, Arbeitsmedizin)?',
        helpText: 'Gesundheitsdaten sind besonders schuetzenswerte Daten nach Art. 9 DSGVO und unterliegen strengeren Anforderungen.',
        type: 'boolean',
        required: true,
      },
    ],
  },
]

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

/**
 * Retrieve the value of a specific answer by question ID.
 */
export function getAnswerValue(answers: ProfilingAnswer[], questionId: string): unknown {
  const answer = answers.find(a => a.questionId === questionId)
  return answer?.value ?? undefined
}

/**
 * Check whether all required questions in a given step have been answered.
 */
export function isStepComplete(answers: ProfilingAnswer[], stepId: ProfilingStepId): boolean {
  const step = PROFILING_STEPS.find(s => s.id === stepId)
  if (!step) return false

  return step.questions
    .filter(q => q.required)
    .every(q => {
      const answer = answers.find(a => a.questionId === q.id)
      if (!answer) return false

      // Check that the value is not empty
      const val = answer.value
      if (val === undefined || val === null) return false
      if (typeof val === 'string' && val.trim() === '') return false
      if (Array.isArray(val) && val.length === 0) return false

      return true
    })
}

/**
 * Calculate overall profiling progress as a percentage (0-100).
 */
export function getProfilingProgress(answers: ProfilingAnswer[]): number {
  const totalRequired = PROFILING_STEPS.reduce(
    (sum, step) => sum + step.questions.filter(q => q.required).length,
    0
  )
  if (totalRequired === 0) return 100

  const answeredRequired = PROFILING_STEPS.reduce((sum, step) => {
    return (
      sum +
      step.questions.filter(q => q.required).filter(q => {
        const answer = answers.find(a => a.questionId === q.id)
        if (!answer) return false
        const val = answer.value
        if (val === undefined || val === null) return false
        if (typeof val === 'string' && val.trim() === '') return false
        if (Array.isArray(val) && val.length === 0) return false
        return true
      }).length
    )
  }, 0)

  return Math.round((answeredRequired / totalRequired) * 100)
}

// =============================================================================
// CORE GENERATOR
// =============================================================================

/**
 * Generate deletion policies based on the profiling answers.
 *
 * Logic:
 * - Match baseline templates based on boolean and categorical answers
 * - Deduplicate matched templates by templateId
 * - Convert matched templates to full LoeschfristPolicy objects
 * - Add additional storage locations (Cloud, Backup) if applicable
 * - Detect legal hold requirements
 */
export function generatePoliciesFromProfile(answers: ProfilingAnswer[]): ProfilingResult {
  const matchedTemplateIds = new Set<string>()

  // -------------------------------------------------------------------------
  // Helper to get a boolean answer
  // -------------------------------------------------------------------------
  const getBool = (questionId: string): boolean => {
    const val = getAnswerValue(answers, questionId)
    return val === true
  }

  const getString = (questionId: string): string => {
    const val = getAnswerValue(answers, questionId)
    return typeof val === 'string' ? val : ''
  }

  // -------------------------------------------------------------------------
  // Always-included templates (universally recommended)
  // -------------------------------------------------------------------------
  matchedTemplateIds.add('protokolle-gesellschafter')

  // -------------------------------------------------------------------------
  // HR data (data-hr = true)
  // -------------------------------------------------------------------------
  if (getBool('data-hr')) {
    matchedTemplateIds.add('personal-akten')
    matchedTemplateIds.add('gehaltsabrechnungen')
    matchedTemplateIds.add('zeiterfassung')
    matchedTemplateIds.add('bewerbungsunterlagen')
    matchedTemplateIds.add('krankmeldungen')
  }

  // -------------------------------------------------------------------------
  // Buchhaltung (data-buchhaltung = true)
  // -------------------------------------------------------------------------
  if (getBool('data-buchhaltung')) {
    matchedTemplateIds.add('buchhaltungsbelege')
    matchedTemplateIds.add('rechnungen')
    matchedTemplateIds.add('steuererklaerungen')
  }

  // -------------------------------------------------------------------------
  // Vertraege (data-vertraege = true)
  // -------------------------------------------------------------------------
  if (getBool('data-vertraege')) {
    matchedTemplateIds.add('vertraege')
    matchedTemplateIds.add('geschaeftsbriefe')
    matchedTemplateIds.add('kundenstammdaten')
  }

  // -------------------------------------------------------------------------
  // Marketing (data-marketing = true)
  // -------------------------------------------------------------------------
  if (getBool('data-marketing')) {
    matchedTemplateIds.add('newsletter-einwilligungen')
    matchedTemplateIds.add('crm-kontakthistorie')
    matchedTemplateIds.add('cookie-consent-logs')
  }

  // -------------------------------------------------------------------------
  // Video (data-video = true)
  // -------------------------------------------------------------------------
  if (getBool('data-video')) {
    matchedTemplateIds.add('videoueberwachung')
  }

  // -------------------------------------------------------------------------
  // Website (org-website = true)
  // -------------------------------------------------------------------------
  if (getBool('org-website')) {
    matchedTemplateIds.add('webserver-logs')
    matchedTemplateIds.add('cookie-consent-logs')
  }

  // -------------------------------------------------------------------------
  // ERP/CRM (sys-erp = true)
  // -------------------------------------------------------------------------
  if (getBool('sys-erp')) {
    matchedTemplateIds.add('kundenstammdaten')
    matchedTemplateIds.add('crm-kontakthistorie')
  }

  // -------------------------------------------------------------------------
  // Backup (sys-backup = true)
  // -------------------------------------------------------------------------
  if (getBool('sys-backup')) {
    matchedTemplateIds.add('backup-daten')
  }

  // -------------------------------------------------------------------------
  // Gesundheitsdaten (special-gesundheit = true)
  // -------------------------------------------------------------------------
  if (getBool('special-gesundheit')) {
    // Ensure krankmeldungen is included even without full HR data
    matchedTemplateIds.add('krankmeldungen')
  }

  // -------------------------------------------------------------------------
  // Resolve matched templates from catalog
  // -------------------------------------------------------------------------
  const matchedTemplates: BaselineTemplate[] = []
  for (const templateId of matchedTemplateIds) {
    const template = BASELINE_TEMPLATES.find(t => t.templateId === templateId)
    if (template) {
      matchedTemplates.push(template)
    }
  }

  // -------------------------------------------------------------------------
  // Convert to policies
  // -------------------------------------------------------------------------
  const generatedPolicies: LoeschfristPolicy[] = matchedTemplates.map(template =>
    templateToPolicy(template)
  )

  // -------------------------------------------------------------------------
  // Additional storage locations
  // -------------------------------------------------------------------------
  const additionalStorageLocations: StorageLocation[] = []

  if (getBool('sys-cloud')) {
    const cloudLocation: StorageLocation = {
      id: crypto.randomUUID(),
      name: 'Cloud-Speicher',
      type: 'CLOUD',
      isBackup: false,
      provider: null,
      deletionCapable: true,
    }
    additionalStorageLocations.push(cloudLocation)

    // Add Cloud storage location to all generated policies
    for (const policy of generatedPolicies) {
      policy.storageLocations.push({ ...cloudLocation, id: crypto.randomUUID() })
    }
  }

  if (getBool('sys-backup')) {
    const backupLocation: StorageLocation = {
      id: crypto.randomUUID(),
      name: 'Backup-System',
      type: 'BACKUP',
      isBackup: true,
      provider: null,
      deletionCapable: true,
    }
    additionalStorageLocations.push(backupLocation)

    // Add Backup storage location to all generated policies
    for (const policy of generatedPolicies) {
      policy.storageLocations.push({ ...backupLocation, id: crypto.randomUUID() })
    }
  }

  // -------------------------------------------------------------------------
  // Legal Hold
  // -------------------------------------------------------------------------
  const hasLegalHoldRequirement = getBool('special-legal-hold')

  // If legal hold is active, mark all generated policies accordingly
  if (hasLegalHoldRequirement) {
    for (const policy of generatedPolicies) {
      policy.hasActiveLegalHold = true
      policy.deletionTrigger = 'LEGAL_HOLD'
    }
  }

  // -------------------------------------------------------------------------
  // Tag policies with profiling metadata
  // -------------------------------------------------------------------------
  const branche = getString('org-branche')
  const mitarbeiter = getString('org-mitarbeiter')

  for (const policy of generatedPolicies) {
    policy.tags = [
      ...policy.tags,
      'profiling-generated',
      ...(branche ? [`branche:${branche}`] : []),
      ...(mitarbeiter ? [`groesse:${mitarbeiter}`] : []),
    ]
  }

  return {
    matchedTemplates,
    generatedPolicies,
    additionalStorageLocations,
    hasLegalHoldRequirement,
  }
}

// =============================================================================
// COMPLIANCE SCOPE INTEGRATION
// =============================================================================

/**
 * Prefill Loeschfristen profiling answers from Compliance Scope Engine answers.
 * The Scope Engine acts as the "Single Source of Truth" for organizational questions.
 */
export function prefillFromScopeAnswers(
  scopeAnswers: import('./compliance-scope-types').ScopeProfilingAnswer[]
): ProfilingAnswer[] {
  const { exportToLoeschfristenAnswers } = require('./compliance-scope-profiling')
  const exported = exportToLoeschfristenAnswers(scopeAnswers) as Array<{ questionId: string; value: unknown }>
  return exported.map(item => ({
    questionId: item.questionId,
    value: item.value as string | string[] | boolean | number,
  }))
}

/**
 * Get the list of Loeschfristen question IDs that are prefilled from Scope answers.
 * These questions should show "Aus Scope-Analyse uebernommen" hint.
 */
export const SCOPE_PREFILLED_LF_QUESTIONS = [
  'org-branche',
  'org-mitarbeiter',
  'org-geschaeftsmodell',
  'org-website',
  'data-hr',
  'data-buchhaltung',
  'data-vertraege',
  'data-marketing',
  'data-video',
  'sys-cloud',
  'sys-erp',
]
