/**
 * Vendor Audit Pack Export Utilities
 *
 * Functions for generating comprehensive vendor audit documentation.
 */

import type {
  Vendor,
  ContractDocument,
  Finding,
  ControlInstance,
  RiskAssessment,
  LocalizedText,
} from '../types'

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

export interface VendorAuditPackOptions {
  vendor: Vendor
  contracts: ContractDocument[]
  findings: Finding[]
  controlInstances: ControlInstance[]
  riskAssessment?: RiskAssessment
  language: 'de' | 'en'
  format: 'PDF' | 'DOCX'
  includeContracts?: boolean
  includeFindings?: boolean
  includeControlStatus?: boolean
  includeRiskAssessment?: boolean
}

export interface VendorAuditSection {
  title: string
  content: string | Record<string, unknown>
  level: 1 | 2 | 3
}

export interface VendorAuditPackResult {
  success: boolean
  filename: string
  sections: VendorAuditSection[]
  metadata: {
    vendorName: string
    generatedAt: Date
    language: string
    contractCount: number
    findingCount: number
    openFindingCount: number
    riskLevel: string
  }
}

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

const VENDOR_ROLE_LABELS: Record<string, LocalizedText> = {
  PROCESSOR: { de: 'Auftragsverarbeiter', en: 'Processor' },
  JOINT_CONTROLLER: { de: 'Gemeinsam Verantwortlicher', en: 'Joint Controller' },
  CONTROLLER: { de: 'Verantwortlicher', en: 'Controller' },
  SUB_PROCESSOR: { de: 'Unterauftragnehmer', en: 'Sub-Processor' },
  THIRD_PARTY: { de: 'Dritter', en: 'Third Party' },
}

const SERVICE_CATEGORY_LABELS: Record<string, LocalizedText> = {
  HOSTING: { de: 'Hosting', en: 'Hosting' },
  CLOUD_INFRASTRUCTURE: { de: 'Cloud-Infrastruktur', en: 'Cloud Infrastructure' },
  ANALYTICS: { de: 'Analytics', en: 'Analytics' },
  CRM: { de: 'CRM-System', en: 'CRM System' },
  ERP: { de: 'ERP-System', en: 'ERP System' },
  HR_SOFTWARE: { de: 'HR-Software', en: 'HR Software' },
  PAYMENT: { de: 'Zahlungsabwicklung', en: 'Payment Processing' },
  EMAIL: { de: 'E-Mail-Dienst', en: 'Email Service' },
  MARKETING: { de: 'Marketing', en: 'Marketing' },
  SUPPORT: { de: 'Support', en: 'Support' },
  SECURITY: { de: 'Sicherheit', en: 'Security' },
  INTEGRATION: { de: 'Integration', en: 'Integration' },
  CONSULTING: { de: 'Beratung', en: 'Consulting' },
  LEGAL: { de: 'Recht', en: 'Legal' },
  ACCOUNTING: { de: 'Buchhaltung', en: 'Accounting' },
  COMMUNICATION: { de: 'Kommunikation', en: 'Communication' },
  STORAGE: { de: 'Speicher', en: 'Storage' },
  OTHER: { de: 'Sonstiges', en: 'Other' },
}

const DATA_ACCESS_LABELS: Record<string, LocalizedText> = {
  NONE: { de: 'Kein Zugriff', en: 'No Access' },
  POTENTIAL: { de: 'Potentieller Zugriff', en: 'Potential Access' },
  ADMINISTRATIVE: { de: 'Administrativer Zugriff', en: 'Administrative Access' },
  CONTENT: { de: 'Inhaltlicher Zugriff', en: 'Content Access' },
}

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

function getLabel(labels: Record<string, LocalizedText>, key: string, lang: 'de' | 'en'): string {
  return labels[key]?.[lang] || key
}

