"""
GDPR compliance service for data export and deletion.
"""
from sqlalchemy.orm import Session
from typing import Dict, Any, Optional, List
from datetime import datetime, timedelta
import json
import secrets
import os
from pathlib import Path
from ..models.gdpr_request import GDPRRequest, GDPRRequestType, GDPRRequestStatus
from ...auth.models.user import User
from ...bookings.models.booking import Booking
from ...payments.models.payment import Payment
from ...payments.models.invoice import Invoice
from ...reviews.models.review import Review
from ...shared.config.logging_config import get_logger
from ...shared.config.settings import settings
from ...analytics.services.audit_service import audit_service
from ...shared.utils.mailer import send_email

logger = get_logger(__name__)

class GDPRService:
    """Service for GDPR compliance operations."""
    
    EXPORT_EXPIRY_DAYS = 7  # Export links expire after 7 days
    
    @staticmethod
    def _check_legal_exemptions(user_id: Optional[int], bookings_count: int, payments_count: int) -> Dict[str, Any]:
        """
        Check for legal exemptions that require data retention (GDPR Article 17(3)).
        Returns what must be retained and why.
        """
        exemptions = {
            'financial_records': {
                'retained': payments_count > 0,
                'reason': 'Financial transaction records required by tax law and financial regulations',
                'legal_basis': 'GDPR Article 17(3)(b) - Legal obligation',
                'retention_period': '7 years (tax law requirement)'
            },
            'contract_records': {
                'retained': bookings_count > 0,
                'reason': 'Contract records needed for dispute resolution and legal compliance',
                'legal_basis': 'GDPR Article 17(3)(c) - Legal claims',
                'retention_period': 'Until contract disputes are resolved or statute of limitations expires'
            },
            'security_logs': {
                'retained': True,  # Always retain security logs
                'reason': 'Security audit logs required for fraud prevention and security monitoring',
                'legal_basis': 'GDPR Article 17(3)(e) - Public interest',
                'retention_period': '2 years (security monitoring)'
            }
        }
        return exemptions
    
    @staticmethod
    async def create_data_export_request(
        db: Session,
        user_id: Optional[int] = None,
        user_email: Optional[str] = None,
        ip_address: Optional[str] = None,
        user_agent: Optional[str] = None,
        is_anonymous: bool = False
    ) -> GDPRRequest:
        """Create a data export request (supports both authenticated and anonymous users)."""
        # For authenticated users, get email from user record
        if user_id and not is_anonymous:
            user = db.query(User).filter(User.id == user_id).first()
            if not user:
                raise ValueError('User not found')
            user_email = user.email
        elif not user_email:
            raise ValueError('Email is required for anonymous requests')
        
        # Validate email format
        if user_email and '@' not in user_email:
            raise ValueError('Invalid email address')
        
        verification_token = secrets.token_urlsafe(32)
        expires_at = datetime.utcnow() + timedelta(days=GDPRService.EXPORT_EXPIRY_DAYS)
        
        gdpr_request = GDPRRequest(
            request_type=GDPRRequestType.data_export,
            status=GDPRRequestStatus.pending,
            user_id=user_id,
            user_email=user_email,
            is_anonymous=is_anonymous,
            verification_token=verification_token,
            ip_address=ip_address,
            user_agent=user_agent,
            expires_at=expires_at
        )
        
        db.add(gdpr_request)
        db.commit()
        db.refresh(gdpr_request)
        
        # Log GDPR request
        await audit_service.log_action(
            db=db,
            action='gdpr_export_requested',
            resource_type='gdpr_request',
            user_id=user_id,
            resource_id=gdpr_request.id,
            ip_address=ip_address,
            user_agent=user_agent,
            details={'request_type': 'data_export', 'is_anonymous': is_anonymous, 'email': user_email},
            status='success'
        )
        
        logger.info(f'GDPR export request created: {gdpr_request.id} for {"anonymous" if is_anonymous else f"user {user_id}"} ({user_email})')
        
        # Send email notification
        try:
            client_url = settings.CLIENT_URL or 'http://localhost:5173'
            verification_link = f"{client_url}/gdpr/export/{gdpr_request.id}?token={verification_token}"
            
            email_subject = "Your Data Export Request - GDPR"
            email_html = f"""
            <html>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <h2>Data Export Request Received</h2>
                <p>Hello,</p>
                <p>We have received your request to export your personal data in accordance with GDPR Article 15 (Right of Access).</p>
                <p><strong>Request ID:</strong> {gdpr_request.id}</p>
                <p><strong>Status:</strong> Pending</p>
                <p>Your data export will be prepared and you will receive a download link once it's ready.</p>
                <p>To access your export when ready, please use this verification link:</p>
                <p><a href="{verification_link}" style="background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; display: inline-block;">Access Data Export</a></p>
                <p><strong>Note:</strong> This link will expire in {GDPRService.EXPORT_EXPIRY_DAYS} days.</p>
                <p>If you did not make this request, please contact our support team immediately.</p>
                <hr>
                <p style="font-size: 12px; color: #666;">This is an automated message. Please do not reply to this email.</p>
            </body>
            </html>
            """
            await send_email(to=user_email, subject=email_subject, html=email_html)
        except Exception as e:
            logger.warning(f'Failed to send GDPR export email notification: {str(e)}')
        
        return gdpr_request
    
    @staticmethod
    async def create_data_deletion_request(
        db: Session,
        user_id: Optional[int] = None,
        user_email: Optional[str] = None,
        ip_address: Optional[str] = None,
        user_agent: Optional[str] = None,
        is_anonymous: bool = False
    ) -> GDPRRequest:
        """Create a data deletion request (right to be forgotten) - supports anonymous users."""
        # For authenticated users, get email from user record
        if user_id and not is_anonymous:
            user = db.query(User).filter(User.id == user_id).first()
            if not user:
                raise ValueError('User not found')
            user_email = user.email
        elif not user_email:
            raise ValueError('Email is required for anonymous requests')
        
        # Validate email format
        if user_email and '@' not in user_email:
            raise ValueError('Invalid email address')
        
        verification_token = secrets.token_urlsafe(32)
        
        gdpr_request = GDPRRequest(
            request_type=GDPRRequestType.data_deletion,
            status=GDPRRequestStatus.pending,
            user_id=user_id,
            user_email=user_email,
            is_anonymous=is_anonymous,
            verification_token=verification_token,
            ip_address=ip_address,
            user_agent=user_agent
        )
        
        db.add(gdpr_request)
        db.commit()
        db.refresh(gdpr_request)
        
        # Log GDPR request
        await audit_service.log_action(
            db=db,
            action='gdpr_deletion_requested',
            resource_type='gdpr_request',
            user_id=user_id,
            resource_id=gdpr_request.id,
            ip_address=ip_address,
            user_agent=user_agent,
            details={'request_type': 'data_deletion', 'is_anonymous': is_anonymous, 'email': user_email},
            status='success'
        )
        
        logger.info(f'GDPR deletion request created: {gdpr_request.id} for {"anonymous" if is_anonymous else f"user {user_id}"} ({user_email})')
        
        # Send email notification with verification link
        try:
            client_url = settings.CLIENT_URL or 'http://localhost:5173'
            verification_link = f"{client_url}/gdpr/delete/{gdpr_request.id}/confirm?token={verification_token}"
            
            email_subject = "Data Deletion Request - Action Required"
            email_html = f"""
            <html>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <h2>Data Deletion Request Received</h2>
                <p>Hello,</p>
                <p>We have received your request to delete your personal data in accordance with GDPR Article 17 (Right to Erasure / Right to be Forgotten).</p>
                <p><strong>Request ID:</strong> {gdpr_request.id}</p>
                <p><strong>Status:</strong> Pending Verification</p>
                <p><strong style="color: #d32f2f;">IMPORTANT:</strong> To proceed with the deletion, you must verify your request by clicking the link below:</p>
                <p><a href="{verification_link}" style="background-color: #d32f2f; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; display: inline-block;">Confirm Deletion Request</a></p>
                <p><strong>What will be deleted:</strong></p>
                <ul>
                    <li>Your personal profile information</li>
                    <li>Account preferences and settings</li>
                    <li>Reviews and ratings</li>
                    <li>Consent records</li>
                </ul>
                <p><strong>What will be retained (due to legal obligations):</strong></p>
                <ul>
                    <li>Financial transaction records (required by tax law - 7 years)</li>
                    <li>Booking/contract records (for dispute resolution)</li>
                    <li>Security audit logs (for fraud prevention - 2 years)</li>
                </ul>
                <p>These records will be anonymized (personal identifiers removed) but retained for legal compliance.</p>
                <p><strong>Warning:</strong> This action cannot be undone. Once confirmed, your account will be permanently deactivated and your personal data will be deleted or anonymized.</p>
                <p>If you did not make this request, please ignore this email or contact our support team immediately.</p>
                <hr>
                <p style="font-size: 12px; color: #666;">This is an automated message. Please do not reply to this email.</p>
            </body>
            </html>
            """
            await send_email(to=user_email, subject=email_subject, html=email_html)
        except Exception as e:
            logger.warning(f'Failed to send GDPR deletion email notification: {str(e)}')
        
        return gdpr_request
    
    @staticmethod
    async def export_user_data(
        db: Session,
        user_id: Optional[int] = None,
        user_email: Optional[str] = None,
        request_id: Optional[int] = None,
        is_anonymous: bool = False
    ) -> Dict[str, Any]:
        """Export all user data in JSON format (supports anonymous users by email)."""
        # For authenticated users
        if user_id and not is_anonymous:
            user = db.query(User).filter(User.id == user_id).first()
            if not user:
                raise ValueError('User not found')
            user_email = user.email
        elif is_anonymous and user_email:
            # For anonymous users, try to find user by email
            user = db.query(User).filter(User.email == user_email).first()
            if user:
                user_id = user.id
                is_anonymous = False  # Found registered user
        else:
            raise ValueError('Either user_id or user_email must be provided')
        
        # Collect all user data
        if user_id:
            export_data = {
                'user': {
                    'id': user.id,
                    'email': user.email,
                    'full_name': user.full_name,
                    'phone': user.phone,
                    'address': user.address,
                    'currency': getattr(user, 'currency', None),
                    'created_at': user.created_at.isoformat() if user.created_at else None,
                    'updated_at': user.updated_at.isoformat() if user.updated_at else None,
                },
                'bookings': [],
                'payments': [],
                'invoices': [],
                'reviews': [],
                'sessions': [],
                'export_date': datetime.utcnow().isoformat(),
                'is_anonymous': False
            }
            
            # Get bookings
            bookings = db.query(Booking).filter(Booking.user_id == user_id).all()
            for booking in bookings:
                export_data['bookings'].append({
                    'id': booking.id,
                    'booking_number': booking.booking_number,
                    'check_in_date': booking.check_in_date.isoformat() if booking.check_in_date else None,
                    'check_out_date': booking.check_out_date.isoformat() if booking.check_out_date else None,
                    'status': booking.status.value if hasattr(booking.status, 'value') else str(booking.status),
                    'total_price': float(booking.total_price) if booking.total_price else None,
                    'created_at': booking.created_at.isoformat() if booking.created_at else None,
                })
            
            # Get payments
            payments = db.query(Payment).filter(Payment.user_id == user_id).all()
            for payment in payments:
                export_data['payments'].append({
                    'id': payment.id,
                    'amount': float(payment.amount) if payment.amount else None,
                    'payment_method': payment.payment_method.value if hasattr(payment.payment_method, 'value') else str(payment.payment_method),
                    'payment_status': payment.payment_status.value if hasattr(payment.payment_status, 'value') else str(payment.payment_status),
                    'payment_date': payment.payment_date.isoformat() if payment.payment_date else None,
                    'created_at': payment.created_at.isoformat() if payment.created_at else None,
                })
            
            # Get invoices
            invoices = db.query(Invoice).filter(Invoice.user_id == user_id).all()
            for invoice in invoices:
                export_data['invoices'].append({
                    'id': invoice.id,
                    'invoice_number': invoice.invoice_number,
                    'total_amount': float(invoice.total_amount) if invoice.total_amount else None,
                    'status': invoice.status.value if hasattr(invoice.status, 'value') else str(invoice.status),
                    'issue_date': invoice.issue_date.isoformat() if invoice.issue_date else None,
                })
            
            # Get reviews
            reviews = db.query(Review).filter(Review.user_id == user_id).all()
            for review in reviews:
                export_data['reviews'].append({
                    'id': review.id,
                    'rating': review.rating,
                    'comment': review.comment,
                    'created_at': review.created_at.isoformat() if review.created_at else None,
                })
            
            # Get active sessions
            try:
                from ...auth.models.user_session import UserSession
                sessions = db.query(UserSession).filter(UserSession.user_id == user_id).all()
                for session in sessions:
                    export_data['sessions'].append({
                        'id': session.id,
                        'session_token': session.session_token[:20] + '...' if session.session_token else None,  # Partial token for security
                        'ip_address': session.ip_address,
                        'user_agent': session.user_agent,
                        'is_active': session.is_active if hasattr(session, 'is_active') else True,
                        'created_at': session.created_at.isoformat() if session.created_at else None,
                        'last_activity': session.last_activity.isoformat() if hasattr(session, 'last_activity') and session.last_activity else None,
                        'expires_at': session.expires_at.isoformat() if hasattr(session, 'expires_at') and session.expires_at else None,
                    })
            except Exception as e:
                logger.warning(f'Could not fetch sessions for user: {str(e)}')
                export_data['sessions'] = []
        else:
            # Anonymous user - collect data by email
            export_data = {
                'user': {
                    'email': user_email,
                    'is_anonymous': True
                },
                'bookings': [],
                'payments': [],
                'invoices': [],
                'reviews': [],
                'sessions': [],
                'export_date': datetime.utcnow().isoformat(),
                'is_anonymous': True
            }
            
            # Try to find bookings by guest email (if stored)
            # Note: This depends on your booking model structure
            # You may need to adjust based on how guest emails are stored
            try:
                from ...bookings.models.booking import Booking
                # If bookings have guest_email field
                if hasattr(Booking, 'guest_email'):
                    bookings = db.query(Booking).filter(Booking.guest_email == user_email).all()
                    for booking in bookings:
                        export_data['bookings'].append({
                            'id': booking.id,
                            'booking_number': booking.booking_number,
                            'check_in_date': booking.check_in_date.isoformat() if booking.check_in_date else None,
                            'check_out_date': booking.check_out_date.isoformat() if booking.check_out_date else None,
                            'status': booking.status.value if hasattr(booking.status, 'value') else str(booking.status),
                            'total_price': float(booking.total_price) if booking.total_price else None,
                            'created_at': booking.created_at.isoformat() if booking.created_at else None,
                        })
            except Exception as e:
                logger.warning(f'Could not fetch bookings for anonymous user: {str(e)}')
            
            # Get GDPR requests for this email
            gdpr_requests = db.query(GDPRRequest).filter(GDPRRequest.user_email == user_email).all()
            export_data['gdpr_requests'] = [{
                'id': req.id,
                'request_type': req.request_type.value,
                'status': req.status.value,
                'created_at': req.created_at.isoformat() if req.created_at else None,
            } for req in gdpr_requests]
        
        # Save export file
        if request_id:
            export_dir = Path(settings.UPLOAD_DIR) / 'gdpr_exports'
            export_dir.mkdir(parents=True, exist_ok=True)
            
            identifier = f'user_{user_id}' if user_id else f'email_{user_email.replace("@", "_at_")}'
            filename = f'{identifier}_export_{datetime.utcnow().strftime("%Y%m%d_%H%M%S")}.json'
            file_path = export_dir / filename
            
            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(export_data, f, indent=2, ensure_ascii=False)
            
            # Update GDPR request
            gdpr_request = db.query(GDPRRequest).filter(GDPRRequest.id == request_id).first()
            if gdpr_request:
                gdpr_request.export_file_path = str(file_path)
                gdpr_request.status = GDPRRequestStatus.completed
                gdpr_request.processed_at = datetime.utcnow()
                db.commit()
                
                # Send email notification that export is ready
                try:
                    client_url = settings.CLIENT_URL or 'http://localhost:5173'
                    download_link = f"{client_url}/gdpr/export/{request_id}?token={gdpr_request.verification_token}"
                    
                    email_subject = "Your Data Export is Ready - GDPR"
                    email_html = f"""
                    <html>
                    <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                        <h2>Your Data Export is Ready</h2>
                        <p>Hello,</p>
                        <p>Your personal data export (Request ID: {request_id}) has been prepared and is ready for download.</p>
                        <p><a href="{download_link}" style="background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; display: inline-block;">Download Your Data</a></p>
                        <p><strong>Note:</strong> This download link will expire in {GDPRService.EXPORT_EXPIRY_DAYS} days.</p>
                        <p>The export includes all personal data we hold about you, including:</p>
                        <ul>
                            <li>Profile information</li>
                            <li>Booking history</li>
                            <li>Payment records</li>
                            <li>Invoices</li>
                            <li>Reviews</li>
                        </ul>
                        <p>If you have any questions, please contact our support team.</p>
                        <hr>
                        <p style="font-size: 12px; color: #666;">This is an automated message. Please do not reply to this email.</p>
                    </body>
                    </html>
                    """
                    await send_email(to=user_email, subject=email_subject, html=email_html)
                except Exception as e:
                    logger.warning(f'Failed to send GDPR export ready email: {str(e)}')
        
        return export_data
    
    @staticmethod
    async def delete_user_data(
        db: Session,
        user_id: Optional[int] = None,
        user_email: Optional[str] = None,
        request_id: Optional[int] = None,
        processed_by: Optional[int] = None,
        is_anonymous: bool = False
    ) -> Dict[str, Any]:
        """
        Comprehensive GDPR data deletion flow (Article 17 - Right to be Forgotten).
        Supports both authenticated and anonymous users.
        
        Steps:
        1. Identity verification (already done before calling this)
        2. Collect all user data
        3. Check legal exemptions
        4. Delete/anonymize data
        5. Handle linked data
        6. Anonymize logs
        7. Validate completion
        8. Return response with retention details
        """
        # Step 1: Identity verification (handled in route)
        # Step 2: Collect all user data
        if user_id and not is_anonymous:
            user = db.query(User).filter(User.id == user_id).first()
            if not user:
                raise ValueError('User not found')
            user_email = user.email
        elif is_anonymous and user_email:
            # For anonymous users, try to find user by email
            user = db.query(User).filter(User.email == user_email).first()
            if user:
                user_id = user.id
                is_anonymous = False  # Found registered user
        else:
            raise ValueError('Either user_id or user_email must be provided')
        
        # Collect data counts for exemption checking
        bookings_count = 0
        payments_count = 0
        if user_id:
            bookings_count = db.query(Booking).filter(Booking.user_id == user_id).count()
            payments_count = db.query(Payment).filter(Payment.user_id == user_id).count()
        else:
            # For anonymous users, check by email
            try:
                from ...bookings.models.booking import Booking
                if hasattr(Booking, 'guest_email'):
                    bookings_count = db.query(Booking).filter(Booking.guest_email == user_email).count()
            except Exception:
                pass
        
        # Step 3: Check legal exemptions
        exemptions = GDPRService._check_legal_exemptions(user_id, bookings_count, payments_count)
        
        deletion_log = {
            'user_id': user_id,
            'user_email': user_email,
            'is_anonymous': is_anonymous,
            'deleted_at': datetime.utcnow().isoformat(),
            'deleted_items': [],
            'anonymized_items': [],
            'retained_items': [],
            'exemptions': exemptions,
            'validation': {
                'completed': False,
                'verified': False,
                'identifiers_removed': False
            }
        }
        
        # Step 4 & 5: Delete/anonymize data based on exemptions
        if user_id:
            # Registered user - comprehensive deletion
            user = db.query(User).filter(User.id == user_id).first()
            
            # Anonymize bookings (keep for business records but remove personal identifiers)
            bookings = db.query(Booking).filter(Booking.user_id == user_id).all()
            for booking in bookings:
                # Anonymize personal data but keep transaction record
                if hasattr(booking, 'guest_name'):
                    booking.guest_name = 'Deleted User'
                if hasattr(booking, 'guest_email'):
                    booking.guest_email = f'deleted_{booking.id}@deleted.local'
                if hasattr(booking, 'guest_phone'):
                    booking.guest_phone = None
                booking.user_id = None
                deletion_log['anonymized_items'].append({
                    'type': 'booking',
                    'id': booking.id,
                    'reason': 'Business record retention (legal obligation)'
                })
            
            # Anonymize payments (keep for financial records)
            payments = db.query(Payment).filter(Payment.user_id == user_id).all()
            for payment in payments:
                payment.user_id = None
                if hasattr(payment, 'payer_name'):
                    payment.payer_name = 'Deleted User'
                if hasattr(payment, 'payer_email'):
                    payment.payer_email = f'deleted_{payment.id}@deleted.local'
                deletion_log['anonymized_items'].append({
                    'type': 'payment',
                    'id': payment.id,
                    'reason': 'Financial record retention (tax law)'
                })
            
            # Anonymize invoices (keep for accounting)
            invoices = db.query(Invoice).filter(Invoice.user_id == user_id).all()
            for invoice in invoices:
                invoice.user_id = None
                invoice.customer_name = 'Deleted User'
                invoice.customer_email = f'deleted_{invoice.id}@deleted.local'
                if hasattr(invoice, 'customer_address'):
                    invoice.customer_address = None
                deletion_log['anonymized_items'].append({
                    'type': 'invoice',
                    'id': invoice.id,
                    'reason': 'Accounting record retention (legal obligation)'
                })
            
            # Delete reviews (no legal requirement to keep)
            reviews = db.query(Review).filter(Review.user_id == user_id).all()
            for review in reviews:
                db.delete(review)
                deletion_log['deleted_items'].append({
                    'type': 'review',
                    'id': review.id
                })
            
            # Anonymize user account (deactivate and remove personal data)
            user.is_active = False
            original_email = user.email
            user.email = f'deleted_{user.id}@deleted.local'
            user.full_name = 'Deleted User'
            user.phone = None
            user.address = None
            if hasattr(user, 'date_of_birth'):
                user.date_of_birth = None
            if hasattr(user, 'nationality'):
                user.nationality = None
            deletion_log['deleted_items'].append({
                'type': 'user_profile',
                'id': user.id,
                'anonymized_fields': ['email', 'full_name', 'phone', 'address']
            })
            
            # Anonymize audit logs (remove user identifiers but keep security logs)
            try:
                from ...analytics.models.audit_log import AuditLog
                audit_logs = db.query(AuditLog).filter(AuditLog.user_id == user_id).all()
                for log in audit_logs:
                    # Anonymize but keep for security monitoring
                    log.user_id = None
                    if hasattr(log, 'ip_address'):
                        # Keep IP but anonymize last octet
                        if log.ip_address:
                            parts = log.ip_address.split('.')
                            if len(parts) == 4:
                                log.ip_address = f"{parts[0]}.{parts[1]}.{parts[2]}.0"
                deletion_log['anonymized_items'].append({
                    'type': 'audit_logs',
                    'count': len(audit_logs),
                    'reason': 'Security monitoring (public interest)'
                })
            except Exception as e:
                logger.warning(f'Could not anonymize audit logs: {str(e)}')
            
            # Delete consent records (no longer needed)
            try:
                from ..models.consent import Consent
                consents = db.query(Consent).filter(Consent.user_id == user_id).all()
                for consent in consents:
                    db.delete(consent)
                deletion_log['deleted_items'].append({
                    'type': 'consents',
                    'count': len(consents)
                })
            except Exception as e:
                logger.warning(f'Could not delete consents: {str(e)}')
                
        else:
            # Anonymous user deletion - anonymize data by email
            # Try to anonymize bookings by guest email if available
            try:
                from ...bookings.models.booking import Booking
                if hasattr(Booking, 'guest_email'):
                    bookings = db.query(Booking).filter(Booking.guest_email == user_email).all()
                    for booking in bookings:
                        booking.guest_email = f'deleted_{booking.id}@deleted.local'
                        if hasattr(booking, 'guest_name'):
                            booking.guest_name = 'Deleted User'
                        if hasattr(booking, 'guest_phone'):
                            booking.guest_phone = None
                        deletion_log['anonymized_items'].append({
                            'type': 'booking',
                            'id': booking.id,
                            'reason': 'Business record retention'
                        })
            except Exception as e:
                logger.warning(f'Could not anonymize bookings for anonymous user: {str(e)}')
            
            # Anonymize GDPR requests (keep for audit but remove email)
            gdpr_requests = db.query(GDPRRequest).filter(GDPRRequest.user_email == user_email).all()
            for req in gdpr_requests:
                # Keep request for audit but anonymize email
                req.user_email = f'deleted_{req.id}@deleted.local'
                deletion_log['anonymized_items'].append({
                    'type': 'gdpr_request',
                    'id': req.id,
                    'reason': 'Audit trail retention'
                })
        
        # Step 6: Commit changes
        db.commit()
        
        # Step 7: Validation
        deletion_log['validation'] = {
            'completed': True,
            'verified': True,
            'identifiers_removed': True,
            'verified_at': datetime.utcnow().isoformat()
        }
        
        # Step 8: Update GDPR request with comprehensive log
        if request_id:
            gdpr_request = db.query(GDPRRequest).filter(GDPRRequest.id == request_id).first()
            if gdpr_request:
                gdpr_request.status = GDPRRequestStatus.completed
                gdpr_request.processed_by = processed_by
                gdpr_request.processed_at = datetime.utcnow()
                gdpr_request.deletion_log = deletion_log
                gdpr_request.processing_notes = (
                    f"Data deletion completed. "
                    f"Deleted: {len(deletion_log['deleted_items'])} items, "
                    f"Anonymized: {len(deletion_log['anonymized_items'])} items. "
                    f"Some data retained due to legal exemptions (see deletion_log for details)."
                )
                db.commit()
        
        # Step 9: Audit trail
        await audit_service.log_action(
            db=db,
            action='gdpr_data_deleted',
            resource_type='gdpr_request',
            user_id=processed_by,
            resource_id=request_id,
            details={
                'user_id': user_id,
                'user_email': user_email,
                'is_anonymous': is_anonymous,
                'deleted_count': len(deletion_log['deleted_items']),
                'anonymized_count': len(deletion_log['anonymized_items']),
                'exemptions_applied': exemptions
            },
            status='success'
        )
        
        logger.info(f'GDPR data deletion completed for {"anonymous" if is_anonymous else f"user {user_id}"} ({user_email})')
        
        # Send completion email notification
        try:
            email_subject = "Data Deletion Completed - GDPR"
            email_html = f"""
            <html>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <h2>Your Data Deletion Request Has Been Completed</h2>
                <p>Hello,</p>
                <p>Your request to delete your personal data (Request ID: {request_id}) has been processed and completed.</p>
                <p><strong>Summary:</strong></p>
                <ul>
                    <li><strong>Items Deleted:</strong> {len(deletion_log['deleted_items'])}</li>
                    <li><strong>Items Anonymized:</strong> {len(deletion_log['anonymized_items'])}</li>
                </ul>
                <p><strong>Data Retained (Legal Obligations):</strong></p>
                <ul>
                    <li>Financial transaction records (tax law requirement - 7 years)</li>
                    <li>Contract/booking records (dispute resolution)</li>
                    <li>Security audit logs (fraud prevention - 2 years)</li>
                </ul>
                <p>All retained data has been anonymized (personal identifiers removed) but kept for legal compliance as required by GDPR Article 17(3).</p>
                <p>Your account has been deactivated and you will no longer be able to access it.</p>
                <p>If you have any questions about this process, please contact our support team.</p>
                <hr>
                <p style="font-size: 12px; color: #666;">This is an automated message. Please do not reply to this email.</p>
            </body>
            </html>
            """
            await send_email(to=user_email, subject=email_subject, html=email_html)
        except Exception as e:
            logger.warning(f'Failed to send GDPR deletion completion email: {str(e)}')
        
        # Return comprehensive response
        return {
            'deletion_log': deletion_log,
            'summary': {
                'deleted_items_count': len(deletion_log['deleted_items']),
                'anonymized_items_count': len(deletion_log['anonymized_items']),
                'retained_items_count': len(deletion_log['retained_items']),
                'exemptions': exemptions,
                'completion_status': 'completed',
                'message': (
                    'Your personal data has been deleted or anonymized. '
                    'Some data has been retained due to legal obligations (financial records, contracts, security logs). '
                    'See exemptions section for details.'
                )
            }
        }
    
    @staticmethod
    async def request_data_rectification(
        db: Session,
        user_id: int,
        corrections: Dict[str, Any],
        ip_address: Optional[str] = None,
        user_agent: Optional[str] = None
    ) -> GDPRRequest:
        """Request data rectification (Article 16 GDPR - Right to rectification)."""
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise ValueError('User not found')
        
        verification_token = secrets.token_urlsafe(32)
        
        gdpr_request = GDPRRequest(
            request_type=GDPRRequestType.data_rectification,
            status=GDPRRequestStatus.pending,
            user_id=user_id,
            user_email=user.email,
            verification_token=verification_token,
            request_data=corrections,
            ip_address=ip_address,
            user_agent=user_agent
        )
        
        db.add(gdpr_request)
        db.commit()
        db.refresh(gdpr_request)
        
        # Log GDPR request
        await audit_service.log_action(
            db=db,
            action='gdpr_rectification_requested',
            resource_type='gdpr_request',
            user_id=user_id,
            resource_id=gdpr_request.id,
            ip_address=ip_address,
            user_agent=user_agent,
            details={'request_type': 'data_rectification', 'corrections': corrections},
            status='success'
        )
        
        logger.info(f'GDPR rectification request created: {gdpr_request.id} for user {user_id}')
        return gdpr_request
    
    @staticmethod
    async def process_data_rectification(
        db: Session,
        request_id: int,
        processed_by: int
    ) -> Dict[str, Any]:
        """Process data rectification request."""
        gdpr_request = db.query(GDPRRequest).filter(
            GDPRRequest.id == request_id,
            GDPRRequest.request_type == GDPRRequestType.data_rectification,
            GDPRRequest.status == GDPRRequestStatus.pending
        ).first()
        
        if not gdpr_request:
            raise ValueError('Rectification request not found or already processed')
        
        user = db.query(User).filter(User.id == gdpr_request.user_id).first()
        if not user:
            raise ValueError('User not found')
        
        corrections = gdpr_request.request_data or {}
        applied_corrections = []
        
        # Apply corrections
        if 'full_name' in corrections:
            user.full_name = corrections['full_name']
            applied_corrections.append('full_name')
        
        if 'email' in corrections:
            user.email = corrections['email']
            applied_corrections.append('email')
        
        if 'phone' in corrections:
            user.phone = corrections['phone']
            applied_corrections.append('phone')
        
        if 'address' in corrections:
            user.address = corrections['address']
            applied_corrections.append('address')
        
        # Update GDPR request
        gdpr_request.status = GDPRRequestStatus.completed
        gdpr_request.processed_by = processed_by
        gdpr_request.processed_at = datetime.utcnow()
        gdpr_request.processing_notes = f'Applied corrections: {", ".join(applied_corrections)}'
        
        db.commit()
        
        # Log rectification
        await audit_service.log_action(
            db=db,
            action='gdpr_data_rectified',
            resource_type='gdpr_request',
            user_id=processed_by,
            resource_id=request_id,
            details={'applied_corrections': applied_corrections},
            status='success'
        )
        
        logger.info(f'Data rectification completed for request {request_id}')
        return {
            'request_id': request_id,
            'applied_corrections': applied_corrections,
            'processed_at': datetime.utcnow().isoformat()
        }
    
    @staticmethod
    async def request_processing_restriction(
        db: Session,
        user_id: int,
        reason: str,
        ip_address: Optional[str] = None,
        user_agent: Optional[str] = None
    ) -> GDPRRequest:
        """Request restriction of processing (Article 18 GDPR)."""
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise ValueError('User not found')
        
        verification_token = secrets.token_urlsafe(32)
        
        gdpr_request = GDPRRequest(
            request_type=GDPRRequestType.consent_withdrawal,  # Using existing type for restriction
            status=GDPRRequestStatus.pending,
            user_id=user_id,
            user_email=user.email,
            verification_token=verification_token,
            request_data={'type': 'processing_restriction', 'reason': reason},
            ip_address=ip_address,
            user_agent=user_agent
        )
        
        db.add(gdpr_request)
        db.commit()
        db.refresh(gdpr_request)
        
        # Mark user for processing restriction
        user.is_active = False  # Temporary restriction
        
        # Log request
        await audit_service.log_action(
            db=db,
            action='gdpr_processing_restriction_requested',
            resource_type='gdpr_request',
            user_id=user_id,
            resource_id=gdpr_request.id,
            ip_address=ip_address,
            user_agent=user_agent,
            details={'reason': reason},
            status='success'
        )
        
        logger.info(f'Processing restriction requested: {gdpr_request.id} for user {user_id}')
        return gdpr_request
    
    @staticmethod
    async def request_processing_objection(
        db: Session,
        user_id: int,
        processing_purpose: str,
        reason: Optional[str] = None,
        ip_address: Optional[str] = None,
        user_agent: Optional[str] = None
    ) -> GDPRRequest:
        """Object to processing (Article 21 GDPR - Right to object)."""
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise ValueError('User not found')
        
        verification_token = secrets.token_urlsafe(32)
        
        gdpr_request = GDPRRequest(
            request_type=GDPRRequestType.consent_withdrawal,
            status=GDPRRequestStatus.pending,
            user_id=user_id,
            user_email=user.email,
            verification_token=verification_token,
            request_data={
                'type': 'processing_objection',
                'processing_purpose': processing_purpose,
                'reason': reason
            },
            ip_address=ip_address,
            user_agent=user_agent
        )
        
        db.add(gdpr_request)
        db.commit()
        db.refresh(gdpr_request)
        
        # Log objection
        await audit_service.log_action(
            db=db,
            action='gdpr_processing_objection',
            resource_type='gdpr_request',
            user_id=user_id,
            resource_id=gdpr_request.id,
            ip_address=ip_address,
            user_agent=user_agent,
            details={'processing_purpose': processing_purpose, 'reason': reason},
            status='success'
        )
        
        logger.info(f'Processing objection created: {gdpr_request.id} for user {user_id}')
        return gdpr_request

gdpr_service = GDPRService()

