/**
 * Enhanced Security Generator
 *
 * Generates comprehensive security and compliance configurations from enhanced schema.
 * Handles:
 * - Compliance (GDPR, CCPA, HIPAA, SOC2, PCI DSS)
 * - Encryption (at rest, in transit, field-level)
 * - Audit logging
 * - Content Security Policy (CSP)
 * - Rate limiting
 */

import path from 'path';
import {
  Generator,
  GeneratorContext,
  GenerationResult,
  GeneratedFile,
} from '../types';
import {
  Security,
  DataRetentionPolicy,
  GDPRConfig,
  RateLimitingConfig,
  StackComponent,
} from '../../types/workflow';

export class EnhancedSecurityGenerator implements Generator {
  id = 'enhanced-security';
  name = 'Enhanced Security Generator';
  description = 'Generates comprehensive security and compliance configurations from enhanced schema';

  generate(context: GeneratorContext): GenerationResult {
    const { workflow, outputDirectory } = context;
    const files: GeneratedFile[] = [];

    if (!workflow.security) {
      return { files: [] };
    }

    const security = workflow.security as Security;

    // Find backend and frontend components
    const backendComponent = Object.entries(workflow.stack).find(([_, c]) => (c as StackComponent).type === 'backend');
    const frontendComponent = Object.entries(workflow.stack).find(([_, c]) => (c as StackComponent).type === 'frontend');

    // Generate backend security configurations
    if (backendComponent) {
      const [componentName] = backendComponent;
      files.push(...this.generateBackendSecurity(componentName, security, outputDirectory));
    }

    // Generate frontend security configurations
    if (frontendComponent) {
      const [componentName] = frontendComponent;
      files.push(...this.generateFrontendSecurity(componentName, security, outputDirectory));
    }

    // Generate shared security configurations
    files.push(...this.generateSharedSecurity(security, outputDirectory));

    return { files };
  }

  private generateBackendSecurity(
    componentName: string,
    security: Security,
    outputDirectory: string
  ): GeneratedFile[] {
    const files: GeneratedFile[] = [];

    // Encryption configuration
    if (security.encryption) {
      files.push(this.generateEncryptionConfig(componentName, security.encryption, outputDirectory));
    }

    // Audit logging
    if (security.audit_logging?.enabled) {
      files.push(this.generateAuditLogging(componentName, security.audit_logging, outputDirectory));
    }

    // Rate limiting
    if (security.rate_limiting) {
      files.push(this.generateRateLimiting(componentName, security.rate_limiting, outputDirectory));
    }

    // Compliance configurations
    if (security.compliance) {
      files.push(...this.generateComplianceConfigs(componentName, security.compliance, outputDirectory));
    }

    return files;
  }

  private generateFrontendSecurity(
    componentName: string,
    security: Security,
    outputDirectory: string
  ): GeneratedFile[] {
    const files: GeneratedFile[] = [];

    // Content Security Policy
    if (security.csp?.enabled) {
      files.push(this.generateCSP(componentName, security.csp, outputDirectory));
    }

    // GDPR utilities (if applicable)
    if (security.compliance?.gdpr) {
      files.push(this.generateGDPRUtils(componentName, security.compliance.gdpr, outputDirectory));
    }

    return files;
  }

  private generateSharedSecurity(security: Security, outputDirectory: string): GeneratedFile[] {
    const files: GeneratedFile[] = [];

    // Security policy documentation
    if (security.compliance) {
      files.push(this.generateSecurityPolicy(security, outputDirectory));
    }

    return files;
  }

  // ========================================
  // Encryption Configuration
  // ========================================