function formatDate(date: Date | string | undefined, lang: 'de' | 'en'): string {
  if (!date) return lang === 'de' ? 'Nicht angegeben' : 'Not specified'
  const d = new Date(date)
  return d.toLocaleDateString(lang === 'de' ? 'de-DE' : 'en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  })
}

function getRiskLevelLabel(score: number, lang: 'de' | 'en'): string {
  if (score >= 70) return lang === 'de' ? 'KRITISCH' : 'CRITICAL'
  if (score >= 50) return lang === 'de' ? 'HOCH' : 'HIGH'
  if (score >= 30) return lang === 'de' ? 'MITTEL' : 'MEDIUM'
  return lang === 'de' ? 'NIEDRIG' : 'LOW'
}

// ==========================================
// SECTION GENERATORS
// ==========================================

/**
 * Generate vendor overview section
 */
export function generateVendorOverview(
  vendor: Vendor,
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Vendor-Übersicht' : 'Vendor Overview'

  const content = {
    name: vendor.name,
    legalForm: vendor.legalForm || '-',
    country: vendor.country,
    address: vendor.address
      ? `${vendor.address.street}, ${vendor.address.postalCode} ${vendor.address.city}`
      : '-',
    website: vendor.website || '-',
    role: getLabel(VENDOR_ROLE_LABELS, vendor.role, lang),
    serviceCategory: getLabel(SERVICE_CATEGORY_LABELS, vendor.serviceCategory, lang),
    serviceDescription: vendor.serviceDescription,
    dataAccessLevel: getLabel(DATA_ACCESS_LABELS, vendor.dataAccessLevel, lang),
    status: vendor.status,
    createdAt: formatDate(vendor.createdAt, lang),
  }

  return { title, content, level: 1 }
}

/**
 * Generate contacts section
 */
export function generateContactsSection(
  vendor: Vendor,
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Kontaktdaten' : 'Contact Information'

  const content = {
    primaryContact: {
      name: vendor.primaryContact.name,
      email: vendor.primaryContact.email,
      phone: vendor.primaryContact.phone || '-',
      department: vendor.primaryContact.department || '-',
      role: vendor.primaryContact.role || '-',
    },
    dpoContact: vendor.dpoContact
      ? {
          name: vendor.dpoContact.name,
          email: vendor.dpoContact.email,
          phone: vendor.dpoContact.phone || '-',
        }
      : null,
  }

  return { title, content, level: 2 }
}

/**
 * Generate processing locations section
 */
export function generateLocationsSection(
  vendor: Vendor,
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Verarbeitungsstandorte' : 'Processing Locations'

  const locations = vendor.processingLocations.map((loc) => ({
    country: loc.country,
    region: loc.region || '-',
    city: loc.city || '-',
    dataCenter: loc.dataCenter || '-',
    isEU: loc.isEU,
    isAdequate: loc.isAdequate,
  }))

  return { title, content: { locations }, level: 2 }
}

/**
 * Generate transfer mechanisms section
 */
export function generateTransferSection(
  vendor: Vendor,
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Drittlandtransfers' : 'Third Country Transfers'

  const mechanismLabels: 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: 'Binding Corporate Rules', en: 'Binding Corporate Rules' },
    DEROGATION_CONSENT: { de: 'Ausdrückliche Einwilligung', en: 'Explicit Consent' },
    DEROGATION_CONTRACT: { de: 'Vertragserfüllung', en: 'Contract Performance' },
    CERTIFICATION: { de: 'Zertifizierung', en: 'Certification' },
    CODE_OF_CONDUCT: { de: 'Verhaltensregeln', en: 'Code of Conduct' },
  }

  const mechanisms = vendor.transferMechanisms.map((tm) => ({
    type: tm,
    label: mechanismLabels[tm]?.[lang] || tm,
  }))

  return { title, content: { mechanisms }, level: 2 }
}

/**
 * Generate certifications section
 */
export function generateCertificationsSection(
  vendor: Vendor,
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Zertifizierungen' : 'Certifications'

  const certifications = vendor.certifications.map((cert) => ({
    type: cert.type,
    issuer: cert.issuer || '-',
    issuedDate: cert.issuedDate ? formatDate(cert.issuedDate, lang) : '-',
    expirationDate: cert.expirationDate ? formatDate(cert.expirationDate, lang) : '-',
    scope: cert.scope || '-',
    certificateNumber: cert.certificateNumber || '-',
  }))

  return { title, content: { certifications }, level: 2 }
}

