// =============================================================================
// TOM Generator DOCX Export
// Export TOMs to Microsoft Word format
// =============================================================================

import {
  TOMGeneratorState,
  DerivedTOM,
  ControlCategory,
  CONTROL_CATEGORIES,
} from '../types'
import { getControlById, getCategoryMetadata } from '../controls/loader'

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

export interface DOCXExportOptions {
  language: 'de' | 'en'
  includeNotApplicable: boolean
  includeEvidence: boolean
  includeGapAnalysis: boolean
  companyLogo?: string
  primaryColor?: string
}

const DEFAULT_OPTIONS: DOCXExportOptions = {
  language: 'de',
  includeNotApplicable: false,
  includeEvidence: true,
  includeGapAnalysis: true,
  primaryColor: '#1a56db',
}

// =============================================================================
// DOCX CONTENT GENERATION
// =============================================================================

export interface DocxParagraph {
  type: 'paragraph' | 'heading1' | 'heading2' | 'heading3' | 'bullet'
  content: string
  style?: Record<string, string>
}

export interface DocxTableRow {
  cells: string[]
  isHeader?: boolean
}

export interface DocxTable {
  type: 'table'
  headers: string[]
  rows: DocxTableRow[]
}

export type DocxElement = DocxParagraph | DocxTable

/**
 * Generate DOCX content structure for TOMs
 */