  private generateEncryptionConfig(
    componentName: string,
    encryption: { at_rest: boolean; in_transit: boolean; field_level?: string[] },
    outputDirectory: string
  ): GeneratedFile {
    const content = `/**
 * Encryption Configuration
 *
 * Handles encryption at rest, in transit, and field-level encryption.
 * Generated from enhanced security schema.
 */

import crypto from 'crypto';

// Encryption configuration
export const encryptionConfig = {
  atRest: ${encryption.at_rest},
  inTransit: ${encryption.in_transit},
  fieldLevel: ${JSON.stringify(encryption.field_level || [], null, 2)},
};

// AES-256-GCM encryption for sensitive fields
const ALGORITHM = 'aes-256-gcm';
const IV_LENGTH = 16;
const SALT_LENGTH = 64;
const TAG_LENGTH = 16;
const KEY_LENGTH = 32;

// Derive encryption key from password using PBKDF2
function deriveKey(password: string, salt: Buffer): Buffer {
  return crypto.pbkdf2Sync(password, salt, 100000, KEY_LENGTH, 'sha512');
}

/**
 * Encrypt sensitive data
 */
export function encrypt(plaintext: string, password: string): string {
  const salt = crypto.randomBytes(SALT_LENGTH);
  const key = deriveKey(password, salt);
  const iv = crypto.randomBytes(IV_LENGTH);

  const cipher = crypto.createCipheriv(ALGORITHM, key, iv);

  let encrypted = cipher.update(plaintext, 'utf8', 'hex');
  encrypted += cipher.final('hex');

  const tag = cipher.getAuthTag();

  // Return: salt + iv + tag + encrypted data
  return Buffer.concat([salt, iv, tag, Buffer.from(encrypted, 'hex')]).toString('base64');
}

/**
 * Decrypt sensitive data
 */
export function decrypt(ciphertext: string, password: string): string {
  const buffer = Buffer.from(ciphertext, 'base64');

  const salt = buffer.slice(0, SALT_LENGTH);
  const iv = buffer.slice(SALT_LENGTH, SALT_LENGTH + IV_LENGTH);
  const tag = buffer.slice(SALT_LENGTH + IV_LENGTH, SALT_LENGTH + IV_LENGTH + TAG_LENGTH);
  const encrypted = buffer.slice(SALT_LENGTH + IV_LENGTH + TAG_LENGTH);

  const key = deriveKey(password, salt);

  const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
  decipher.setAuthTag(tag);

  let decrypted = decipher.update(encrypted);
  decrypted = Buffer.concat([decrypted, decipher.final()]);

  return decrypted.toString('utf8');
}

/**
 * Field-level encryption middleware for sensitive fields
 */
export function encryptFields<T extends Record<string, any>>(
  data: T,
  fields: string[],
  password: string
): T {
  const encrypted = { ...data };

  for (const field of fields) {
    if (field in encrypted && encrypted[field] != null) {
      encrypted[field] = encrypt(String(encrypted[field]), password);
    }
  }

  return encrypted;
}

/**
 * Field-level decryption for sensitive fields
 */
export function decryptFields<T extends Record<string, any>>(
  data: T,
  fields: string[],
  password: string
): T {
  const decrypted = { ...data };

  for (const field of fields) {
    if (field in decrypted && decrypted[field] != null) {
      decrypted[field] = decrypt(String(decrypted[field]), password);
    }
  }

  return decrypted;
}

// Environment variable for encryption key
export const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY || '';

if (!ENCRYPTION_KEY && (encryptionConfig.atRest || encryptionConfig.fieldLevel.length > 0)) {
  console.warn('⚠️  ENCRYPTION_KEY not set. Encryption features will not work.');
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/config/encryption.ts'),
      content,
    };
  }

  // ========================================
  // Audit Logging
  // ========================================

  private generateAuditLogging(
    componentName: string,
    auditConfig: { enabled: boolean; retention: string; log_all_database_changes?: boolean; log_api_requests?: boolean },
    outputDirectory: string
  ): GeneratedFile {
    const content = `/**
 * Audit Logging Configuration
 *
 * Tracks all security-relevant events and data changes.
 * Retention: ${auditConfig.retention}
 * Generated from enhanced security schema.
 */

import { createLogger, format, transports } from 'winston';

// Audit log configuration
export const auditConfig = {
  enabled: ${auditConfig.enabled},
  retention: '${auditConfig.retention}',
  logDatabaseChanges: ${auditConfig.log_all_database_changes || false},
  logApiRequests: ${auditConfig.log_api_requests || false},
};

// Create dedicated audit logger
export const auditLogger = createLogger({
  level: 'info',
  format: format.combine(
    format.timestamp(),
    format.json()
  ),
  transports: [
    // Separate audit log file
    new transports.File({
      filename: 'logs/audit.log',
      maxsize: 10485760, // 10MB
      maxFiles: 100, // Keep 100 files for rotation
    }),
    // Console in development
    ...(process.env.NODE_ENV === 'development'
      ? [new transports.Console({ format: format.simple() })]
      : []
    ),
  ],
});

// Audit event types
export enum AuditEventType {
  USER_LOGIN = 'USER_LOGIN',
  USER_LOGOUT = 'USER_LOGOUT',
  USER_CREATED = 'USER_CREATED',
  USER_UPDATED = 'USER_UPDATED',
  USER_DELETED = 'USER_DELETED',
  PASSWORD_CHANGED = 'PASSWORD_CHANGED',
  PERMISSION_GRANTED = 'PERMISSION_GRANTED',
  PERMISSION_REVOKED = 'PERMISSION_REVOKED',
  DATA_ACCESSED = 'DATA_ACCESSED',
  DATA_MODIFIED = 'DATA_MODIFIED',
  DATA_DELETED = 'DATA_DELETED',
  SENSITIVE_DATA_ACCESSED = 'SENSITIVE_DATA_ACCESSED',
  EXPORT_REQUESTED = 'EXPORT_REQUESTED',
  SYSTEM_CONFIG_CHANGED = 'SYSTEM_CONFIG_CHANGED',
  SECURITY_VIOLATION = 'SECURITY_VIOLATION',
}

export interface AuditEvent {
  event_type: AuditEventType;
  user_id?: string;
  user_email?: string;
  ip_address?: string;
  user_agent?: string;
  resource_type?: string;
  resource_id?: string;
  action: string;
  details?: Record<string, any>;
  success: boolean;
  error_message?: string;
  timestamp: Date;
}

/**
 * Log an audit event
 */
export function logAuditEvent(event: Omit<AuditEvent, 'timestamp'>): void {
  const auditEvent: AuditEvent = {
    ...event,
    timestamp: new Date(),
  };

  auditLogger.info('Audit Event', auditEvent);
}

/**
 * Express middleware for API request auditing
 */
export function auditRequestMiddleware(req: any, res: any, next: any): void {
  if (!auditConfig.logApiRequests) {
    return next();
  }

  const startTime = Date.now();

  // Log after response
  res.on('finish', () => {
    logAuditEvent({
      event_type: AuditEventType.DATA_ACCESSED,
      user_id: req.user?.id,
      user_email: req.user?.email,
      ip_address: req.ip,
      user_agent: req.get('user-agent'),
      action: \`\${req.method} \${req.path}\`,
      details: {
        method: req.method,
        path: req.path,
        status: res.statusCode,
        duration_ms: Date.now() - startTime,
      },
      success: res.statusCode < 400,
    });
  });

  next();
}

/**
 * Database change auditing (for use with ORM hooks)
 */
export function auditDatabaseChange(
  operation: 'create' | 'update' | 'delete',
  model: string,
  recordId: string,
  userId?: string,
  changes?: Record<string, any>
): void {
  if (!auditConfig.logDatabaseChanges) {
    return;
  }

  const eventTypeMap = {
    create: AuditEventType.DATA_MODIFIED,
    update: AuditEventType.DATA_MODIFIED,
    delete: AuditEventType.DATA_DELETED,
  };

  logAuditEvent({
    event_type: eventTypeMap[operation],
    user_id: userId,
    resource_type: model,
    resource_id: recordId,
    action: \`\${operation.toUpperCase()} \${model}\`,
    details: changes,
    success: true,
  });
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/config/audit-logging.ts'),
      content,
    };
  }

  // ========================================
  // Rate Limiting
  // ========================================

  private generateRateLimiting(
    componentName: string,
    rateLimiting: RateLimitingConfig,
    outputDirectory: string
  ): GeneratedFile {
    const content = `/**
 * Rate Limiting Configuration
 *
 * Protects against abuse and DoS attacks.
 * Generated from enhanced security schema.
 */

import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';
import { createClient } from 'redis';

// Rate limiting configuration
export const rateLimitConfig = {
  global: ${JSON.stringify(rateLimiting.global || {}, null, 2)},
  perUser: ${JSON.stringify(rateLimiting.per_user || {}, null, 2)},
  perEndpoint: ${JSON.stringify(rateLimiting.per_endpoint || [], null, 2)},
};

// Redis client for distributed rate limiting
let redisClient: ReturnType<typeof createClient> | null = null;

if (process.env.REDIS_URL) {
  redisClient = createClient({
    url: process.env.REDIS_URL,
  });

  redisClient.on('error', (err) => {
    console.error('Redis rate limit client error:', err);
  });

  redisClient.connect();
}

/**
 * Global rate limiter
 */
export const globalRateLimiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: rateLimitConfig.global?.requests_per_minute || 100,
  standardHeaders: true,
  legacyHeaders: false,
  message: 'Too many requests, please try again later.',
  ${rateLimiting.global ? `
  // Use Redis store if available for distributed rate limiting
  ...(redisClient ? {
    store: new RedisStore({
      sendCommand: (...args: string[]) => redisClient!.sendCommand(args),
    }),
  } : {}),
  ` : ''}
});

/**
 * Create endpoint-specific rate limiter
 */
export function createEndpointRateLimiter(limit: string) {
  // Parse limit format: "50/minute", "100/hour", etc.
  const match = limit.match(/(\\d+)\\/(minute|hour|day)/);

  if (!match) {
    throw new Error(\`Invalid rate limit format: \${limit}\`);
  }

  const [, count, unit] = match;
  const windowMs = {
    minute: 60 * 1000,
    hour: 60 * 60 * 1000,
    day: 24 * 60 * 60 * 1000,
  }[unit] || 60 * 1000;

  return rateLimit({
    windowMs,
    max: parseInt(count, 10),
    standardHeaders: true,
    legacyHeaders: false,
    message: \`Rate limit exceeded for this endpoint. Limit: \${limit}\`,
    ...(redisClient ? {
      store: new RedisStore({
        sendCommand: (...args: string[]) => redisClient!.sendCommand(args),
      }),
    } : {}),
  });
}

/**
 * User-tier based rate limiter
 */
export function createTierRateLimiter(tier: string = 'free') {
  const tierLimits = rateLimitConfig.perUser;
  const limit = tierLimits[tier] || tierLimits['free'] || '100/minute';

  return createEndpointRateLimiter(limit);
}

/**
 * Apply endpoint-specific rate limits
 */
export function applyEndpointRateLimits(app: any) {
  for (const endpoint of rateLimitConfig.perEndpoint) {
    const limiter = createEndpointRateLimiter(endpoint.limit);
    app.use(endpoint.path, limiter);
  }
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/middleware/rate-limiting.ts'),
      content,
    };
  }

  // ========================================
  // Compliance Configurations
  // ========================================

  private generateComplianceConfigs(
    componentName: string,
    compliance: { regulations: string[]; data_retention?: DataRetentionPolicy; gdpr?: GDPRConfig },
    outputDirectory: string
  ): GeneratedFile[] {
    const files: GeneratedFile[] = [];

    // GDPR compliance utilities
    if (compliance.regulations.includes('gdpr') && compliance.gdpr) {
      files.push(this.generateGDPRBackendConfig(componentName, compliance.gdpr, outputDirectory));
    }

    // Data retention policy
    if (compliance.data_retention) {
      files.push(this.generateDataRetentionConfig(componentName, compliance.data_retention, outputDirectory));
    }

    // HIPAA compliance utilities
    if (compliance.regulations.includes('hipaa')) {
      files.push(this.generateHIPAAConfig(componentName, outputDirectory));
    }

    // PCI DSS compliance utilities
    if (compliance.regulations.includes('pci_dss')) {
      files.push(this.generatePCIDSSConfig(componentName, outputDirectory));
    }

    return files;
  }

  private generateGDPRBackendConfig(
    componentName: string,
    gdpr: GDPRConfig,
    outputDirectory: string
  ): GeneratedFile {
    const content = `/**
 * GDPR Compliance Configuration (Backend)
 *
 * Implements GDPR rights:
 * - Right to access: ${gdpr.right_to_access || false}
 * - Right to erasure: ${gdpr.right_to_erasure || false}
 * - Data portability: ${gdpr.data_portability || false}
 * - Consent management: ${gdpr.consent_management || false}
 */

import { logAuditEvent, AuditEventType } from '../config/audit-logging';

export const gdprConfig = {
  rightToAccess: ${gdpr.right_to_access || false},
  rightToErasure: ${gdpr.right_to_erasure || false},
  dataPortability: ${gdpr.data_portability || false},
  consentManagement: ${gdpr.consent_management || false},
};

/**
 * Export user data (Right to Access)
 */
export async function exportUserData(userId: string, db: any): Promise<Record<string, any>> {
  if (!gdprConfig.rightToAccess) {
    throw new Error('Right to access is not enabled');
  }

  logAuditEvent({
    event_type: AuditEventType.EXPORT_REQUESTED,
    user_id: userId,
    action: 'GDPR_DATA_EXPORT',
    success: true,
  });

  // Collect all user data from various tables
  const userData: Record<string, any> = {
    profile: await db.user.findUnique({ where: { id: userId } }),
    // Add other user-related data collections here
    // orders: await db.order.findMany({ where: { userId } }),
    // preferences: await db.userPreference.findMany({ where: { userId } }),
  };

  return userData;
}

/**
 * Delete user data (Right to Erasure / Right to be Forgotten)
 */
export async function deleteUserData(userId: string, db: any): Promise<void> {
  if (!gdprConfig.rightToErasure) {
    throw new Error('Right to erasure is not enabled');
  }

  logAuditEvent({
    event_type: AuditEventType.USER_DELETED,
    user_id: userId,
    action: 'GDPR_DATA_ERASURE',
    success: true,
  });

  // Delete or anonymize user data
  // This should cascade through all related tables
  await db.user.delete({ where: { id: userId } });

  // Or anonymize instead of delete:
  // await db.user.update({
  //   where: { id: userId },
  //   data: {
  //     email: \`deleted-\${userId}@anonymized.local\`,
  //     name: 'Deleted User',
  //     // ... anonymize other fields
  //   },
  // });
}

/**
 * Consent management
 */
export interface UserConsent {
  userId: string;
  marketing: boolean;
  analytics: boolean;
  functional: boolean;
  timestamp: Date;
}

export async function updateConsent(userId: string, consent: Partial<UserConsent>, db: any): Promise<void> {
  if (!gdprConfig.consentManagement) {
    throw new Error('Consent management is not enabled');
  }

  logAuditEvent({
    event_type: AuditEventType.USER_UPDATED,
    user_id: userId,
    action: 'CONSENT_UPDATED',
    details: consent,
    success: true,
  });

  // Store consent in database
  // await db.userConsent.upsert({
  //   where: { userId },
  //   update: { ...consent, timestamp: new Date() },
  //   create: { userId, ...consent, timestamp: new Date() },
  // });
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/utils/gdpr.ts'),
      content,
    };
  }

  private generateDataRetentionConfig(
    componentName: string,
    retention: DataRetentionPolicy,
    outputDirectory: string
  ): GeneratedFile {
    const content = `/**
 * Data Retention Policy Configuration
 *
 * Automatically manages data lifecycle according to retention policies.
 * Generated from enhanced security schema.
 */

// Data retention policies
export const dataRetentionPolicies = ${JSON.stringify(retention, null, 2)};

/**
 * Parse retention period to days
 */
function parseRetentionPeriod(period: string): number {
  const match = period.match(/(\\d+)_(day|month|year)s?/);

  if (!match) {
    throw new Error(\`Invalid retention period format: \${period}\`);
  }

  const [, count, unit] = match;
  const days = {
    day: 1,
    month: 30,
    year: 365,
  }[unit] || 1;

  return parseInt(count, 10) * days;
}

/**
 * Calculate deletion date based on retention policy
 */
export function calculateDeletionDate(dataType: string, createdAt: Date): Date {
  const retentionPeriod = dataRetentionPolicies[dataType];

  if (!retentionPeriod) {
    throw new Error(\`No retention policy defined for data type: \${dataType}\`);
  }

  const retentionDays = parseRetentionPeriod(retentionPeriod);
  const deletionDate = new Date(createdAt);
  deletionDate.setDate(deletionDate.getDate() + retentionDays);

  return deletionDate;
}

/**
 * Check if data should be deleted based on retention policy
 */
export function shouldDelete(dataType: string, createdAt: Date): boolean {
  const deletionDate = calculateDeletionDate(dataType, createdAt);
  return new Date() >= deletionDate;
}

/**
 * Cleanup job for expired data
 * Should be run periodically (e.g., daily cron job)
 */
export async function cleanupExpiredData(db: any): Promise<void> {
  for (const [dataType, retentionPeriod] of Object.entries(dataRetentionPolicies)) {
    const retentionDays = parseRetentionPeriod(retentionPeriod);
    const cutoffDate = new Date();
    cutoffDate.setDate(cutoffDate.getDate() - retentionDays);

    console.log(\`Cleaning up \${dataType} older than \${retentionPeriod} (before \${cutoffDate.toISOString()})\`);

    // Delete expired records
    // Example:
    // await db[dataType].deleteMany({
    //   where: {
    //     createdAt: {
    //       lt: cutoffDate,
    //     },
    //   },
    // });
  }
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/utils/data-retention.ts'),
      content,
    };
  }

  private generateHIPAAConfig(componentName: string, outputDirectory: string): GeneratedFile {
    const content = `/**
 * HIPAA Compliance Utilities
 *
 * Implements HIPAA security and privacy requirements for Protected Health Information (PHI).
 */

import { encrypt, decrypt } from '../config/encryption';
import { logAuditEvent, AuditEventType } from '../config/audit-logging';

/**
 * Identify if data contains PHI
 */
export function containsPHI(data: Record<string, any>): boolean {
  const phiFields = [
    'ssn',
    'medical_record_number',
    'health_plan_number',
    'diagnosis',
    'prescription',
    'treatment',
    'date_of_birth',
    'phone_number',
    'email', // If healthcare-related
  ];

  return phiFields.some(field => field in data);
}

/**
 * Encrypt PHI data
 */
export function encryptPHI<T extends Record<string, any>>(data: T, encryptionKey: string): T {
  const phiFields = Object.keys(data).filter(key =>
    ['ssn', 'medical_record_number', 'diagnosis', 'prescription'].includes(key)
  );

  const encrypted = { ...data };

  for (const field of phiFields) {
    if (encrypted[field] != null) {
      encrypted[field] = encrypt(String(encrypted[field]), encryptionKey);
    }
  }

  return encrypted;
}

/**
 * Log PHI access for HIPAA audit trail
 */
export function logPHIAccess(userId: string, patientId: string, action: string, details?: any): void {
  logAuditEvent({
    event_type: AuditEventType.SENSITIVE_DATA_ACCESSED,
    user_id: userId,
    resource_type: 'PHI',
    resource_id: patientId,
    action,
    details,
    success: true,
  });
}

/**
 * Minimum necessary rule: Return only required PHI fields
 */
export function applyMinimumNecessary<T extends Record<string, any>>(
  data: T,
  requiredFields: string[]
): Partial<T> {
  const filtered: Partial<T> = {};

  for (const field of requiredFields) {
    if (field in data) {
      filtered[field as keyof T] = data[field];
    }
  }

  return filtered;
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/utils/hipaa.ts'),
      content,
    };
  }

  private generatePCIDSSConfig(componentName: string, outputDirectory: string): GeneratedFile {
    const content = `/**
 * PCI DSS Compliance Utilities
 *
 * Implements PCI DSS requirements for payment card data protection.
 */

import { encrypt, decrypt } from '../config/encryption';
import { logAuditEvent, AuditEventType } from '../config/audit-logging';

/**
 * Mask credit card number (PAN)
 */
export function maskCardNumber(cardNumber: string): string {
  // Show only last 4 digits
  return cardNumber.replace(/.(?=.{4})/g, '*');
}

/**
 * Validate card number using Luhn algorithm
 */
export function validateCardNumber(cardNumber: string): boolean {
  const digits = cardNumber.replace(/\\D/g, '');

  if (digits.length < 13 || digits.length > 19) {
    return false;
  }

  let sum = 0;
  let isEven = false;

  for (let i = digits.length - 1; i >= 0; i--) {
    let digit = parseInt(digits[i], 10);

    if (isEven) {
      digit *= 2;
      if (digit > 9) {
        digit -= 9;
      }
    }

    sum += digit;
    isEven = !isEven;
  }

  return sum % 10 === 0;
}

/**
 * Encrypt cardholder data
 */
export function encryptCardData(cardData: {
  cardNumber: string;
  cvv: string;
  expiryDate: string;
}, encryptionKey: string): {
  encryptedCardNumber: string;
  encryptedCVV: string;
  expiryDate: string; // Not considered sensitive by PCI DSS
} {
  return {
    encryptedCardNumber: encrypt(cardData.cardNumber, encryptionKey),
    encryptedCVV: encrypt(cardData.cvv, encryptionKey),
    expiryDate: cardData.expiryDate, // Can be stored unencrypted
  };
}

/**
 * Log cardholder data access
 */
export function logCardDataAccess(userId: string, action: string, details?: any): void {
  logAuditEvent({
    event_type: AuditEventType.SENSITIVE_DATA_ACCESSED,
    user_id: userId,
    resource_type: 'CARD_DATA',
    action,
    details,
    success: true,
  });
}

/**
 * Tokenize card number (for storing with payment processors)
 */
export function tokenizeCard(cardNumber: string): string {
  // In production, this would call a payment processor's tokenization API
  // For now, return a mock token
  return \`tok_\${Math.random().toString(36).substring(7)}\`;
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/utils/pci-dss.ts'),
      content,
    };
  }

  // ========================================
  // Content Security Policy (Frontend)
  // ========================================

  private generateCSP(
    componentName: string,
    csp: { enabled: boolean; directives?: Record<string, string[]> },
    outputDirectory: string
  ): GeneratedFile {
    const defaultDirectives = {
      'default-src': ["'self'"],
      'script-src': ["'self'", "'unsafe-inline'"],
      'style-src': ["'self'", "'unsafe-inline'"],
      'img-src': ["'self'", 'data:', 'https:'],
      'font-src': ["'self'", 'data:'],
      'connect-src': ["'self'"],
      'frame-ancestors': ["'none'"],
      'base-uri': ["'self'"],
      'form-action': ["'self'"],
    };

    const directives = { ...defaultDirectives, ...(csp.directives || {}) };

    const content = `/**
 * Content Security Policy (CSP) Configuration
 *
 * Prevents XSS and other code injection attacks.
 * Generated from enhanced security schema.
 */

// CSP directives
export const cspDirectives = ${JSON.stringify(directives, null, 2)};

/**
 * Generate CSP header value
 */
export function generateCSPHeader(): string {
  return Object.entries(cspDirectives)
    .map(([directive, values]) => \`\${directive} \${values.join(' ')}\`)
    .join('; ');
}

/**
 * CSP meta tag for static HTML
 */
export function generateCSPMetaTag(): string {
  return \`<meta http-equiv="Content-Security-Policy" content="\${generateCSPHeader()}">\`;
}

/**
 * Express middleware for CSP headers
 */
export function cspMiddleware(req: any, res: any, next: any): void {
  res.setHeader('Content-Security-Policy', generateCSPHeader());
  next();
}

/**
 * Vite plugin for CSP in development
 */
export function viteCSPPlugin() {
  return {
    name: 'csp-plugin',
    transformIndexHtml(html: string) {
      return html.replace(
        '<head>',
        \`<head>\\n  \${generateCSPMetaTag()}\`
      );
    },
  };
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/utils/csp.ts'),
      content,
    };
  }

  // ========================================
  // GDPR Utilities (Frontend)
  // ========================================

  private generateGDPRUtils(
    componentName: string,
    gdpr: GDPRConfig,
    outputDirectory: string
  ): GeneratedFile {
    const content = `/**
 * GDPR Compliance Utilities (Frontend)
 *
 * Implements GDPR-compliant consent management and data access UI.
 */

import { useState, useEffect } from 'react';

export interface ConsentPreferences {
  marketing: boolean;
  analytics: boolean;
  functional: boolean;
}

/**
 * Cookie consent hook
 */
export function useConsentManagement() {
  const [consent, setConsent] = useState<ConsentPreferences | null>(null);
  const [showBanner, setShowBanner] = useState(false);

  useEffect(() => {
    // Check for existing consent
    const savedConsent = localStorage.getItem('gdpr_consent');

    if (savedConsent) {
      setConsent(JSON.parse(savedConsent));
    } else {
      setShowBanner(true);
    }
  }, []);

  const saveConsent = async (preferences: ConsentPreferences) => {
    // Save to localStorage
    localStorage.setItem('gdpr_consent', JSON.stringify(preferences));

    // Send to backend
    try {
      await fetch('/api/consent', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(preferences),
      });
    } catch (error) {
      console.error('Failed to save consent preferences:', error);
    }

    setConsent(preferences);
    setShowBanner(false);
  };

  return { consent, showBanner, saveConsent };
}

/**
 * Request user data export (Right to Access)
 */
export async function requestDataExport(): Promise<void> {
  const response = await fetch('/api/gdpr/export', {
    method: 'POST',
  });

  if (!response.ok) {
    throw new Error('Failed to request data export');
  }

  // Download will be sent via email or available for download
  alert('Your data export request has been received. You will receive an email when it is ready.');
}

/**
 * Request account deletion (Right to Erasure)
 */
export async function requestAccountDeletion(): Promise<void> {
  const confirmed = window.confirm(
    'Are you sure you want to delete your account? This action cannot be undone.'
  );

  if (!confirmed) {
    return;
  }

  const response = await fetch('/api/gdpr/delete', {
    method: 'POST',
  });

  if (!response.ok) {
    throw new Error('Failed to request account deletion');
  }

  alert('Your account deletion request has been received.');

  // Logout user
  window.location.href = '/logout';
}

/**
 * Consent banner component
 */
export function ConsentBanner({ onAccept }: { onAccept: (preferences: ConsentPreferences) => void }) {
  const handleAcceptAll = () => {
    onAccept({
      marketing: true,
      analytics: true,
      functional: true,
    });
  };

  const handleRejectAll = () => {
    onAccept({
      marketing: false,
      analytics: false,
      functional: true, // Functional cookies are necessary
    });
  };

  return (
    <div className="consent-banner">
      <p>
        We use cookies to improve your experience. By using our site, you agree to our use of cookies.
      </p>
      <div className="consent-buttons">
        <button onClick={handleAcceptAll}>Accept All</button>
        <button onClick={handleRejectAll}>Reject Non-Essential</button>
      </div>
    </div>
  );
}
`;

    return {
      path: path.join(outputDirectory, componentName, 'src/utils/gdpr.ts'),
      content,
    };
  }

  // ========================================
  // Security Policy Documentation
  // ========================================

  private generateSecurityPolicy(security: Security, outputDirectory: string): GeneratedFile {
    const regulations = security.compliance?.regulations || [];

    const content = `# Security & Compliance Policy

This document outlines the security and compliance measures implemented in this application.

## Compliance Requirements

${regulations.length > 0 ? `
This application complies with the following regulations:

${regulations.map(reg => `- **${reg.toUpperCase()}**`).join('\n')}
` : 'No specific compliance requirements configured.'}

## Encryption

${security.encryption ? `
### Encryption at Rest
${security.encryption.at_rest ? '✅ Enabled - All sensitive data is encrypted when stored in the database.' : '❌ Disabled'}

### Encryption in Transit
${security.encryption.in_transit ? '✅ Enabled - All data transmitted over the network is encrypted using TLS/SSL.' : '❌ Disabled'}

${security.encryption.field_level && security.encryption.field_level.length > 0 ? `
### Field-Level Encryption
The following fields are encrypted using AES-256-GCM:
${security.encryption.field_level.map(f => `- ${f}`).join('\n')}
` : ''}
` : 'No encryption configured.'}

## Audit Logging

${security.audit_logging?.enabled ? `
✅ **Audit logging is enabled**

- **Retention Period**: ${security.audit_logging.retention}
- **Database Changes**: ${security.audit_logging.log_all_database_changes ? 'Logged' : 'Not logged'}
- **API Requests**: ${security.audit_logging.log_api_requests ? 'Logged' : 'Not logged'}

All security-relevant events are logged to \`logs/audit.log\` for compliance and forensic analysis.
` : '❌ Audit logging is disabled'}

## Rate Limiting

${security.rate_limiting ? `
✅ **Rate limiting is enabled**

${security.rate_limiting.global ? `
### Global Rate Limit
- **Requests per minute**: ${security.rate_limiting.global.requests_per_minute}
${security.rate_limiting.global.burst ? `- **Burst capacity**: ${security.rate_limiting.global.burst}` : ''}
` : ''}

${security.rate_limiting.per_endpoint && security.rate_limiting.per_endpoint.length > 0 ? `
### Endpoint-Specific Limits
${security.rate_limiting.per_endpoint.map(e => `- \`${e.path}\`: ${e.limit}`).join('\n')}
` : ''}
` : '❌ Rate limiting is disabled'}

## Content Security Policy

${security.csp?.enabled ? `
✅ **CSP is enabled**

Content Security Policy headers are configured to prevent XSS and code injection attacks.

${security.csp.directives ? `
### CSP Directives
\`\`\`
${Object.entries(security.csp.directives).map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(' ') : v}`).join('\n')}
\`\`\`
` : ''}
` : '❌ CSP is disabled'}

## GDPR Compliance

${security.compliance?.gdpr ? `
${security.compliance.regulations.includes('gdpr') ? '✅' : '⚠️'} **GDPR features enabled**

- **Right to Access**: ${security.compliance.gdpr.right_to_access ? '✅ Implemented' : '❌ Not implemented'}
- **Right to Erasure**: ${security.compliance.gdpr.right_to_erasure ? '✅ Implemented' : '❌ Not implemented'}
- **Data Portability**: ${security.compliance.gdpr.data_portability ? '✅ Implemented' : '❌ Not implemented'}
- **Consent Management**: ${security.compliance.gdpr.consent_management ? '✅ Implemented' : '❌ Not implemented'}
` : ''}

## Data Retention

${security.compliance?.data_retention ? `
Data retention policies are configured to automatically delete data after the specified retention period:

${Object.entries(security.compliance.data_retention).map(([type, period]) => `- **${type}**: ${period}`).join('\n')}

A scheduled job runs daily to clean up expired data.
` : 'No data retention policies configured.'}

## Security Best Practices

1. **Environment Variables**: All sensitive configuration (API keys, encryption keys) must be stored in environment variables, never in code.
2. **Password Security**: Passwords are hashed using bcrypt with a minimum cost factor of 12.
3. **Session Management**: Sessions use secure, HTTP-only cookies with SameSite=Strict.
4. **Input Validation**: All user input is validated and sanitized to prevent injection attacks.
5. **Dependency Security**: Regular security audits are performed using \`npm audit\`.

## Incident Response

In case of a security incident:

1. **Isolate**: Immediately isolate affected systems
2. **Assess**: Determine scope and impact of the breach
3. **Notify**: Notify relevant stakeholders and authorities within 72 hours (GDPR requirement)
4. **Remediate**: Fix vulnerabilities and restore normal operations
5. **Review**: Conduct post-incident review and update security measures

## Security Contacts

For security concerns or to report vulnerabilities, contact: [security@example.com](mailto:security@example.com)
`;

    return {
      path: path.join(outputDirectory, 'SECURITY.md'),
      content,
    };
  }
}