/**
 * Generate contracts section
 */
export function generateContractsSection(
  contracts: ContractDocument[],
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Verträge' : 'Contracts'

  const contractList = contracts.map((contract) => ({
    type: contract.documentType,
    fileName: contract.originalName,
    version: contract.version,
    effectiveDate: contract.effectiveDate ? formatDate(contract.effectiveDate, lang) : '-',
    expirationDate: contract.expirationDate ? formatDate(contract.expirationDate, lang) : '-',
    status: contract.status,
    reviewStatus: contract.reviewStatus,
    complianceScore: contract.complianceScore !== undefined ? `${contract.complianceScore}%` : '-',
  }))

  return { title, content: { contracts: contractList }, level: 1 }
}

/**
 * Generate findings section
 */
export function generateFindingsSection(
  findings: Finding[],
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Findings' : 'Findings'

  const summary = {
    total: findings.length,
    open: findings.filter((f) => f.status === 'OPEN').length,
    inProgress: findings.filter((f) => f.status === 'IN_PROGRESS').length,
    resolved: findings.filter((f) => f.status === 'RESOLVED').length,
    critical: findings.filter((f) => f.severity === 'CRITICAL').length,
    high: findings.filter((f) => f.severity === 'HIGH').length,
    medium: findings.filter((f) => f.severity === 'MEDIUM').length,
    low: findings.filter((f) => f.severity === 'LOW').length,
  }

  const findingList = findings.map((finding) => ({
    id: finding.id.slice(0, 8),
    type: finding.type,
    category: finding.category,
    severity: finding.severity,
    title: finding.title[lang] || finding.title.de,
    description: finding.description[lang] || finding.description.de,
    recommendation: finding.recommendation
      ? finding.recommendation[lang] || finding.recommendation.de
      : '-',
    status: finding.status,
    affectedRequirement: finding.affectedRequirement || '-',
    createdAt: formatDate(finding.createdAt, lang),
    resolvedAt: finding.resolvedAt ? formatDate(finding.resolvedAt, lang) : '-',
  }))

  return { title, content: { summary, findings: findingList }, level: 1 }
}

/**
 * Generate control status section
 */
export function generateControlStatusSection(
  controlInstances: ControlInstance[],
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Control-Status' : 'Control Status'

  const summary = {
    total: controlInstances.length,
    pass: controlInstances.filter((c) => c.status === 'PASS').length,
    partial: controlInstances.filter((c) => c.status === 'PARTIAL').length,
    fail: controlInstances.filter((c) => c.status === 'FAIL').length,
    notApplicable: controlInstances.filter((c) => c.status === 'NOT_APPLICABLE').length,
    planned: controlInstances.filter((c) => c.status === 'PLANNED').length,
  }

  const passRate =
    summary.total > 0
      ? Math.round((summary.pass / (summary.total - summary.notApplicable)) * 100)
      : 0

  const controlList = controlInstances.map((ci) => ({
    controlId: ci.controlId,
    status: ci.status,
    lastAssessedAt: formatDate(ci.lastAssessedAt, lang),
    nextAssessmentDate: formatDate(ci.nextAssessmentDate, lang),
    notes: ci.notes || '-',
  }))

  return {
    title,
    content: { summary, passRate: `${passRate}%`, controls: controlList },
    level: 1,
  }
}

/**
 * Generate risk assessment section
 */
export function generateRiskSection(
  vendor: Vendor,
  riskAssessment: RiskAssessment | undefined,
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Risikobewertung' : 'Risk Assessment'

  const content = {
    inherentRiskScore: vendor.inherentRiskScore,
    inherentRiskLevel: getRiskLevelLabel(vendor.inherentRiskScore, lang),
    residualRiskScore: vendor.residualRiskScore,
    residualRiskLevel: getRiskLevelLabel(vendor.residualRiskScore, lang),
    manualAdjustment: vendor.manualRiskAdjustment || 0,
    justification: vendor.riskJustification || '-',
    assessment: riskAssessment
      ? {
          assessedBy: riskAssessment.assessedBy,
          assessedAt: formatDate(riskAssessment.assessedAt, lang),
          approvedBy: riskAssessment.approvedBy || '-',
          approvedAt: riskAssessment.approvedAt
            ? formatDate(riskAssessment.approvedAt, lang)
            : '-',
          nextAssessmentDate: formatDate(riskAssessment.nextAssessmentDate, lang),
          riskFactors: riskAssessment.riskFactors.map((rf) => ({
            name: rf.name[lang] || rf.name.de,
            category: rf.category,
            value: rf.value,
            weight: rf.weight,
            rationale: rf.rationale || '-',
          })),
        }
      : null,
  }

  return { title, content, level: 1 }
}