export function generateDOCXContent(
  state: TOMGeneratorState,
  options: Partial<DOCXExportOptions> = {}
): DocxElement[] {
  const opts = { ...DEFAULT_OPTIONS, ...options }
  const elements: DocxElement[] = []

  // Title page
  elements.push({
    type: 'heading1',
    content: opts.language === 'de'
      ? 'Technische und Organisatorische Maßnahmen (TOMs)'
      : 'Technical and Organizational Measures (TOMs)',
  })

  elements.push({
    type: 'paragraph',
    content: opts.language === 'de'
      ? `gemäß Art. 32 DSGVO`
      : 'according to Art. 32 GDPR',
  })

  // Company info
  if (state.companyProfile) {
    elements.push({
      type: 'heading2',
      content: opts.language === 'de' ? 'Unternehmen' : 'Company',
    })

    elements.push({
      type: 'paragraph',
      content: `${state.companyProfile.name}`,
    })

    elements.push({
      type: 'paragraph',
      content: opts.language === 'de'
        ? `Branche: ${state.companyProfile.industry}`
        : `Industry: ${state.companyProfile.industry}`,
    })

    elements.push({
      type: 'paragraph',
      content: opts.language === 'de'
        ? `Rolle: ${formatRole(state.companyProfile.role, opts.language)}`
        : `Role: ${formatRole(state.companyProfile.role, opts.language)}`,
    })

    if (state.companyProfile.dpoPerson) {
      elements.push({
        type: 'paragraph',
        content: opts.language === 'de'
          ? `Datenschutzbeauftragter: ${state.companyProfile.dpoPerson}`
          : `Data Protection Officer: ${state.companyProfile.dpoPerson}`,
      })
    }
  }

  // Document metadata
  elements.push({
    type: 'paragraph',
    content: opts.language === 'de'
      ? `Stand: ${new Date().toLocaleDateString('de-DE')}`
      : `Date: ${new Date().toLocaleDateString('en-US')}`,
  })

  // Protection level summary
  if (state.riskProfile) {
    elements.push({
      type: 'heading2',
      content: opts.language === 'de' ? 'Schutzbedarf' : 'Protection Level',
    })

    elements.push({
      type: 'paragraph',
      content: opts.language === 'de'
        ? `Ermittelter Schutzbedarf: ${formatProtectionLevel(state.riskProfile.protectionLevel, opts.language)}`
        : `Determined Protection Level: ${formatProtectionLevel(state.riskProfile.protectionLevel, opts.language)}`,
    })

    elements.push({
      type: 'paragraph',
      content: opts.language === 'de'
        ? `CIA-Bewertung: Vertraulichkeit ${state.riskProfile.ciaAssessment.confidentiality}/5, Integrität ${state.riskProfile.ciaAssessment.integrity}/5, Verfügbarkeit ${state.riskProfile.ciaAssessment.availability}/5`
        : `CIA Assessment: Confidentiality ${state.riskProfile.ciaAssessment.confidentiality}/5, Integrity ${state.riskProfile.ciaAssessment.integrity}/5, Availability ${state.riskProfile.ciaAssessment.availability}/5`,
    })

    if (state.riskProfile.dsfaRequired) {
      elements.push({
        type: 'paragraph',
        content: opts.language === 'de'
          ? '⚠️ Eine Datenschutz-Folgenabschätzung (DSFA) ist erforderlich.'
          : '⚠️ A Data Protection Impact Assessment (DPIA) is required.',
      })
    }
  }

  // TOMs by category
  elements.push({
    type: 'heading2',
    content: opts.language === 'de'
      ? 'Übersicht der Maßnahmen'
      : 'Measures Overview',
  })

  // Group TOMs by category
  const tomsByCategory = groupTOMsByCategory(state.derivedTOMs, opts.includeNotApplicable)

  for (const category of CONTROL_CATEGORIES) {
    const categoryTOMs = tomsByCategory.get(category.id)
    if (!categoryTOMs || categoryTOMs.length === 0) continue

    const categoryName = category.name[opts.language]
    elements.push({
      type: 'heading3',
      content: `${categoryName} (${category.gdprReference})`,
    })

    // Create table for this category
    const tableHeaders = opts.language === 'de'
      ? ['ID', 'Maßnahme', 'Typ', 'Status', 'Anwendbarkeit']
      : ['ID', 'Measure', 'Type', 'Status', 'Applicability']

    const tableRows: DocxTableRow[] = categoryTOMs.map((tom) => ({
      cells: [
        tom.controlId,
        tom.name,
        formatType(getControlById(tom.controlId)?.type || 'TECHNICAL', opts.language),
        formatImplementationStatus(tom.implementationStatus, opts.language),
        formatApplicability(tom.applicability, opts.language),
      ],
    }))

    elements.push({
      type: 'table',
      headers: tableHeaders,
      rows: tableRows,
    })

    // Add detailed descriptions
    for (const tom of categoryTOMs) {
      if (tom.applicability === 'NOT_APPLICABLE' && !opts.includeNotApplicable) {
        continue
      }

      elements.push({
        type: 'paragraph',
        content: `**${tom.controlId}: ${tom.name}**`,
      })

      elements.push({
        type: 'paragraph',
        content: tom.aiGeneratedDescription || tom.description,
      })

      elements.push({
        type: 'bullet',
        content: opts.language === 'de'
          ? `Anwendbarkeit: ${formatApplicability(tom.applicability, opts.language)}`
          : `Applicability: ${formatApplicability(tom.applicability, opts.language)}`,
      })

      elements.push({
        type: 'bullet',
        content: opts.language === 'de'
          ? `Begründung: ${tom.applicabilityReason}`
          : `Reason: ${tom.applicabilityReason}`,
      })

      elements.push({
        type: 'bullet',
        content: opts.language === 'de'
          ? `Umsetzungsstatus: ${formatImplementationStatus(tom.implementationStatus, opts.language)}`
          : `Implementation Status: ${formatImplementationStatus(tom.implementationStatus, opts.language)}`,
      })

      if (tom.responsiblePerson) {
        elements.push({
          type: 'bullet',
          content: opts.language === 'de'
            ? `Verantwortlich: ${tom.responsiblePerson}`
            : `Responsible: ${tom.responsiblePerson}`,
        })
      }

      if (opts.includeEvidence && tom.linkedEvidence.length > 0) {
        elements.push({
          type: 'bullet',
          content: opts.language === 'de'
            ? `Nachweise: ${tom.linkedEvidence.length} Dokument(e) verknüpft`
            : `Evidence: ${tom.linkedEvidence.length} document(s) linked`,
        })
      }

      if (tom.evidenceGaps.length > 0) {
        elements.push({
          type: 'bullet',
          content: opts.language === 'de'
            ? `Fehlende Nachweise: ${tom.evidenceGaps.join(', ')}`
            : `Missing Evidence: ${tom.evidenceGaps.join(', ')}`,
        })
      }
    }
  }

  // Gap Analysis
  if (opts.includeGapAnalysis && state.gapAnalysis) {
    elements.push({
      type: 'heading2',
      content: opts.language === 'de' ? 'Lückenanalyse' : 'Gap Analysis',
    })

    elements.push({
      type: 'paragraph',
      content: opts.language === 'de'
        ? `Gesamtscore: ${state.gapAnalysis.overallScore}%`
        : `Overall Score: ${state.gapAnalysis.overallScore}%`,
    })

    if (state.gapAnalysis.missingControls.length > 0) {
      elements.push({
        type: 'heading3',
        content: opts.language === 'de'
          ? 'Fehlende Maßnahmen'
          : 'Missing Measures',
      })

      for (const missing of state.gapAnalysis.missingControls) {
        const control = getControlById(missing.controlId)
        elements.push({
          type: 'bullet',
          content: `${missing.controlId}: ${control?.name[opts.language] || 'Unknown'} (${missing.priority})`,
        })
      }
    }

    if (state.gapAnalysis.recommendations.length > 0) {
      elements.push({
        type: 'heading3',
        content: opts.language === 'de' ? 'Empfehlungen' : 'Recommendations',
      })

      for (const rec of state.gapAnalysis.recommendations) {
        elements.push({
          type: 'bullet',
          content: rec,
        })
      }
    }
  }

  // Footer
  elements.push({
    type: 'paragraph',
    content: opts.language === 'de'
      ? `Dieses Dokument wurde automatisch generiert mit dem TOM Generator am ${new Date().toLocaleDateString('de-DE')}.`
      : `This document was automatically generated with the TOM Generator on ${new Date().toLocaleDateString('en-US')}.`,
  })

  return elements
}

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

