/**
 * GDPR Controller
 *
 * Endpoints for GDPR compliance (data export, deletion, consent)
 */

import {
  Controller,
  Get,
  Post,
  Delete,
  Body,
  UseGuards,
  HttpCode,
  HttpStatus,
  Res,
  Req,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiResponse } from '@nestjs/swagger';
import { Response, Request } from 'express';
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
import { CurrentUser } from '../decorators/current-user.decorator';
import { UserPayload } from '../decorators/current-user.decorator';
import { GDPRService } from '../services/gdpr.service';
import { UpdateConsentDto, ConsentResponseDto, WithdrawConsentDto } from '../dto/consent.dto';

@ApiTags('GDPR')
@Controller('gdpr')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class GDPRController {
  constructor(private readonly gdprService: GDPRService) {}

  /**
   * Export user data (GDPR Right to Data Portability)
   */
  @Get('export')
  @ApiOperation({
    summary: 'Export all user data',
    description: 'Export all personal data in JSON format (GDPR Article 20)',
  })
  @ApiResponse({
    status: 200,
    description: 'Data export successful',
  })
  async exportData(@CurrentUser() user: UserPayload, @Res() res: Response): Promise<void> {
    const exportData = await this.gdprService.exportUserData(user.id);

    // Set headers for file download
    res.setHeader('Content-Type', 'application/json');
    res.setHeader(
      'Content-Disposition',
      `attachment; filename="xpeditis-data-export-${user.id}-${Date.now()}.json"`
    );

    res.json(exportData);
  }

  /**
   * Export user data as CSV
   */
  @Get('export/csv')
  @ApiOperation({
    summary: 'Export user data as CSV',
    description: 'Export personal data in CSV format for easy viewing',
  })
  @ApiResponse({
    status: 200,
    description: 'CSV export successful',
  })
  async exportDataCSV(@CurrentUser() user: UserPayload, @Res() res: Response): Promise<void> {
    const exportData = await this.gdprService.exportUserData(user.id);

    // Convert to CSV (simplified version)
    let csv = 'Category,Field,Value\n';

    // User data
    Object.entries(exportData.userData).forEach(([key, value]) => {
      csv += `User Data,${key},"${value}"\n`;
    });

    // Cookie consent data
    if (exportData.cookieConsent) {
      Object.entries(exportData.cookieConsent).forEach(([key, value]) => {
        csv += `Cookie Consent,${key},"${value}"\n`;
      });
    }

    // Set headers
    res.setHeader('Content-Type', 'text/csv');
    res.setHeader(
      'Content-Disposition',
      `attachment; filename="xpeditis-data-export-${user.id}-${Date.now()}.csv"`
    );

    res.send(csv);
  }

  /**
   * Delete user data (GDPR Right to Erasure)
   */
  @Delete('delete-account')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({
    summary: 'Delete user account and data',
    description: 'Permanently delete or anonymize user data (GDPR Article 17)',
  })
  @ApiResponse({
    status: 204,
    description: 'Account deletion initiated',
  })
  async deleteAccount(
    @CurrentUser() user: UserPayload,
    @Body() body: { reason?: string; confirmEmail: string }
  ): Promise<void> {
    // Verify email confirmation (security measure)
    if (body.confirmEmail !== user.email) {
      throw new Error('Email confirmation does not match');
    }

    await this.gdprService.deleteUserData(user.id, body.reason);
  }

  /**
   * Record consent
   */
  @Post('consent')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: 'Record user consent',
    description: 'Record consent for cookies (GDPR Article 7)',
  })
  @ApiResponse({
    status: 200,
    description: 'Consent recorded',
    type: ConsentResponseDto,
  })
  async recordConsent(
    @CurrentUser() user: UserPayload,
    @Body() body: UpdateConsentDto,
    @Req() req: Request
  ): Promise<ConsentResponseDto> {
    // Add IP and user agent from request if not provided
    const consentData: UpdateConsentDto = {
      ...body,
      ipAddress: body.ipAddress || req.ip || req.socket.remoteAddress,
      userAgent: body.userAgent || req.headers['user-agent'],
    };

    return this.gdprService.recordConsent(user.id, consentData);
  }

  /**
   * Withdraw consent
   */
  @Post('consent/withdraw')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({
    summary: 'Withdraw consent',
    description: 'Withdraw consent for functional, analytics, or marketing (GDPR Article 7.3)',
  })
  @ApiResponse({
    status: 200,
    description: 'Consent withdrawn',
    type: ConsentResponseDto,
  })
  async withdrawConsent(
    @CurrentUser() user: UserPayload,
    @Body() body: WithdrawConsentDto
  ): Promise<ConsentResponseDto> {
    return this.gdprService.withdrawConsent(user.id, body.consentType);
  }

  /**
   * Get consent status
   */
  @Get('consent')
  @ApiOperation({
    summary: 'Get current consent status',
    description: 'Retrieve current consent preferences',
  })
  @ApiResponse({
    status: 200,
    description: 'Consent status retrieved',
    type: ConsentResponseDto,
  })
  async getConsentStatus(@CurrentUser() user: UserPayload): Promise<ConsentResponseDto | null> {
    return this.gdprService.getConsentStatus(user.id);
  }
}
