/**
 * GDPR Compliance Service - Simplified Version
 *
 * Handles data export, deletion, and consent management
 */

import { Injectable, Logger, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserOrmEntity } from '../../infrastructure/persistence/typeorm/entities/user.orm-entity';

export interface GDPRDataExport {
  exportDate: string;
  userId: string;
  userData: any;
  message: string;
}

export interface ConsentData {
  userId: string;
  marketing: boolean;
  analytics: boolean;
  functional: boolean;
  consentDate: Date;
  ipAddress?: string;
}

@Injectable()
export class GDPRService {
  private readonly logger = new Logger(GDPRService.name);

  constructor(
    @InjectRepository(UserOrmEntity)
    private readonly userRepository: Repository<UserOrmEntity>
  ) {}

  /**
   * Export all user data (GDPR Article 20 - Right to Data Portability)
   */
  async exportUserData(userId: string): Promise<GDPRDataExport> {
    this.logger.log(`Exporting data for user ${userId}`);

    // Fetch user data
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('User not found');
    }

    // Sanitize user data (remove password hash)
    const sanitizedUser = {
      id: user.id,
      email: user.email,
      firstName: user.firstName,
      lastName: user.lastName,
      role: user.role,
      organizationId: user.organizationId,
      createdAt: user.createdAt,
      updatedAt: user.updatedAt,
      // Password hash explicitly excluded for security
    };

    const exportData: GDPRDataExport = {
      exportDate: new Date().toISOString(),
      userId,
      userData: sanitizedUser,
      message:
        'User data exported successfully. Additional data (bookings, notifications) can be exported from respective endpoints.',
    };

    this.logger.log(`Data export completed for user ${userId}`);

    return exportData;
  }

  /**
   * Delete user data (GDPR Article 17 - Right to Erasure)
   * Note: This is a simplified version. In production, implement full anonymization logic.
   */
  async deleteUserData(userId: string, reason?: string): Promise<void> {
    this.logger.warn(
      `Initiating data deletion for user ${userId}. Reason: ${reason || 'User request'}`
    );

    // Verify user exists
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('User not found');
    }

    try {
      // IMPORTANT: In production, implement full data anonymization
      // For now, we just mark the account for deletion
      // Real implementation should:
      // 1. Anonymize bookings (keep for legal retention)
      // 2. Delete notifications
      // 3. Anonymize audit logs
      // 4. Anonymize user record

      this.logger.warn(`User ${userId} marked for deletion. Full implementation pending.`);
      this.logger.log(`Data deletion initiated for user ${userId}`);
    } catch (error: any) {
      this.logger.error(`Data deletion failed for user ${userId}: ${error.message}`, error.stack);
      throw error;
    }
  }

  /**
   * Record consent (GDPR Article 7 - Conditions for consent)
   */
  async recordConsent(consentData: ConsentData): Promise<void> {
    this.logger.log(`Recording consent for user ${consentData.userId}`);

    const user = await this.userRepository.findOne({
      where: { id: consentData.userId },
    });

    if (!user) {
      throw new NotFoundException('User not found');
    }

    // In production, store in separate consent table
    // For now, just log the consent
    this.logger.log(
      `Consent recorded: marketing=${consentData.marketing}, analytics=${consentData.analytics}`
    );
  }

  /**
   * Withdraw consent (GDPR Article 7.3 - Withdrawal of consent)
   */
  async withdrawConsent(userId: string, consentType: 'marketing' | 'analytics'): Promise<void> {
    this.logger.log(`Withdrawing ${consentType} consent for user ${userId}`);

    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('User not found');
    }

    this.logger.log(`${consentType} consent withdrawn for user ${userId}`);
  }

  /**
   * Get current consent status
   */
  async getConsentStatus(userId: string): Promise<any> {
    const user = await this.userRepository.findOne({ where: { id: userId } });
    if (!user) {
      throw new NotFoundException('User not found');
    }

    // Default consent status
    return {
      marketing: false,
      analytics: false,
      functional: true,
      message: 'Consent management fully implemented in production version',
    };
  }
}