function groupTOMsByCategory(
  toms: DerivedTOM[],
  includeNotApplicable: boolean
): Map<ControlCategory, DerivedTOM[]> {
  const grouped = new Map<ControlCategory, DerivedTOM[]>()

  for (const tom of toms) {
    if (!includeNotApplicable && tom.applicability === 'NOT_APPLICABLE') {
      continue
    }

    const control = getControlById(tom.controlId)
    if (!control) continue

    const category = control.category
    const existing = grouped.get(category) || []
    existing.push(tom)
    grouped.set(category, existing)
  }

  return grouped
}

function formatRole(role: string, language: 'de' | 'en'): string {
  const roles: Record<string, Record<'de' | 'en', string>> = {
    CONTROLLER: { de: 'Verantwortlicher', en: 'Controller' },
    PROCESSOR: { de: 'Auftragsverarbeiter', en: 'Processor' },
    JOINT_CONTROLLER: { de: 'Gemeinsam Verantwortlicher', en: 'Joint Controller' },
  }
  return roles[role]?.[language] || role
}

function formatProtectionLevel(level: string, language: 'de' | 'en'): string {
  const levels: Record<string, Record<'de' | 'en', string>> = {
    NORMAL: { de: 'Normal', en: 'Normal' },
    HIGH: { de: 'Hoch', en: 'High' },
    VERY_HIGH: { de: 'Sehr hoch', en: 'Very High' },
  }
  return levels[level]?.[language] || level
}

function formatType(type: string, language: 'de' | 'en'): string {
  const types: Record<string, Record<'de' | 'en', string>> = {
    TECHNICAL: { de: 'Technisch', en: 'Technical' },
    ORGANIZATIONAL: { de: 'Organisatorisch', en: 'Organizational' },
  }
  return types[type]?.[language] || type
}

function formatImplementationStatus(status: string, language: 'de' | 'en'): string {
  const statuses: Record<string, Record<'de' | 'en', string>> = {
    NOT_IMPLEMENTED: { de: 'Nicht umgesetzt', en: 'Not Implemented' },
    PARTIAL: { de: 'Teilweise umgesetzt', en: 'Partially Implemented' },
    IMPLEMENTED: { de: 'Umgesetzt', en: 'Implemented' },
  }
  return statuses[status]?.[language] || status
}