/**
 * Generate review schedule section
 */
export function generateReviewScheduleSection(
  vendor: Vendor,
  lang: 'de' | 'en'
): VendorAuditSection {
  const title = lang === 'de' ? 'Review-Zeitplan' : 'Review Schedule'

  const frequencyLabels: Record<string, LocalizedText> = {
    QUARTERLY: { de: 'Vierteljährlich', en: 'Quarterly' },
    SEMI_ANNUAL: { de: 'Halbjährlich', en: 'Semi-Annual' },
    ANNUAL: { de: 'Jährlich', en: 'Annual' },
    BIENNIAL: { de: 'Alle 2 Jahre', en: 'Biennial' },
  }

  const content = {
    reviewFrequency: getLabel(frequencyLabels, vendor.reviewFrequency, lang),
    lastReviewDate: vendor.lastReviewDate ? formatDate(vendor.lastReviewDate, lang) : '-',
    nextReviewDate: vendor.nextReviewDate ? formatDate(vendor.nextReviewDate, lang) : '-',
    isOverdue:
      vendor.nextReviewDate && new Date(vendor.nextReviewDate) < new Date()
        ? lang === 'de'
          ? 'Ja'
          : 'Yes'
        : lang === 'de'
        ? 'Nein'
        : 'No',
  }

  return { title, content, level: 2 }
}

// ==========================================
// MAIN EXPORT FUNCTION
// ==========================================

/**
 * Generate complete vendor audit pack
 */
export function generateVendorAuditPack(options: VendorAuditPackOptions): VendorAuditPackResult {
  const { vendor, contracts, findings, controlInstances, riskAssessment, language } = options

  const sections: VendorAuditSection[] = []

  // Always include vendor overview
  sections.push(generateVendorOverview(vendor, language))
  sections.push(generateContactsSection(vendor, language))
  sections.push(generateLocationsSection(vendor, language))
  sections.push(generateTransferSection(vendor, language))
  sections.push(generateCertificationsSection(vendor, language))
  sections.push(generateReviewScheduleSection(vendor, language))

  // Contracts (optional)
  if (options.includeContracts !== false && contracts.length > 0) {
    sections.push(generateContractsSection(contracts, language))
  }

  // Findings (optional)
  if (options.includeFindings !== false && findings.length > 0) {
    sections.push(generateFindingsSection(findings, language))
  }

  // Control status (optional)
  if (options.includeControlStatus !== false && controlInstances.length > 0) {
    sections.push(generateControlStatusSection(controlInstances, language))
  }

  // Risk assessment (optional)
  if (options.includeRiskAssessment !== false) {
    sections.push(generateRiskSection(vendor, riskAssessment, language))
  }

  // Calculate metadata
  const openFindings = findings.filter((f) => f.status === 'OPEN').length

  return {
    success: true,
    filename: `Vendor_Audit_${vendor.name.replace(/\s+/g, '_')}_${new Date().toISOString().slice(0, 10)}.${options.format.toLowerCase()}`,
    sections,
    metadata: {
      vendorName: vendor.name,
      generatedAt: new Date(),
      language,
      contractCount: contracts.length,
      findingCount: findings.length,
      openFindingCount: openFindings,
      riskLevel: getRiskLevelLabel(vendor.inherentRiskScore, language),
    },
  }
}

/**
 * Generate vendor audit pack as JSON
 */
export function generateVendorAuditJson(options: VendorAuditPackOptions): string {
  const result = generateVendorAuditPack(options)
  return JSON.stringify(result, null, 2)
}