function formatApplicability(applicability: string, language: 'de' | 'en'): string {
  const apps: Record<string, Record<'de' | 'en', string>> = {
    REQUIRED: { de: 'Erforderlich', en: 'Required' },
    RECOMMENDED: { de: 'Empfohlen', en: 'Recommended' },
    OPTIONAL: { de: 'Optional', en: 'Optional' },
    NOT_APPLICABLE: { de: 'Nicht anwendbar', en: 'Not Applicable' },
  }
  return apps[applicability]?.[language] || applicability
}

// =============================================================================
// DOCX BLOB GENERATION
// Uses simple XML structure compatible with docx libraries
// =============================================================================

/**
 * Generate a DOCX file as a Blob
 * Note: For production, use docx library (npm install docx)
 * This is a simplified version that generates XML-based content
 */
export async function generateDOCXBlob(
  state: TOMGeneratorState,
  options: Partial<DOCXExportOptions> = {}
): Promise<Blob> {
  const content = generateDOCXContent(state, options)

  // Generate simple HTML that can be converted to DOCX
  // In production, use the docx library for proper DOCX generation
  const html = generateHTMLFromContent(content, options)

  // Return as a Word-compatible HTML blob
  // The proper way would be to use the docx library
  const blob = new Blob([html], {
    type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  })

  return blob
}

function generateHTMLFromContent(
  content: DocxElement[],
  options: Partial<DOCXExportOptions>
): string {
  const opts = { ...DEFAULT_OPTIONS, ...options }

  let html = `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <style>
    body { font-family: Calibri, Arial, sans-serif; font-size: 11pt; line-height: 1.5; }
    h1 { font-size: 24pt; color: ${opts.primaryColor}; border-bottom: 2px solid ${opts.primaryColor}; }
    h2 { font-size: 18pt; color: ${opts.primaryColor}; margin-top: 24pt; }
    h3 { font-size: 14pt; color: #333; margin-top: 18pt; }
    table { border-collapse: collapse; width: 100%; margin: 12pt 0; }
    th, td { border: 1px solid #ddd; padding: 8pt; text-align: left; }
    th { background-color: ${opts.primaryColor}; color: white; }
    tr:nth-child(even) { background-color: #f9f9f9; }
    ul { margin: 6pt 0; }
    li { margin: 3pt 0; }
    .warning { color: #dc2626; font-weight: bold; }
  </style>
</head>
<body>
`

  for (const element of content) {
    if (element.type === 'table') {
      html += '<table>'
      html += '<tr>'
      for (const header of element.headers) {
        html += `<th>${escapeHtml(header)}</th>`
      }
      html += '</tr>'
      for (const row of element.rows) {
        html += '<tr>'
        for (const cell of row.cells) {
          html += `<td>${escapeHtml(cell)}</td>`
        }
        html += '</tr>'
      }
      html += '</table>'
    } else {
      const tag = getHtmlTag(element.type)
      const processedContent = processContent(element.content)
      html += `<${tag}>${processedContent}</${tag}>\n`
    }
  }

  html += '</body></html>'
  return html
}

function getHtmlTag(type: string): string {
  switch (type) {
    case 'heading1':
      return 'h1'
    case 'heading2':
      return 'h2'
    case 'heading3':
      return 'h3'
    case 'bullet':
      return 'li'
    default:
      return 'p'
  }
}

function escapeHtml(text: string): string {
  return text
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;')
}

function processContent(content: string): string {
  // Convert markdown-style bold to HTML
  return escapeHtml(content).replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
}

// =============================================================================
// FILENAME GENERATION
// =============================================================================

/**
 * Generate a filename for the DOCX export
 */
export function generateDOCXFilename(
  state: TOMGeneratorState,
  language: 'de' | 'en' = 'de'
): string {
  const companyName = state.companyProfile?.name?.replace(/[^a-zA-Z0-9]/g, '-') || 'unknown'
  const date = new Date().toISOString().split('T')[0]
  const prefix = language === 'de' ? 'TOMs' : 'TOMs'
  return `${prefix}-${companyName}-${date}.docx`
}

// Types are exported at their definition site above
